File Coverage

blib/lib/Tapper/Installer/Precondition/PRC.pm
Criterion Covered Total %
statement 102 143 71.3
branch 27 78 34.6
condition 3 12 25.0
subroutine 14 15 93.3
pod 8 8 100.0
total 154 256 60.1


line stmt bran cond sub pod time code
1             our $AUTHORITY = 'cpan:TAPPER';
2             $Tapper::Installer::Precondition::PRC::VERSION = '5.0.1';
3             use strict;
4 5     5   118158 use warnings;
  5         19  
  5         130  
5 5     5   25  
  5         8  
  5         108  
6             use File::Basename;
7 5     5   22 use Hash::Merge::Simple 'merge';
  5         9  
  5         402  
8 5     5   803 use File::ShareDir 'module_file';
  5         922  
  5         227  
9 5     5   2479 use Moose;
  5         94827  
  5         223  
10 5     5   528 use YAML;
  5         417055  
  5         33  
11 5     5   28863 extends 'Tapper::Installer::Precondition';
  5         5821  
  5         7706  
12              
13              
14              
15              
16             {
17             my ($self, $config) = @_;
18             $config->{report_server} = $self->{cfg}->{report_server};
19 6     6 1 15 $config->{report_port} = $self->{cfg}->{report_port};
20 6         19 $config->{report_api_port} = $self->{cfg}->{report_api_port};
21 6         13 $config->{hostname} = $self->{cfg}->{hostname}; # allows guest systems to know their host system name
22 6         14 $config->{test_run} = $self->{cfg}->{test_run};
23 6         11 $config->{mcp_port} = $self->{cfg}->{mcp_port} if $self->{cfg}->{mcp_port};
24 6         14 $config->{mcp_server} = $self->{cfg}->{mcp_server};
25 6 50       23 $config->{sync_port} = $self->{cfg}->{sync_port} if $self->{cfg}->{sync_port};
26 6         12 $config->{prc_nfs_server} = $self->{cfg}->{prc_nfs_server} if $self->{cfg}->{prc_nfs_server}; # prc_nfs_path is set by merging paths above
27 6 50       23 $config->{scenario_id} = $self->{cfg}->{scenario_id} if $self->{cfg}->{scenario_id};
28 6 50       18 $config->{paths} = $self->{cfg}->{paths};
29 6 50       15 $config->{files} = $self->{cfg}->{files} if $self->{cfg}->{files} ;
30 6         11 $config->{testplan} = $self->{cfg}->{testplan} if $self->{cfg}->{testplan};
31 6 100       16 $config->{log_to_file} = $self->{cfg}->{log_to_file};
32 6 50       16  
33 6         11  
34             return $config;
35             }
36 6         13  
37              
38             {
39             my ($self, $prc) = @_;
40              
41             my $config = $self->create_common_config($prc->{config});
42 2     2 1 784 $config = merge($config, {times=>$self->{cfg}->{times}});
43             my @timeouts;
44 2         9  
45 2         19 if ($prc->{config}->{guest_count})
46 2         74 {
47             $config->{guest_count} = $prc->{config}->{guest_count};
48 2 50       8 $config->{timeouts} = $prc->{config}->{timeouts};
49             }
50 0         0 else
51 0         0 {
52             $config->{mcp_server} = $self->{cfg}->{mcp_server};
53             }
54              
55 2         4 return $config;
56             }
57              
58 2         6  
59             {
60             my ($self, $prc) = @_;
61             my $basedir = $self->cfg->{paths}{base_dir};
62             my $config = $self->create_unix_config($prc);
63              
64 1     1 1 3 $self->makedir("$basedir/etc") if not -d "$basedir/etc";
65 1         28 open my $file, '>',"$basedir/etc/tapper" or return "Can not open /etc/tapper in $basedir:$!";
66 1         4 print $file YAML::Dump($config);
67             close $file;
68 1 50       26 return 0;
69 1 50       6768 }
70 1         31  
71 1         15196  
72 1         22  
73             {
74             my ($self, $distro) = @_;
75             my $basedir = $self->cfg->{paths}{base_dir};
76             my ($error, $retval);
77             if (not -d "$basedir/etc/init.d" ) {
78             mkdir("$basedir/etc/init.d") or return "Can't create /etc/init.d/ in $basedir";
79 0     0 1 0 }
80 0         0 ($error, $retval) = $self->log_and_exec("cp",module_file('Tapper::Installer', "startfiles/$distro/etc/init.d/tapper"),"$basedir/etc/init.d/tapper");
81 0         0 return $retval if $error;
82 0 0       0 if ($distro!~/tapper/) {
83 0 0       0  
84             pipe (my $read, my $write);
85 0         0 return ("Can't open pipe:$!") if not (defined $read and defined $write);
86 0 0       0  
87 0 0       0 # fork for the stuff inside chroot
88             my $pid = fork();
89 0         0 return "fork failed: $!" if not defined $pid;
90 0 0 0     0  
91             # child
92             if ($pid == 0) {
93 0         0 close $read;
94 0 0       0 chroot $basedir;
95             chdir ("/");
96              
97 0 0       0 my $ret = 0;
98 0         0 my ($error, $retval);
99 0         0 if ($distro=~m/suse|debian/) {
100 0         0 ($error, $retval)=$self->log_and_exec("insserv","/etc/init.d/tapper");
101             } elsif ($distro=~m/(redhat)|(fedora)/) {
102 0         0 ($error, $retval)=$self->log_and_exec("chkconfig","--add","tapper");
103 0         0 } elsif ($distro=~m/(ubuntu)/) {
104 0 0       0 ($error, $retval)=$self->log_and_exec("update-rc.d","-f", "tapper", "defaults");
    0          
    0          
    0          
105 0         0 } elsif ($distro=~/gentoo/) {
106             ($error, $retval)=$self->log_and_exec("rc-update", "add", "tapper_gentoo", "default");
107 0         0 } else {
108             ($error, $retval)=(1,"No supported distribution detected.");
109 0         0 }
110             print($write "$retval") if $error;
111 0         0 close $write;
112             exit $error;
113 0         0 } else { # parent
114             close $write;
115 0 0       0 waitpid($pid,0);
116 0         0 if ($?) {
117 0         0 my $output = <$read>;
118             return($output);
119 0         0 }
120 0         0 }
121 0 0       0 }
122 0         0 }
123 0         0  
124              
125             {
126             my ($self, $prc) = @_;
127             my $basedir = $self->cfg->{paths}{base_dir};
128              
129             my $config = $self->create_common_config();
130             $config->{guest_number} = $prc->{config}->{guest_number} if $prc->{config}->{guest_number};
131              
132 3     3 1 2189 if ($prc->{config}->{guest_count})
133 3         151 {
134             $config->{guest_count} = $prc->{config}->{guest_count};
135 3         14 }
136 3 100       15 if ($prc->{config}->{testprogram_list}) {
137             for (my $i=0; $i< int @{$prc->{config}->{testprogram_list}}; $i++) {
138 3 50       9 # string concatenation for hash keys, otherwise perl can't tell whether
139             # $i ot $i_prog is the name of the variable
140 0         0 my $list_element = $prc->{config}->{testprogram_list}->[$i];
141             $config->{"test".$i."_prog"} = $list_element->{program};
142 3 100       17 $config->{"test".$i."_prog"} ||= $list_element->{test_program};
    100          
143 1         2 $config->{"test".$i."_runtime_default"} = $list_element->{runtime};
  4         51  
144             $config->{"test".$i."_timeout"} = $list_element->{timeout};
145             $config->{"test".$i."_timeout"} ||= $list_element->{timeout_testprogram};
146 3         8 }
147 3         9 } elsif ($prc->{config}->{test_program}) {
148 3   33     21 $config->{test0_prog} = $prc->{config}->{test_program};
149 3         8 $config->{test0_runtime_default} = $prc->{config}->{runtime};
150 3         6 $config->{test0_timeout} = $prc->{config}->{timeout_testprogram}
151 3   33     12 }
152             return $config;
153              
154 1         3 }
155 1         8  
156              
157 1         3 {
158 3         11 my ($self, $prc) = @_;
159              
160             my $config = $self->create_windows_config($prc);
161             my $basedir = $self->cfg->{paths}{base_dir};
162             open my $file, '>', $basedir.'/test.config' or return "Can not open /test.config in $basedir:$!";
163             print $file YAML::Dump($config);
164             close $file;
165 1     1 1 3  
166             return 0
167 1         11 }
168 1         27  
169 1 50       119  
170 1         8  
171 1         2846  
172             {
173 1         9 my ($self, $prc) = @_;
174              
175             my $basedir = $self->cfg->{paths}{base_dir};
176             my ($error, $retval);
177             my $distro = $self->get_distro($basedir);
178             $retval = $self->install_startscript($distro) if $distro and not $prc->{skip_startscript};
179             return $retval if $retval;
180              
181 1     1 1 549 $error = $self->write_unix_config($prc);
182             return $error if $error;
183 1         37  
184 1         3  
185 1         3 $error = $self->write_windows_config($prc);
186 1 50 33     5 return $error if $error;
187 1 50       6  
188             if ($prc->{tapper_package}) {
189 1         5 my $pkg_object=Tapper::Installer::Precondition::Package->new($self->cfg);
190 1 50       8 my $package={filename => $prc->{tapper_package}};
191             $self->logdie($retval) if $retval = $pkg_object->install($package);
192             }
193 1         9  
194 1 50       54 return 0;
195             }
196 1 50       5  
197 0         0  
198 0         0  
199 0 0       0  
200             {
201             my ($self, $dir) = @_;
202 1         11 my @files=glob("$dir/etc/*-release");
203             for my $file(@files){
204             return "suse" if $file =~ /suse/i;
205             return "redhat" if $file =~ /redhat/i;
206             return "gentoo" if $file =~ /gentoo/i;
207             return "tapper" if $file =~ /tapper/i;
208             }
209             {
210 4     4 1 1421 open my $fh, '<',"$dir/etc/issue" or next;
211 4         210 local $\='';
212 4         16 my $issue = <$fh>;
213 1 50       11 close $fh;
214 0 0       0 my $distro;
215 0 0       0 ($distro) = $issue =~ m/(Debian|Ubuntu)/i;
216 0 0       0 return lc($distro) if $distro;
217             }
218             return "";
219 3 100       6 }
  3         90  
