Rename mock_install_group attribute to mock_install_packages
[Fedora-Rebuild.git] / lib / Fedora / Rebuild / Mock.pm
blobe616c8ec6ac365474ae3c8002ca1ac2984adbc57
1 package Fedora::Rebuild::Mock;
2 use strict;
3 use warnings;
4 use version 0.77; our $VERSION = version->declare("v0.12.1");
6 use Moose;
7 use Carp;
8 use File::Spec;
9 use File::Temp;
10 use URI;
11 use namespace::clean;
13 # Archicture of mock environment. E.g. "x86_64".
14 has architecture => (
15 is => 'ro',
16 isa => 'Str',
17 required => 1
20 # Reference to list of repository URLs.
21 has repositories => (
22 is => 'ro',
23 isa => 'ArrayRef[Str]',
24 required => 1
27 # Create a mock environment with enabled caching.
28 # Default is false.
29 has shared => (
30 is => 'ro',
31 isa => 'Bool',
32 required => 0,
33 default => 0
36 # YUM packages to install at mock chroot initialization. Separate them by
37 # a space.
38 # '@buildsys-build' is needed for mirrored Fedora repositories
39 # '@build' is needed for direct koji repositories.
40 # Default value is '@buildsys-build'.
41 has install_packages => (
42 is => 'ro',
43 isa => 'Str',
44 default => '@buildsys-build'
47 # Directory with mock configuration.
48 has config_dir => (
49 is => 'ro',
50 isa => 'Str',
51 lazy_build => 1,
52 init_arg => undef
55 # Base name of configuration file without extension.
56 has config_root => (
57 is => 'ro',
58 isa => 'Str',
59 default => 'config'
62 sub BUILD {
63 my $self = shift;
65 if (!defined $self->architecture || $self->architecture eq '') {
66 corak("architecture attribute must be non-empty string");
68 if ($self->architecture =~ /['"\n]/s) {
69 croak("architecture attribute cannot contain " .
70 "apostrophe or a double quote or new line");
72 if ($self->install_packages =~ /['"\n]/s) {
73 croak("install_packages attribute cannot contain " .
74 "apostrophe or a double quote or new line");
78 for my $repo (@{$self->repositories}) {
79 if ($repo =~ /['"\s]/s) {
80 croak("repository cannot contain apostrophe or a double quote "
81 . "or a white space");
87 # Create a directory. Caller is responsible for removing it.
88 # Croaks on error.
89 sub _build_config_dir {
90 my $directory;
91 local $! = undef;
92 eval { $directory = File::Temp::tempdir(CLEANUP => 0); } or
93 croak ("Could not create temporary mock configuration directory: " .
94 "$!\n");
95 return $directory;
99 # Write mock configuration file into the config directory. Returns the full
100 # pathname to the file.
101 # Croeaks on error.
102 sub config_file {
103 my $self=shift;
104 my $arch = $self->architecture;
105 my $install_packages = $self->install_packages;
106 # Embed the config_dir random name into mock chroot to allow parallel run
107 # of more mock instances. Otherwise mock returns failure on existing lock.
108 my (undef, undef, $dir) = File::Spec->splitpath($self->config_dir);
110 my $file_name = File::Spec->catfile($self->config_dir,
111 ($self->config_root . '.cfg'));
112 my $fh;
113 local $! = undef;
114 open($fh, '>', $file_name) or
115 croak("Could not create mock configuration file: $!\n");
116 $! = undef;
118 binmode($fh, ':utf8');
119 if ($self->shared) {
120 print $fh <<"FILE";
121 config_opts['plugin_conf']['ccache_enable'] = True
122 config_opts['plugin_conf']['yum_cache_enable'] = True
123 config_opts['plugin_conf']['root_cache_enable'] = True
124 FILE
125 } else {
126 print $fh <<"FILE";
127 config_opts['plugin_conf']['ccache_enable'] = False
128 config_opts['plugin_conf']['yum_cache_enable'] = False
129 config_opts['plugin_conf']['root_cache_enable'] = False
130 FILE
132 print $fh <<"FILE";
133 config_opts['root'] = 'fedorarebuild-$arch-$dir'
134 config_opts['target_arch'] = '$arch'
135 config_opts['legal_host_arches'] = ('$arch',)
136 config_opts['chroot_setup_cmd'] = 'install $install_packages'
138 config_opts['yum.conf'] = """
139 [main]
140 cachedir=/var/cache/yum
141 debuglevel=1
142 reposdir=/dev/null
143 logfile=/var/log/yum.log
144 retries=20
145 obsoletes=1
146 gpgcheck=0
147 assumeyes=1
148 syslog_ident=mock
149 syslog_device=
151 FILE
153 my $id = 0;
154 for my $repo (@{$self->repositories}) {
155 my $url = URI->new($repo);
156 print $fh "[$id]\n";
157 print $fh "name=$id\n";
158 print $fh "baseurl=$url\n";
159 $id++;
162 print $fh qq{"""\n};
163 $fh->close;
164 if ($!) {
165 croak("Could not write mock configuration file `" . $file_name .
166 "': $!\n");
168 return $file_name;
172 # Links configuration file from global configuration directory to this
173 # specific directory.
174 # Croaks on error.
175 sub inherit_file {
176 my ($self, $file) = @_;
177 local $! = undef;
179 my $target = File::Spec->catfile('/etc/mock', $file);
180 my $link = File::Spec->catfile($self->config_dir, $file);
182 if (-l $link or -e $link) {
183 unlink $link or croak("Could not remove old `" . $link .
184 "': $!\n");
186 if (!symlink($target, $link)) {
187 croak("Could not inherit mock file `" . $file . "' into `" .
188 $self->directory . "': $!\n");
193 # Creates mock configuration and return name of configuration directory and
194 # base name of configuration file without extension.
195 # Removal of the directory is on caller discretion.
196 # Croaks on error.
197 sub make_configuration {
198 my $self = shift;
199 $self->config_file;
200 $self->inherit_file('logging.ini');
201 $self->inherit_file('site-defaults.cfg');
203 return ($self->config_dir, $self->config_root);