File Coverage

blib/lib/Tapper/Installer/Base.pm
Criterion Covered Total %
statement 8 10 80.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 12 14 85.7


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