220 1         6  
221 1         639  
222 1         21 1;
223 1         4  
224 1         11  
225 1 50       13 =pod
226              
227 2         8 =encoding UTF-8
228              
229             =head1 NAME
230              
231             Tapper::Installer::Precondition::PRC
232              
233             =head1 SYNOPSIS
234              
235             use Tapper::Installer::Precondition::PRC;
236              
237             =head1 NAME
238              
239             Tapper::Installer::Precondition::PRC - Install Program Run Control to a given location
240              
241             =head1 FUNCTIONS
242              
243             =head2 create_common_config
244              
245             Create the part of the config that is the same for both Windows and Unix.
246              
247             @return hash ref
248              
249             =head2 create_unix_config
250              
251             Generate a config for PRC running on Unix system. Take special care for
252             virtualisation environments. In this case, the host system runs a proxy
253             which collects status messages from all virtualisation guests.
254              
255             @param hash reference - contains all information about the PRC to install
256              
257             @return hash ref - config
258              
259             =head2 write_unix_config
260              
261             Generate and write config for unix test.
262              
263             @param hash reference - contains all information about the PRC to install
264              
265             @return success - 0
266             @return error - error string
267              
268             =head2 install_startscript
269              
270             Install a startscript for init in test state.
271              
272             @return success - 0
273             @return error - error string
274              
275             =head2 create_windows_config
276              
277             Create the config for a windows guest running the special Win-PRC. Win-PRC
278             expects a flat YAML with some different keys and does not want any waste
279             options.
280              
281             @param hash reference - contains all information about the PRC to install
282              
283             @return hash ref - windows config
284              
285             =head2 write_windows_config
286              
287             Generate and write config for windows guest.
288              
289             @param hash reference - contains all information about the PRC to install
290              
291             @return success - 0
292             @return error - error string
293              
294             =head2 install
295              
296             Install the tools used to control running of programs on the test
297             system. This function is implemented to fullfill the needs of kernel
298             testing and is likely to change dramatically in the future due to
299             limited extensibility. Furthermore, it has the name of the PRC hard
300             coded which isn't a good thing either.
301              
302             @param hash ref - contains all information about the PRC to install
303              
304             @return success - 0
305             @return error - return value of system or error string
306              
307             =head2 get_distro
308              
309             Find out which distribution is installed below the directory structure
310             given as argument. The guessed distribution is returned as a string.
311              
312             @param string - path name under which to check for an installed
313             distribution
314              
315             @return success - name of the distro
316             @return error - empty string
317              
318             =head1 AUTHORS
319              
320             =over 4
321              
322             =item *
323              
324             AMD OSRC Tapper Team <tapper@amd64.org>
325              
326             =item *
327              
328             Tapper Team <tapper-ops@amazon.com>
329              
330             =back
331              
332             =head1 COPYRIGHT AND LICENSE
333              
334             This software is Copyright (c) 2022 by Advanced Micro Devices, Inc.
335              
336             This is free software, licensed under:
337              
338             The (two-clause) FreeBSD License
339              
340             =cut