File Coverage

blib/lib/Tapper/Installer/Base.pm
Criterion Covered Total %
statement 49 154 31.8
branch 4 78 5.1
condition 1 14 7.1
subroutine 14 17 82.3
pod 4 4 100.0
total 72 267 26.9


line stmt bran cond sub pod time code
1             our $AUTHORITY = 'cpan:TAPPER';
2             $Tapper::Installer::Base::VERSION = '5.0.1';
3             use Moose;
4 3     3   114601  
  3         380198  
  3         18  
5             use common::sense;
6 3     3   17269  
  3         17  
  3         45  
7             use Tapper::Remote::Config;
8 3     3   1373 use Tapper::Installer::Precondition::Copyfile;
  3         85293  
  3         100  
9 3     3   1205 use Tapper::Installer::Precondition::Exec;
  3         11  
  3         109  
10 3     3   1258 use Tapper::Installer::Precondition::Fstab;
  3         8  
  3         89  
11 3     3   1157 use Tapper::Installer::Precondition::Image;
  3         8  
  3         89  
12 3     3   891 use Tapper::Installer::Precondition::Kernelbuild;
  3         7  
  3         78  
13 3     3   1220 use Tapper::Installer::Precondition::PRC;
  3         9  
  3         90  
14 3     3   1226 use Tapper::Installer::Precondition::Package;
  3         7  
  3         110  
15 3     3   1240 use Tapper::Installer::Precondition::Rawimage;
  3         8  
  3         90  
16 3     3   1115 use Tapper::Installer::Precondition::Repository;
  3         8  
  3         116  
17 3     3   1184 use Tapper::Installer::Precondition::Simnow;
  3         8  
  3         118  
18 3     3   1125  
  3         8  
  3         4397  
