source: devel/pb/bin/pb @ 139

Last change on this file since 139 was 139, checked in by Bruno Cornec, 13 years ago

Build on VMs works now with delivery of built packages on the SSH host

  • Property svn:executable set to *
File size: 21.7 KB
Line 
1#!/usr/bin/perl -w
2#
3# Project Builder main application
4#
5# $Id$
6#
7# Copyright B. Cornec 2007
8# Provided under the GPL v2
9
10# Syntax: see at end
11
12use strict 'vars';
13use Getopt::Std;
14use Data::Dumper;
15use English;
16use AppConfig qw(:argcount :expand);
17use File::Basename;
18use File::Copy;
19use Time::localtime qw(localtime);
20use POSIX qw(strftime);
21
22# Global variables
23use lib qw (lib);
24use ProjectBuilder::Distribution qw (pb_distro_init);
25use ProjectBuilder::Changelog qw (pb_changelog);
26use ProjectBuilder::Version qw (pb_version_init);
27use ProjectBuilder::Base qw (pb_conf_read pb_conf_get pb_cms_init pb_mkdir_p pb_system pb_rm_rf pb_get_filters pb_filter_file pb_filter_file_pb pb_cms_export pb_cms_log);
28
29my %opts;                   # CLI Options
30my $action;                 # action to realize
31my $test = "FALSE";
32my $option = "";
33my @pkgs;
34my $pbtag;                  # Global Tag variable
35my $pbver;                  # Global Version variable
36my %pbver;                  # per package
37my %pbtag;                  # per package
38my $pbrev;                  # Global REVISION variable
39my @date=(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
40my $pbdate = strftime("%Y-%m-%d", @date);
41my $pbdatecvs = strftime("%Y-%m-%d %H:%M:%S", @date);
42my $debug = 0;
43my $LOG = \*STDOUT;
44
45getopts('hl:m:p:qr:tv',\%opts);
46
47my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
48if (defined $opts{'h'}) {
49    pb_syntax();
50    exit(0);
51}
52if (defined $opts{'v'}) {
53    $debug++;
54}
55if (defined $opts{'q'}) {
56    $debug=-1;
57}
58if (defined $opts{'l'}) {
59    open(LOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
60    $LOG = *LOG;
61    $debug = 0  if ($debug == -1);
62    }
63# Handles test option
64if (defined $opts{'t'}) {
65    $test = "TRUE";
66    # Works only for SVN
67    $option = "-r BASE";
68}
69
70# Handle root of the project if defined
71if (defined $opts{'r'}) {
72    $ENV{'PBROOT'} = $opts{'r'};
73}
74# Handle virtual machines if any
75if (defined $opts{'m'}) {
76    $ENV{'PBVM'} = $opts{'m'};
77}
78
79# Get Action
80$action = shift @ARGV;
81die pb_syntax() if (not defined $action);
82
83my ($pbrc, $filteredfiles, $defpkgdir, $extpkgdir);
84
85# Handles project name if any
86# And get global params
87if (defined $opts{'p'}) {
88    ($ENV{'PBPROJ'},$debug,$LOG, $pbrc, $filteredfiles, $defpkgdir, $extpkgdir) 
89    = pb_env_init($opts{'p'});
90} else {
91    ($ENV{'PBPROJ'},$debug,$LOG, $pbrc, $filteredfiles, $defpkgdir, $extpkgdir) 
92    = pb_env_init();
93}
94
95print $LOG "Project: $ENV{'PBPROJ'}\n" if ($debug >= 0);
96print $LOG "Action: $action\n" if ($debug >= 0);
97
98# Keep those project values to store them at the end each time
99my $pbprojtag = $ENV{'PBTAG'};
100my $pbprojver = $ENV{'PBVER'};
101
102# Act depending on action
103if ($action =~ /^cms2build$/) {
104    pb_cms2build();
105} elsif ($action =~ /^build2pkg$/) {
106    pb_build2pkg();
107} elsif ($action =~ /^cms2pkg$/) {
108    pb_cms2build();
109    pb_build2pkg();
110} elsif ($action =~ /^build2ssh$/) {
111    pb_build2ssh();
112} elsif ($action =~ /^pkg2ssh$/) {
113    pb_pkg2ssh();
114} elsif ($action =~ /^build2vm$/) {
115    pb_build2vm();
116} elsif ($action =~ /^cms2vm$/) {
117    pb_cms2build();
118    pb_build2vm();
119} elsif ($action =~ /^clean$/) {
120} else {
121    print $LOG "'$action' is not available\n";
122    pb_syntax();
123}
124
125sub pb_cms2build {
126
127    my $ptr = pb_get_pkg($defpkgdir,$extpkgdir);
128    @pkgs = @$ptr;
129    my $cms=pb_cms_init($ENV{'PBPROJ'});
130
131    my ($pkgv, $pkgt) = pb_conf_read("$ENV{'PBCONF'}/$ENV{'PBPROJ'}.pb","pkgver","pkgtag");
132    foreach my $pbpkg (@pkgs) {
133        $ENV{'PBPKG'} = $pbpkg;
134        if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
135            $pbver = $pkgv->{$pbpkg};
136            $ENV{'PBVER'} = $pbver;
137        } else {
138            $pbver = $ENV{'PBVER'};
139        }
140        if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
141            $pbtag = $pkgt->{$pbpkg};
142            $ENV{'PBTAG'} = $pbtag;
143        } else {
144            $pbtag = $ENV{'PBTAG'};
145        }
146
147        $pbrev = $ENV{'PBREVISION'};
148        print $LOG "\n";
149        print $LOG "Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n";
150        die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
151        # Clean up dest if necessary. The export will recreate it
152        my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver";
153        pb_rm_rf($dest) if (-d $dest);
154
155        # Export CMS tree for the concerned package to dest
156        # And generate some additional files
157        $OUTPUT_AUTOFLUSH=1;
158
159        # computes in which dir we have to work
160        my $dir = $defpkgdir->{$pbpkg};
161        $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
162        print "def:".Dumper($defpkgdir)." ext: ".Dumper($extpkgdir)." \n" if ($debug >= 1);
163        pb_cms_export($cms,$pbdatecvs,"$ENV{'PBROOT'}/$dir",$dest);
164
165        # Extract cms log history and store it
166        pb_cms_log($cms,"$ENV{'PBROOT'}/$dir","$dest/$ENV{'PBCMSLOGFILE'}");
167
168        my %build;
169
170        my ($ptr) = pb_conf_get("vmlist");
171        foreach my $d (split(/,/,$ptr->{$ENV{'PBPROJ'}})) {
172            my ($name,$ver) = split(/_/,$d);
173            chomp($ver);
174            my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
175            print $LOG "DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n" if ($debug >= 1);
176            print $LOG "DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n" if ($debug >= 1);
177
178            # Filter build files from the less precise up to the most with overloading
179            # Filter all files found, keeping the name, and generating in dest
180
181            # Find all build files first relatively to PBROOT
182            my %bfiles;
183            print $LOG "DEBUG dir: $ENV{'PBCONF'}/$pbpkg\n" if ($debug >= 1);
184            $build{"$ddir-$dver"} = "yes";
185            if (-d "$ENV{'PBCONF'}/$pbpkg/$dtype") {
186                opendir(BDIR,"$ENV{'PBCONF'}/$pbpkg/$dtype") || die "Unable to open dir $ENV{'PBCONF'}/$pbpkg/$dtype: $!";
187                foreach my $f (readdir(BDIR)) {
188                    next if ($f =~ /^\./);
189                    $bfiles{$f} = "$ENV{'PBCONF'}/$pbpkg/$dtype/$f";
190                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
191                }
192                closedir(BDIR);
193            } elsif (-d "$ENV{'PBCONF'}/$pbpkg/$dfam") {
194                opendir(BDIR,"$ENV{'PBCONF'}/$pbpkg/$dfam") || die "Unable to open dir $ENV{'PBCONF'}/$pbpkg/$dfam: $!";
195                foreach my $f (readdir(BDIR)) {
196                    next if ($f =~ /^\./);
197                    $bfiles{$f} = "$ENV{'PBCONF'}/$pbpkg/$dfam/$f";
198                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
199                }
200                closedir(BDIR);
201            } elsif (-d "$ENV{'PBCONF'}/$pbpkg/$ddir") {
202                opendir(BDIR,"$ENV{'PBCONF'}/$pbpkg/$ddir") || die "Unable to open dir $ENV{'PBCONF'}/$pbpkg/$ddir: $!";
203                foreach my $f (readdir(BDIR)) {
204                    next if ($f =~ /^\./);
205                    $bfiles{$f} = "$ENV{'PBCONF'}/$pbpkg/$ddir/$f";
206                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
207                }
208                closedir(BDIR);
209            } elsif (-d "$ENV{'PBCONF'}/$pbpkg/$ddir-$dver") {
210                opendir(BDIR,"$ENV{'PBCONF'}/$pbpkg/$ddir-$dver") || die "Unable to open dir $ENV{'PBCONF'}/$pbpkg/$ddir-$dver: $!";
211                foreach my $f (readdir(BDIR)) {
212                    next if ($f =~ /^\./);
213                    $bfiles{$f} = "$ENV{'PBCONF'}/$pbpkg/$ddir-$dver/$f";
214                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
215                }
216                closedir(BDIR);
217            } else {
218                $build{"$ddir-$dver"} = "no";
219                next;
220            }
221            print $LOG "DEBUG bfiles: ".Dumper(\%bfiles)."\n" if ($debug >= 1);
222
223            # Get all filters to apply
224            my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
225
226            # Apply now all the filters on all the files concerned
227            # destination dir depends on the type of file
228            if (defined $ptr) {
229                foreach my $f (values %bfiles) {
230                    pb_filter_file_pb("$ENV{'PBROOT'}/$f",$ptr,"$dest/pbconf/$ddir-$dver/".basename($f),$dtype,$pbsuf,$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$defpkgdir,$extpkgdir);
231                }
232                if (defined $filteredfiles->{$pbpkg}) {
233                    foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
234                        pb_filter_file("$ENV{'PBROOT'}/$dir/$f",$ptr,"$dest/$f",$pbsuf,$pbpkg,$pbver,$pbtag,$pbrev,$pbdate);
235                    }
236                }
237            }
238        }
239        if ($debug >= 0) {
240            my @found;
241            my @notfound;
242            foreach my $b (keys %build) {
243                push @found,$b if ($build{$b} =~ /yes/);
244                push @notfound,$b if ($build{$b} =~ /no/);
245            }
246            print $LOG "Build files generated for ".join(',',@found)."\n";
247            print $LOG "No Build files found for ".join(',',@notfound)."\n";
248        }
249        # Prepare the dest directory for archive
250        if (-x "$ENV{'PBCONF'}/$pbpkg/pbinit") {
251            #pb_system("cd $dest ; $ENV{'PBCONF'}/$pbpkg/pbinit","Executing init script $ENV{'PBCONF'}/$pbpkg/pbinit");
252            print $LOG "Executing init script $ENV{'PBCONF'}/$pbpkg/pbinit\n";
253            system("cd $dest ; $ENV{'PBCONF'}/$pbpkg/pbinit");
254        }
255
256        # Archive dest dir
257        chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
258        # Possibility to look at PBSRC to guess more the filename
259        pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
260        print $LOG "Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n" if ($debug >= 0);
261
262        # Keep track of what is generated for default
263        open(LAST,"> $pbrc->{$ENV{'PBPROJ'}}") || die "Unable to create $pbrc->{$ENV{'PBPROJ'}}";
264        print LAST "pbroot $pbprojver-$pbprojtag = $ENV{'PBROOT'}\n";
265        close(LAST);
266
267        # Keep track of per package version
268        if (! -f "$ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb") {
269            open(PKG,">$ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb";
270            print PKG "# Empty\n";
271            close(PKG);
272        }
273        my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb","pbpkg");
274        $pkg = { } if (not defined $pkg);
275        if ((not defined $pkg->{$pbpkg}) || ($pkg->{$pbpkg} ne "$pbver-$pbtag")) {
276            $pkg->{$pbpkg} = "$pbver-$pbtag";
277        }
278
279        print $LOG "DEBUG pkg: ".Dumper($pkg)."\n" if ($debug >= 1);
280        open(PKG,"> $ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb";
281        foreach my $p (keys %$pkg) {
282            print PKG "pbpkg $p = $pkg->{$p}\n";
283        }
284        close(PKG);
285    }
286}
287
288sub pb_build2pkg {
289
290    # Get list of packages to build
291    my $ptr = pb_get_pkg($defpkgdir,$extpkgdir);
292    @pkgs = @$ptr;
293
294    # Get the running distro to build on
295    my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
296    print $LOG "DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n" if ($debug >= 1);
297
298    # Get content saved in cms2build
299    my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb","pbpkg");
300    $pkg = { } if (not defined $pkg);
301
302    chdir "$ENV{'PBBUILDDIR'}";
303    my $made = ""; # pkgs made during build
304    foreach my $pbpkg (@pkgs) {
305        my $vertag = $pkg->{$pbpkg};
306        # get the version of the current package - maybe different
307        ($pbver,$pbtag) = split(/-/,$vertag);
308
309        my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
310        print $LOG "Source file: $src\n" if ($debug >= 0);
311
312        if ($dtype eq "rpm") {
313            print $LOG "Working under $ENV{'PBBUILDDIR'}\n" if ($debug >= 0);
314            foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
315                if (! -d "$ENV{'PBBUILDDIR'}/$d") {
316                pb_mkdir_p("$ENV{'PBBUILDDIR'}/$d") || die "Please ensure that you can write into $ENV{'PBBUILDDIR'} to create $d\nchown the $ENV{'PBBUILDDIR'} directory to your uid";
317                }
318            }
319
320            # We need to first extract the spec file
321            symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
322            my @specfile;
323            @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
324
325            print $LOG "specfile: ".Dumper(\@specfile)."\n" if ($debug >= 1);
326            # set LANGUAGE to check for correct log messages
327            $ENV{'LANGUAGE'}="C";
328            #system("ls -R $ENV{'PBBUILDDIR'}") if ($debug >= 1);
329            foreach my $f (@specfile) {
330                if ($f =~ /\.spec$/) {
331                    pb_system("rpmbuild --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
332                    last;
333                }
334            }
335            $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
336        } elsif ($dtype eq "deb") {
337            $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
338        } elsif ($dtype eq "ebuild") {
339            $made="$made portage/*/$pbpkg/$pbpkg-$pbver.ebuild";
340            pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage") if (! -d "$ENV{'PBBUILDDIR'}/portage");
341        } elsif ($dtype eq "slackware") {
342            $made="$made build-$pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
343            pb_mkdir_p("$ENV{'PBBUILDDIR'}/install") if (! -d "$ENV{'PBBUILDDIR'}/install");
344        } else {
345            die "Unknown dtype format $dtype";
346        }
347    }
348    # Keep track of what is generated so that we can get them back from VMs
349    open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag";
350    print KEEP "$made\n";
351    close(KEEP);
352}
353
354sub pb_build2ssh {
355    pb_send2ssh("Sources");
356}
357
358sub pb_pkg2ssh {
359    pb_send2ssh("Packages");
360}
361
362# By default deliver to the the public site hosting the
363# ftp structure (or whatever) or a VM
364sub pb_send2ssh {
365
366    my $cmt = shift;
367    my $vm = shift || undef;
368    my $host = shift || "sshhost";
369    my $login = shift || "sshlogin";
370    my $dir = shift || "sshdir";
371    my $port = shift || "sshport";
372
373    # Get list of packages to build
374    my $ptr = pb_get_pkg($defpkgdir,$extpkgdir);
375    @pkgs = @$ptr;
376
377    # Get the running distro to consider
378    my ($odir,$over) = (undef, undef);
379    if (defined $vm) {
380        ($odir,$over) = split(/_/,$vm);
381    }
382    my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
383    print $LOG "DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n" if ($debug >= 1);
384
385    # Get content saved in cms2build
386    my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb","pbpkg");
387    $pkg = { } if (not defined $pkg);
388
389    my $src = "";
390    chdir "$ENV{'PBBUILDDIR'}";
391    foreach my $pbpkg (@pkgs) {
392        my $vertag = $pkg->{$pbpkg};
393        # get the version of the current package - maybe different
394        ($pbver,$pbtag) = split(/-/,$vertag);
395
396        if (($cmt eq "Sources") || ($cmt eq "VMs")) {
397            $src="$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
398        }
399    }
400    if ($cmt eq "VMs") {
401        $src="$src $ENV{'PBDESTDIR'}/pbscript $ENV{'PBCONF'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb $ENV{'PBETC'}";
402    } elsif ($cmt eq "Packages") {
403        # Get package list from file made during build2pkg
404        open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag";
405        $src = <KEEP>;
406        chomp($src);
407        close(KEEP);
408        if ($dtype eq "rpm") {
409            # Also make a pbscript to generate yum/urpmi bases
410            # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
411        } elsif ($dtype eq "deb") {
412            # Also make a pbscript to generate apt bases
413            # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
414        }
415    }
416    # Remove potential leading spaces (cause pb with basename)
417    $src =~ s/^ *//;
418    my $basesrc = "";
419    foreach my $i (split(/ +/,$src)) {
420        $basesrc .= " ".basename($i);
421    }
422
423    print $LOG "Sources handled ($cmt): $src\n" if ($debug >= 0);
424    my ($sshhost,$sshlogin,$sshdir,$sshport) = pb_conf_get($host,$login,$dir,$port);
425    my $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
426    my $tdir;
427    my $bdir;
428    if ($cmt eq "Sources") {
429        $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
430    } elsif ($cmt eq "VMs") {
431        $tdir = dirname("$sshdir->{$ENV{'PBPROJ'}}")."/delivery";
432        $bdir = dirname("$sshdir->{$ENV{'PBPROJ'}}")."/build";
433        # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
434        $bdir =~ s|\$ENV.+\}/||;
435    } elsif ($cmt eq "Packages") {
436        $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
437    } else {
438        return;
439    }
440    # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
441    $tdir =~ s|\$ENV.+\}/||;
442
443    $port = $sshport->{$ENV{'PBPROJ'}};
444    pb_system("ssh -q -p $port $mac \"mkdir -p $tdir ; cd $tdir ; rm -f $basesrc\"","Preparing $tdir on $mac");
445    pb_system("cd $ENV{'PBBUILDDIR'} ; scp -p -P $port $src $mac:$tdir 2> /dev/null","$cmt delivery in $tdir on $mac");
446    pb_system("ssh -q -p $port $mac \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi\' | bash\"","Executing pbscript on $mac  if needed");
447    if ($cmt eq "VMs") {
448        # Get back info on pkg produced, compute their name and get them from the VM
449        pb_system("scp -p -P $port $mac:$bdir/pbgen-$pbprojver-$pbprojtag $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $tdir on $mac");
450        open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag";
451        my $src = <KEEP>;
452        chomp($src);
453        close(KEEP);
454        $src =~ s/^ *//;
455        pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
456        # Change pgben to make the next send2ssh happy
457        open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag";
458        my $made = "";
459        foreach my $p (split(/ +/,$src)) {
460            my $j = basename($p);
461            pb_system("scp -p -P $port $mac:\'$bdir/$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $tdir from $mac");
462            $made = "$made $odir/$over/$j\n";
463        }
464        print KEEP "$made\n";
465        close(KEEP);
466        #pb_system("ssh -q -p $port $mac \"rm -rf dirname("$sshdir->{$ENV{'PBPROJ'}}"); sudo /usr/bin/poweroff\"","VM cleanup and halt on $mac");
467        pb_send2ssh("Packages","$odir"."_"."$over");
468        #pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
469    }
470}
471
472sub pb_build2vm {
473    my ($vm,$all) = pb_get_vm();
474
475    # Prepare the script to be executed on the VM
476    # in $ENV{'PBDESTDIR'}/pbscript
477    open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
478    print SCRIPT "#!/bin/bash\n";
479    print SCRIPT "echo ... Execution needed\n";
480    print SCRIPT "# This is in directory delivery\n";
481    print SCRIPT "# Setup the variables required for building\n";
482    print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
483    print SCRIPT "# Preparation for pb\n";
484    print SCRIPT "mkdir -p ../pbconf\n";
485    print SCRIPT "mv $ENV{'PBPROJ'}.pb ../pbconf\n";
486    print SCRIPT "mv .pbrc \$HOME\n";
487    print SCRIPT "cd ..\n";
488    print SCRIPT "export PBROOT=\`pwd\`\n";
489    print SCRIPT "# Build\n";
490    my $p = "";
491    $p = $ARGV[0] if (defined $ARGV[0]);
492    print SCRIPT "echo Building packages on VM...\n";
493    print SCRIPT "pb build2pkg $p\n";
494    close(SCRIPT);
495    chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
496
497    # Send tar files when we do a global generation
498    pb_build2ssh() if ($all == 1);
499
500    foreach my $v (@$vm) {
501        # Launch the VMs
502        my ($ptr,$vmopt,$vmport,$vmpath) = pb_conf_get("vmtype","vmopt","vmport","vmpath");
503        my $vmtype = $ptr->{$ENV{'PBPROJ'}};
504        if (defined $vmopt->{$ENV{'PBPROJ'}}) {
505            $ENV{'PBVMOPT'} = $vmopt->{$ENV{'PBPROJ'}};
506        } else {
507            $ENV{'PBVMOPT'} = "";
508        }
509
510        my $cmd;
511        if ($vmtype eq "qemu") {
512            my $arch = `uname -m`;
513            chomp($arch);
514            my $qemucmd;
515            my $qemucmd32;
516            my $qemucmd64;
517            if ($arch eq "x86_64") {
518                $qemucmd32 = "/usr/bin/qemu-system-i386";
519                $qemucmd64 = "/usr/bin/qemu";
520            } else {
521                $qemucmd32 = "/usr/bin/qemu";
522                $qemucmd64 = "/usr/bin/qemu-system-x86_64";
523            }
524            if ($v =~ /_64/) {
525                $qemucmd = "$qemucmd64 -no-kqemu";
526            } else {
527                $qemucmd = "$qemucmd32";
528            }
529            if (! -f "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu") {
530                print "Unable to find VM $vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
531                next;
532            }
533            $cmd = "$qemucmd $ENV{'PBVMOPT'} -redir tcp:$vmport->{$ENV{'PBPROJ'}}:10.0.2.15:22 $vmpath->{$ENV{'PBPROJ'}}/$v.qemu"
534        } elsif ($vmtype eq "xen") {
535        } elsif ($vmtype eq "vmware") {
536        } else {
537            die "VM of type $vmtype not supported. Report to the dev team";
538        }
539        pb_system("$cmd &","Launching the VM");
540        pb_system("sleep 300","Waiting for it to come up");
541
542        # Gather all required files to send them to the VM and launch the build thourgh pbscript
543        pb_send2ssh("VMs","$v","vmhost","vmlogin","pbrc","vmport");
544    }
545}
546
547sub pb_get_pkg {
548
549my @pkgs;
550my $defpkgdir = shift;
551my $extpkgdir = shift;
552
553# Get packages list
554if (not defined $ARGV[0]) {
555    @pkgs = keys %$defpkgdir;
556} elsif ($ARGV[0] =~ /^all$/) {
557    @pkgs = keys %$defpkgdir;
558    push(@pkgs, keys %$extpkgdir);
559} else {
560    @pkgs = @ARGV;
561}
562print $LOG "Packages: ".join(',',@pkgs)."\n" if ($debug >= 0);
563return(\@pkgs);
564}
565
566#
567# Return the list of VMs we are working on
568# $all is a flag to know if we return all of them
569# or only some (if all we publish also tar files in addition to pkgs
570#
571sub pb_get_vm {
572
573my @vm;
574my $all = 0;
575
576# Get VM list
577if ((not defined $ENV{'PBVM'}) || ($ENV{'PBVM'} =~ /^all$/)) {
578    my ($ptr) = pb_conf_get("vmlist");
579    $ENV{'PBVM'} = $ptr->{$ENV{'PBPROJ'}};
580    $all = 1;
581}
582@vm = split(/,/,$ENV{'PBVM'});
583print $LOG "VMs: ".join(',',@vm)."\n";
584return(\@vm,$all);
585}
586
587sub pb_extract_build_files {
588
589my $src=shift;
590my $dir=shift;
591my $ddir=shift;
592my @files;
593
594pb_system("tar xfpz $src $dir","Extracting build files");
595opendir(DIR,"$dir") || die "Unable to open directory $dir";
596foreach my $f (readdir(DIR)) {
597    next if ($f =~ /^\./);
598    move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
599    print $LOG "mv $dir/$f $ddir\n" if ($debug >= 1);
600    push @files,"$ddir/$f";
601}
602closedir(DIR);
603# Not enough but still a first cleanup
604pb_rm_rf("$dir");
605return(@files);
606}
607
608sub pb_syntax {
609
610    print "pb (aka project-builder) Version $projectbuilderver-$projectbuilderrev\n";
611    print "\n";
612    print "Syntax: pb [-vhqt][-r pbroot][-p project][-m \"mach-1[,...]\"] <action> [<pkg1>...]\n";
613    print "\n";
614    print "-h : This help file\n";
615    print "-q : Quiet mode\n";
616    print "-t : Test mode (not done yet)\n";
617    print "-v : Verbose mode\n";
618    print "\n";
619    print "-m machine : Name of the virtual Machines you want\n";
620    print "             to build on (space separated). All if none precised\n";
621    print "             (or use the env variable PBVM)       \n";
622    print "\n";
623    print "-p project : Name of the project you're working on\n";
624    print "             (or use the env variable PBPROJ)     \n";
625    print "\n";
626    print "-r pbroot  : Path Name of project under the CMS \n";
627    print "             (or use the env variable PBROOT)   \n";
628    print "\n";
629    print "<action> can be:\n";
630    print "\n";
631    print "\tcms2build: Create tar files for the project under your CMS\n";
632    print "\t           CMS supported are SVN and CVS\n";
633    print "\t           parameters are packages to build\n";
634    print "\t           if not using default list\n";
635    print "\n";
636    print "\tbuild2pkg: Create packages for your running distribution  \n";
637    print "\n";
638    print "\tbuild2ssh: Send the tar files to a SSH host               \n";
639    print "\n";
640    print "\tpkg2ssh:   Send the packages built to a SSH host          \n";
641    print "\n";
642    print "\tcms2pkg:   cms2build + build2pkg\n";
643    print "\n";
644    print "\tbuild2vm:  Create packages in a Virtual Machine  \n";
645    print "\t           adn send them to a SSH host once built\n";
646    print "\t           VM supported are QEMU                 \n";
647    print "\n";
648    print "\tcms2vm:    cms2build + build2vm\n";
649    print "\n";
650}
Note: See TracBrowser for help on using the repository browser.