19             extends 'Tapper::Installer';
20              
21              
22              
23             {
24             my ($self) = @_;
25             my ($error, $dev) = $self->log_and_exec('losetup', '-f');
26 1     1 1 9  
27 1         6 return if !$error and $dev eq '/dev/loop0';
28             ($error, $dev) = $self->log_and_exec("mount | grep loop0 | cut -f 3 -d ' '");
29 1 50 33     11 return $dev if $error; # can not search for mounts
30 1         3  
31 1 50       4 if ($dev) {
32             $error = $self->log_and_exec("umount $dev");
33 1 50       2 if ($error) {
34 0         0 my $processes;
35 0 0       0 ($error, $processes) =
36 0         0 $self->log_and_exec('lsof -t +D $dev 2>/dev/null');
37 0         0 foreach my $proc (split "\n", $processes) {
38             kill 15, $proc;
39 0         0 sleep 2;
40 0         0 kill 9, $proc;
41 0         0 }
42 0         0 $error = $self->log_and_exec("umount $dev");
43             return $error if $error;
44 0         0 }
45 0 0       0 }
46              
47             ($error, $dev) = $self->log_and_exec("kpartx -d /dev/loop0");
48             return $dev if $error;
49 1         3  
50 1 50       4 ($error, $dev) = $self->log_and_exec("losetup -d /dev/loop0");
51             return;
52 1         3 }
53 1         3  
54              
55             {
56             my ($self) = @_;
57              
58             $self->log->info('Cleaning up logfiles');
59 0     0 1   my @files_to_clean = ('/var/log/messages','/var/log/syslog');
60             FILE:
61 0           foreach my $file (@files_to_clean) {
62 0           my $filename = $self->cfg->{paths}{base_dir}."$file";
63             next FILE if not -e $filename;
64 0           open my $fh, ">", $filename or $self->log->warn("Can not open $filename for cleaning: $!"), next FILE;
65 0           print $fh '';
66 0 0         close $fh;
67 0 0         }
68 0           return 0;
69 0           }
70              
71 0            
72              
73             {
74             my ($self, $sleeptime) = @_;
75             return unless $sleeptime;
76             while (1) {
77             $self->mcp_inform("keep-alive");
78 0     0 1   sleep($sleeptime);
79 0 0         }
80 0           return;
81 0           }
82 0            
83              
84 0            
85             {
86             my ($self, $state) = @_;
87              
88             my $retval;
89             $state ||= 'standard'; # always defined value for state
90             # fetch configurations from the server
91 0     0 1   my $consumer = Tapper::Remote::Config->new;
92              
93 0           my $config=$consumer->get_local_data('install');
94 0   0       $self->logdie($config) if not ref($config) eq 'HASH';
95              
96 0           $self->{cfg}=$config;
97             $self->logdie("can't get local data: $config") if ref $config ne "HASH";
98 0            
99 0 0         if (not $state eq 'simnow') {
100             $retval = $self->nfs_mount();
101 0           $self->log->warn($retval) if $retval;
102 0 0         }
103              
104 0 0         if ($self->cfg->{log_to_file}) {
105 0           $self->log_to_file('install');
106 0 0         }
107              
108              
109 0 0         $self->log->info("Installing testrun (".$self->cfg->{testrun_id}.") on host ".$self->cfg->{hostname});
110 0           $self->mcp_inform("start-install") unless $state eq "autoinstall";
111              
112             if ($config->{times}{keep_alive_timeout}) {
113             $SIG{CHLD} = 'IGNORE';
114 0           my $pid = fork();
115 0 0         if ($pid == 0) {
116             $self->send_keep_alive_loop($config->{times}{keep_alive_timeout});
117 0 0         exit;
118 0           } else {
119 0           $config->{keep_alive_child} = $pid;
120 0 0         }
121 0           }
122 0            
123             if ($state eq 'simnow') {
124 0           $retval = $self->free_loop_device();
125             $self->logdie($retval) if $retval;
126             }
127              
128 0 0         my $image=Tapper::Installer::Precondition::Image->new($config);
129 0           if ($state eq "standard") {
130 0 0         $self->logdie("First precondition is not the root image")
131             if not $config->{preconditions}->[0]->{precondition_type} eq 'image'
132             and $config->{preconditions}->[0]->{mount} eq '/';
133 0           }
134 0 0          
135             foreach my $precondition (@{$config->{preconditions}}) {
136             if ($precondition->{precondition_type} eq 'image')
137 0 0 0       {
138             $retval = $image->precondition_install($precondition);
139             }
140 0           elsif ($precondition->{precondition_type} eq 'package')
  0            
141 0 0         {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
142             my $package=Tapper::Installer::Precondition::Package->new($config);
143 0           $retval = $package->precondition_install($precondition);
144             }
145             elsif ($precondition->{precondition_type} eq 'copyfile')
146             {
147 0           my $copyfile = Tapper::Installer::Precondition::Copyfile->new($config);
148 0           $retval = $copyfile->precondition_install($precondition);
149             }
150             elsif ($precondition->{precondition_type} eq 'fstab')
151             {
152 0           my $fstab = Tapper::Installer::Precondition::Fstab->new($config);
153 0           $retval = $fstab->precondition_install($precondition);
154             }
155             elsif ($precondition->{precondition_type} eq 'prc')
156             {
157 0           my $prc=Tapper::Installer::Precondition::PRC->new($config);
158 0           $retval = $prc->precondition_install($precondition);
159             }
160             elsif ($precondition->{precondition_type} eq 'rawimage')
161             {
162 0           my $rawimage=Tapper::Installer::Precondition::Rawimage->new($config);
163 0           $retval = $rawimage->precondition_install($precondition);
164             }
165             elsif ($precondition->{precondition_type} eq 'repository')
166             {
167 0           my $repository=Tapper::Installer::Precondition::Repository->new($config);
168 0           $retval = $repository->precondition_install($precondition);
169             }
170             elsif ($precondition->{precondition_type} eq 'exec')
171             {
172 0           my $exec=Tapper::Installer::Precondition::Exec->new($config);
173 0           $retval = $exec->precondition_install($precondition);
174             }
175             elsif ($precondition->{precondition_type} eq 'simnow_backend')
176             {
177 0           my $simnow=Tapper::Installer::Precondition::Simnow->new($config);
178 0           $retval = $simnow->precondition_install($precondition);
179             }
180             elsif ($precondition->{precondition_type} eq 'kernelbuild')
181             {
182 0           my $kernelbuild=Tapper::Installer::Precondition::Kernelbuild->new($config);
183 0           $retval = $kernelbuild->precondition_install($precondition);
184             }
185              
186             if ($retval) {
187 0           if ($precondition->{continue_on_error}) {
188 0           $self->mcp_send({state => 'warn-install', error => $retval});
189             } else {
190             $self->logdie($retval);
191 0 0         }
192 0 0         }
193 0           }
194              
195 0           if ($state eq 'standard' and not $config->{no_cleanup}) {
196             $self->cleanup();
197             }
198              
199             if ( $state eq "standard" and not ($config->{skip_prepare_boot})) {
200 0 0 0       $self->logdie($retval) if $retval = $image->prepare_boot();
201 0            
202             }
203             $image->unmount();
204 0 0 0        
205 0 0         # no longer send keepalive
206             if ($config->{keep_alive_child}) {
207             kill 15, $config->{keep_alive_child};
208 0           sleep 2;
209             kill 9, $config->{keep_alive_child};
210             }
211 0 0          
212 0            
213 0           $self->mcp_inform("end-install");
214 0           $self->log->info("Finished installation of test machine");
215              
216             given ($state){
217             when ("standard"){
218 0           return 0 if $config->{installer_stop};
219 0           system("sync");
220             system("sync");
221 0           system("sync");
222 0           system("reboot");
223 0 0         }
224 0           when ('simnow'){
225 0           #FIXME: don't use hardcoded path
226 0           my $simnow_config = $self->cfg->{files}{simnow_config};
227 0           $retval = qx(/opt/tapper/perl/perls/current/bin/perl /opt/tapper/perl/perls/current/bin/tapper-simnow-start --config=$simnow_config);
228             if ($?) {
229 0           $self->log->error("Can not start simnow: $retval");
230             $self->mcp_send({state => 'error-install',
231 0           error => "Can not start simnow: $retval",
232 0           prc_number => 0});
233 0 0         }
234 0            
235 0           }
236             }
237             return 0;
238             }
239              
240              
241             1;
242 0            
243              
244             =pod
245              
246             =encoding UTF-8
247              
248             =head1 NAME
249              
250             Tapper::Installer::Base
251              
252             =head1 SYNOPSIS
253              
254             use Tapper::Installer::Base;
255              
256             =head1 NAME
257              
258             Tapper::Installer::Base - Install everything needed for a test.
259              
260             =head1 FUNCTIONS
261              
262             =head2 free_loop_device
263              
264             Make sure /dev/loop0 is usable for losetup and kpartx.
265              
266             @return success - 0
267             @return error - error string
268              
269             =head2 cleanup
270              
271             Clean a set of predefine file by deleting all of their content. This prevents
272             confusion in certain test suites which could occur when they find old content
273             in log files. Only warns on error.
274              
275             @return success - 0
276              
277             =head2 send_keep_alive_loop
278              
279             Send keepalive messages to MCP in an endless loop.
280              
281             @param int - sleep time between two keepalives
282              
283             =head2 system_install
284              
285             Install whatever has to be installed. This function is a wrapper around all
286             other system installer functions and calls them appropriately. Note that the
287             function will not return in case of an error. Instead it throws an exception with
288             should be send to the server by Log4perl.
289              
290             @param string - in what state are we called (autoinstall, other)
291              
292             =head1 AUTHOR
293              
294             AMD OSRC Tapper Team, C<< <tapper at amd64.org> >>
295              
296             =head1 BUGS
297              
298             None.
299              
300             =head1 SUPPORT
301              
302             You can find documentation for this module with the perldoc command.
303              
304             perldoc Tapper
305              
306             =head1 ACKNOWLEDGEMENTS
307              
308             =head1 COPYRIGHT & LICENSE
309              
310             Copyright 2008-2011 AMD OSRC Tapper Team, all rights reserved.
311              
312             This program is released under the following license: freebsd
313              
314             =head1 AUTHORS
315              
316             =over 4
317              
318             =item *
319              
320             AMD OSRC Tapper Team <tapper@amd64.org>
321              
322             =item *
323              
324             Tapper Team <tapper-ops@amazon.com>
325              
326             =back
327              
328             =head1 COPYRIGHT AND LICENSE
329              
330             This software is Copyright (c) 2022 by Advanced Micro Devices, Inc.
331              
332             This is free software, licensed under:
333              
334             The (two-clause) FreeBSD License
335              
336             =cut