source: devel/pb/bin/pb @ 322

Last change on this file since 322 was 322, checked in by Bruno Cornec, 12 years ago

Trying to solve the remaining issues for upstream projects with local CMS (begin)

  • Property svn:executable set to *
File size: 39.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 File::Basename;
17use File::Copy;
18use Time::localtime qw(localtime);
19use POSIX qw(strftime);
20
21# Global variables
22use lib qw (lib);
23use ProjectBuilder::Distribution qw (pb_distro_init);
24use ProjectBuilder::Version qw (pb_version_init);
25use ProjectBuilder::Base;
26
27my %opts;                   # CLI Options
28my $action;                 # action to realize
29my $test = "FALSE";         # Not used
30my $force = 0;              # Force VE/VM rebuild
31my $option = "";            # Not used
32my @pkgs;                   # list of packages
33my $pbtag;                  # Global Tag variable
34my $pbver;                  # Global Version variable
35my $pbscript;               # Name of the script
36my %pbver;                  # per package
37my %pbtag;                  # per package
38my $pbrev;                  # Global REVISION variable
39my $pbaccount;              # Login to use to connect to the VM
40my $pbport;                 # Port to use to connect to the VM
41my $newver;                 # New version to create
42my $iso;                    # ISO iage for the VM to create
43
44my @date = pb_get_date();
45my $pbdate = strftime("%Y-%m-%d", @date);
46
47getopts('a:fhi:l:m:P:p:qr:s:tvV:',\%opts);
48
49my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
50if (defined $opts{'h'}) {
51    pb_syntax();
52    exit(0);
53}
54if (defined $opts{'v'}) {
55    $debug = 2;
56    #$debug = $opts{'v'};
57    pb_log(0,"Debug value: $debug\n");
58}
59if (defined $opts{'f'}) {
60    $force=1;
61}
62if (defined $opts{'q'}) {
63    $debug=-1;
64}
65if (defined $opts{'l'}) {
66    open(LOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
67    $LOG = *LOG;
68    $debug = 0  if ($debug == -1);
69    }
70pb_log_init($debug, $LOG);
71
72# Handles test option
73if (defined $opts{'t'}) {
74    $test = "TRUE";
75    # Works only for SVN
76    $option = "-r BASE";
77}
78
79# Handle root of the project if defined
80if (defined $opts{'r'}) {
81    $ENV{'PBROOT'} = $opts{'r'};
82}
83# Handle virtual machines if any
84if (defined $opts{'m'}) {
85    $ENV{'PBV'} = $opts{'m'};
86}
87if (defined $opts{'s'}) {
88    $pbscript = $opts{'s'};
89}
90if (defined $opts{'a'}) {
91    $pbaccount = $opts{'a'};
92}
93if (defined $opts{'P'}) {
94    $pbport = $opts{'P'};
95}
96if (defined $opts{'V'}) {
97    $newver = $opts{'V'};
98}
99if (defined $opts{'i'}) {
100    $iso = $opts{'i'};
101}
102
103# Get Action
104$action = shift @ARGV;
105die pb_syntax() if (not defined $action);
106
107my ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir);
108my $pbinit = undef;
109$pbinit = 1 if ($action =~ /^newproj$/);
110
111# Handles project name if any
112# And get global params
113if (defined $opts{'p'}) {
114    ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) 
115    = pb_env_init($opts{'p'},$pbinit);
116} else {
117    ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) 
118    = pb_env_init(undef,$pbinit);
119}
120
121pb_log(0,"Project: $ENV{'PBPROJ'}\n");
122pb_log(0,"Action: $action\n");
123
124# Keep those project values to store them at the end each time
125my $pbprojtag = $ENV{'PBTAG'};
126my $pbprojver = $ENV{'PBVER'};
127
128# Act depending on action
129if ($action =~ /^cms2build$/) {
130    pb_cms2build();
131} elsif ($action =~ /^build2pkg$/) {
132    pb_build2pkg();
133} elsif ($action =~ /^cms2pkg$/) {
134    pb_cms2build();
135    pb_build2pkg();
136} elsif ($action =~ /^build2ssh$/) {
137    pb_build2ssh();
138} elsif ($action =~ /^cms2ssh$/) {
139    pb_cms2build();
140    pb_build2ssh();
141} elsif ($action =~ /^pkg2ssh$/) {
142    pb_pkg2ssh();
143} elsif ($action =~ /^build2ve$/) {
144    pb_build2v("ve");
145} elsif ($action =~ /^build2vm$/) {
146    pb_build2v("vm");
147} elsif ($action =~ /^cms2ve$/) {
148    pb_cms2build();
149    pb_build2v("ve");
150} elsif ($action =~ /^cms2vm$/) {
151    pb_cms2build();
152    pb_build2v("vm");
153} elsif ($action =~ /^launchvm$/) {
154    pb_launchv("vm",$ENV{'PBV'},0);
155} elsif ($action =~ /^launchve$/) {
156    pb_launchv("ve",$ENV{'PBV'},0);
157} elsif ($action =~ /^script2vm$/) {
158    pb_script2v($pbscript,"vm");
159} elsif ($action =~ /^script2ve$/) {
160    pb_script2v($pbscript,"ve");
161} elsif ($action =~ /^newver$/) {
162    pb_newver();
163} elsif ($action =~ /^newve$/) {
164    pb_launchv("ve",$ENV{'PBV'},1);
165} elsif ($action =~ /^newvm$/) {
166    pb_launchv("vm",$ENV{'PBV'},1);
167} elsif ($action =~ /^newproj$/) {
168    # Nothing to do - already done in pb_env_init
169} elsif ($action =~ /^clean$/) {
170} else {
171    pb_log(0,"\'$action\' is not available\n");
172    pb_syntax();
173}
174
175sub pb_cms2build {
176
177    my $ptr = pb_get_pkg($defpkgdir,$extpkgdir);
178    @pkgs = @$ptr;
179    my ($scheme,$uri)=pb_cms_init($ENV{'PBPROJ'});
180
181    my ($pkgv, $pkgt) = pb_conf_get_if("pkgver","pkgtag");
182
183    # declare packager for filtering
184    my ($tmp) = pb_conf_get("pbpackager");
185    my $pbpackager = $tmp->{$ENV{'PBPROJ'}};
186
187    foreach my $pbpkg (@pkgs) {
188        $ENV{'PBPKG'} = $pbpkg;
189        $ENV{'PBVER'} = $pbprojver;
190        $ENV{'PBTAG'} = $pbprojtag;
191        if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
192            $pbver = $pkgv->{$pbpkg};
193            $ENV{'PBVER'} = $pbver;
194        } else {
195            $pbver = $ENV{'PBVER'};
196        }
197        if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
198            $pbtag = $pkgt->{$pbpkg};
199            $ENV{'PBTAG'} = $pbtag;
200        } else {
201            $pbtag = $ENV{'PBTAG'};
202        }
203
204        $pbrev = $ENV{'PBREVISION'};
205        pb_log(0,"\n");
206        pb_log(0,"Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n");
207        die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
208        # Clean up dest if necessary. The export will recreate it
209        my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver";
210        pb_rm_rf($dest) if (-d $dest);
211
212        # Export CMS tree for the concerned package to dest
213        # And generate some additional files
214        $OUTPUT_AUTOFLUSH=1;
215
216        # computes in which dir we have to work
217        my $dir = $defpkgdir->{$pbpkg};
218        $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
219        pb_log(2,"def:".Dumper($defpkgdir)." ext: ".Dumper($extpkgdir)." \n");
220
221        # If it isn't a flat CMS, then we have the choice to export subdir
222        #$dir = "$uri/$dir" if ($ENV{'PBREVISION'} ne "flat");
223        pb_cms_export($uri,"$dir",$dest);
224
225        # Get project info on authors and log file
226        my $chglog = "$ENV{'PBCONF'}/$pbpkg/pbcl";
227        $chglog = "$ENV{'PBCONF'}/pbcl" if (! -f $chglog);
228        $chglog = undef if (! -f $chglog);
229
230        my $authors = "$ENV{'PBCONF'}/$pbpkg/pbauthors";
231        $authors = "$ENV{'PBCONF'}/pbauthors" if (! -f $authors);
232        $authors = "/dev/null" if (! -f $authors);
233
234        # Extract cms log history and store it
235        if ((defined $chglog) && (! -f "$dest/NEWS")) {
236            pb_log(2,"Generating NEWS file from $chglog\n");
237            copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
238        }
239        pb_cms_log($scheme,$dir,$dest,$chglog,$authors);
240
241        my %build;
242
243        my ($ptr) = pb_conf_get_if("vmlist","velist");
244        foreach my $d (split(/,/,$ptr->{$ENV{'PBPROJ'}})) {
245            my ($name,$ver,$arch) = split(/-/,$d);
246            chomp($arch);
247            my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
248            pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n");
249            pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
250
251            # Filter build files from the less precise up to the most with overloading
252            # Filter all files found, keeping the name, and generating in dest
253
254            # Find all build files first relatively to PBROOT
255            # Find also all specific files referenced in the .pb conf file
256            my %bfiles = ();
257            my %pkgfiles = ();
258            pb_log(2,"DEBUG dir: $ENV{'PBCONF'}/$pbpkg\n");
259            $build{"$ddir-$dver"} = "yes";
260
261            if (-d "$ENV{'PBROOT'}/$pbpkg/$dtype") {
262                pb_list_bfiles("$ENV{'PBROOT'}/$pbpkg/$dtype",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
263            } elsif (-d "$ENV{'PBROOT'}/$pbpkg/$dfam") {
264                pb_list_bfiles("$ENV{'PBROOT'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
265            } elsif (-d "$ENV{'PBROOT'}/$pbpkg/$ddir") {
266                pb_list_bfiles("$ENV{'PBROOT'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
267            } elsif (-d "$ENV{'PBROOT'}/$pbpkg/$ddir-$dver") {
268                pb_list_bfiles("$ENV{'PBROOT'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
269            } else {
270                $build{"$ddir-$dver"} = "no";
271                next;
272            }
273            pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
274
275            # Get all filters to apply
276            my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
277
278            # Apply now all the filters on all the files concerned
279            # destination dir depends on the type of file
280            if (defined $ptr) {
281                foreach my $f (values %bfiles,values %pkgfiles) {
282                    pb_filter_file_pb("$ENV{'PBROOT'}/$f",$ptr,"$dest/pbconf/$ddir-$dver/".basename($f),$dtype,$pbsuf,$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$defpkgdir,$extpkgdir,$pbpackager,$chglog);
283                }
284            }
285        }
286        my @found;
287        my @notfound;
288        foreach my $b (keys %build) {
289            push @found,$b if ($build{$b} =~ /yes/);
290            push @notfound,$b if ($build{$b} =~ /no/);
291        }
292        pb_log(0,"Build files generated for ".join(',',@found)."\n");
293        pb_log(0,"No Build files found for ".join(',',@notfound)."\n") if (@notfound);
294        # Get the generic filter (all.pbf) and
295        # apply those to the non-build files including those
296        # generated by pbinit if applicable
297
298        # Get only all.pbf filter
299        $ptr = pb_get_filters($pbpkg);
300
301        my $liste ="";
302        if (defined $filteredfiles->{$pbpkg}) {
303            foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
304                pb_filter_file_inplace($ptr,"$dest/$f",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$pbpackager);
305                $liste = "$f $liste";
306            }
307        }
308        pb_log(2,"Files ".$liste."have been filtered\n");
309
310        # Prepare the dest directory for archive
311        if (-x "$ENV{'PBROOT'}/$pbpkg/pbinit") {
312            pb_filter_file("$ENV{'PBROOT'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$pbpackager);
313            chmod 0755,"$ENV{'PBTMP'}/pbinit";
314            pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOT'}/$pbpkg/pbinit");
315        }
316
317        # Archive dest dir
318        chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
319        # Possibility to look at PBSRC to guess more the filename
320        pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
321        pb_log(2,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
322
323        # Keep track of what is generated by default
324        open(LAST,"> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
325        #print LAST "pbroot $pbprojver-$pbprojtag = $ENV{'PBROOT'}\n";
326        # Why not use pbproj ?
327        print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOT'}\n";
328        close(LAST);
329
330        # Keep track of per package version
331        my ($pkg) = pb_conf_read_if("$ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb","pbpkg");
332        $pkg = { } if (not defined $pkg);
333        if ((not defined $pkg->{$pbpkg}) || ($pkg->{$pbpkg} ne "$pbver-$pbtag")) {
334            $pkg->{$pbpkg} = "$pbver-$pbtag";
335        }
336
337        pb_log(2,"DEBUG pkg: ".Dumper($pkg)."\n");
338        open(PKG,"> $ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb";
339        foreach my $p (keys %$pkg) {
340            print PKG "pbpkg $p = $pkg->{$p}\n";
341        }
342        close(PKG);
343
344        # Final cleanup
345        pb_rm_rf($dest) if (-d $dest);
346    }
347}
348
349sub pb_build2pkg {
350
351    # Get list of packages to build
352    my $ptr = pb_get_pkg($defpkgdir,$extpkgdir);
353    @pkgs = @$ptr;
354
355    # Get the running distro to build on
356    my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
357    pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
358
359    # Get content saved in cms2build
360    my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb","pbpkg");
361    $pkg = { } if (not defined $pkg);
362
363    # declare packager (via env var in VM/VE
364    my $pbpackager;
365    if (not defined $ENV{'PBPACKAGER'}) {
366        my ($tmp) = pb_conf_get("pbpackager");
367        $pbpackager = $tmp->{$ENV{'PBPROJ'}};
368    } else {
369        $pbpackager = $ENV{'PBPACKAGER'};
370    }
371
372    chdir "$ENV{'PBBUILDDIR'}";
373    my $made = ""; # pkgs made during build
374    foreach my $pbpkg (@pkgs) {
375        my $vertag = $pkg->{$pbpkg};
376        # get the version of the current package - maybe different
377        ($pbver,$pbtag) = split(/-/,$vertag);
378
379        my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
380        pb_log(2,"Source file: $src\n");
381
382        pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
383        if ($dtype eq "rpm") {
384            foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
385                if (! -d "$ENV{'PBBUILDDIR'}/$d") {
386                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";
387                }
388            }
389
390            # Remove in case a previous link/file was there
391            unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
392            symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
393            # We need to first extract the spec file
394            my @specfile;
395            @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
396
397            pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
398            # set LANGUAGE to check for correct log messages
399            $ENV{'LANGUAGE'}="C";
400            foreach my $f (@specfile) {
401                if ($f =~ /\.spec$/) {
402                    pb_system("rpmbuild --define \'packager $pbpackager\' --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
403                    last;
404                }
405            }
406            $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
407            if (-f "/usr/bin/rpmlint") {
408                pb_system("rpmlint $made","Checking validity of rpms with rpmlint");
409            }
410        } elsif ($dtype eq "deb") {
411            chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
412            pb_system("tar xfz $src","Extracting sources");
413
414            chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
415            pb_rm_rf("debian");
416            symlink "pbconf/$ddir-$dver","debian" || die "Unable to symlink to pbconf/$ddir-$dver";
417            chmod 0755,"debian/rules";
418            pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package");
419            $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
420            if (-f "/usr/bin/lintian") {
421                pb_system("lintian $made","Checking validity of debs with lintian");
422            }
423        } elsif ($dtype eq "ebuild") {
424            my @ebuildfile;
425            # For gentoo we need to take pb as subsystem name
426            # We put every apps here under sys-apps. hope it's correct
427            # We use pb's home dir in order o have a single OVERLAY line
428            my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
429            pb_mkdir_p($tmpd) if (! -d "$tmpd");
430            pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
431
432            # We need to first extract the ebuild file
433            @ebuildfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$tmpd");
434
435            # Prepare the build env for gentoo
436            my $found = 0;
437            my $pbbd = $ENV{'HOME'};
438            $pbbd =~ s|/|\\/|g;
439            if (-r "/etc/make.conf") {
440                open(MAKE,"/etc/make.conf");
441                while (<MAKE>) {
442                    $found = 1 if (/$pbbd\/portage/);
443                }
444                close(MAKE);
445            }
446            if ($found == 0) {
447                pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
448            }
449            #$found = 0;
450            #if (-r "/etc/portage/package.keywords") {
451            #open(KEYW,"/etc/portage/package.keywords");
452            #while (<KEYW>) {
453            #$found = 1 if (/portage\/pb/);
454            #}
455            #close(KEYW);
456            #}
457            #if ($found == 0) {
458            #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
459            #}
460
461            # Build
462            foreach my $f (@ebuildfile) {
463                if ($f =~ /\.ebuild$/) {
464                    move($f,"$tmpd/$pbpkg-$pbver.ebuild");
465                    pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package");
466                    # Now move it where pb expects it
467                    pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
468                    move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
469                }
470            }
471
472            $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver.ebuild";
473        } elsif ($dtype eq "slackware") {
474            $made="$made build-$pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
475            pb_mkdir_p("$ENV{'PBBUILDDIR'}/install") if (! -d "$ENV{'PBBUILDDIR'}/install");
476        } else {
477            die "Unknown dtype format $dtype";
478        }
479    }
480    # Keep track of what is generated so that we can get them back from VMs
481    open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag";
482    print KEEP "$made\n";
483    close(KEEP);
484}
485
486sub pb_build2ssh {
487    pb_send2target("Sources");
488}
489
490sub pb_pkg2ssh {
491    pb_send2target("Packages");
492}
493
494# By default deliver to the the public site hosting the
495# ftp structure (or whatever) or a VM/VE
496sub pb_send2target {
497
498    my $cmt = shift;
499    my $v = shift || undef;
500    my $vmexist = shift || 0;           # 0 is FALSE
501    my $vmpid = shift || 0;             # 0 is FALSE
502
503    my $host = "sshhost";
504    my $login = "sshlogin";
505    my $dir = "sshdir";
506    my $port = "sshport";
507    my $tmout = "sshtmout";
508    my $path = "sshpath";
509    my $conf = "sshconf";
510    my $rebuild = "sshrebuild";
511    if ($cmt eq "vm") {
512        $login = "vmlogin";
513        $dir = "pbdefdir";
514        $tmout = "vmtmout";
515        $rebuild = "vmrebuild";
516        # Specific VM
517        $host = "vmhost";
518        $port = "vmport";
519    } elsif ($cmt eq "ve") {
520        $login = "velogin";
521        $dir = "pbdefdir";
522        $tmout = "vetmout";
523        # Specific VE
524        $path = "vepath";
525        $conf = "veconf";
526        $rebuild = "verebuild";
527    }
528    my $cmd = "";
529
530    # Get list of packages to build
531    my $ptr = pb_get_pkg($defpkgdir,$extpkgdir);
532    @pkgs = @$ptr;
533
534    # Get the running distro to consider
535    my ($odir,$over,$oarch) = (undef, undef);
536    if (defined $v) {
537        ($odir,$over,$oarch) = split(/-/,$v);
538    }
539    my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
540    pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
541
542    # Get content saved in cms2build
543    my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb","pbpkg");
544    $pkg = { } if (not defined $pkg);
545
546    my $src = "";
547    chdir "$ENV{'PBBUILDDIR'}";
548    foreach my $pbpkg (@pkgs) {
549        my $vertag = $pkg->{$pbpkg};
550        # get the version of the current package - maybe different
551        ($pbver,$pbtag) = split(/-/,$vertag);
552
553        if (($cmt eq "Sources") || ($cmt eq "vm") || ($cmt eq "ve")) {
554            $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
555            if ($cmd eq "") {
556                $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
557            } else {
558                $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
559            }
560        }
561    }
562    if (($cmt eq "vm") || ($cmt eq "ve")) {
563        $src="$src $ENV{'PBDESTDIR'}/pbscript $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$pbprojver-$pbprojtag.pb $ENV{'PBETC'}";
564    } elsif ($cmt eq "Script") {
565        $src="$src $ENV{'PBDESTDIR'}/pbscript";
566    } elsif ($cmt eq "Packages") {
567        # Get package list from file made during build2pkg
568        open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag";
569        $src = <KEEP>;
570        chomp($src);
571        close(KEEP);
572        if ($dtype eq "rpm") {
573            # Also make a pbscript to generate yum/urpmi bases
574            # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
575        } elsif ($dtype eq "deb") {
576            # Also make a pbscript to generate apt bases
577            # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
578        }
579    }
580    # Remove potential leading spaces (cause problem with basename)
581    $src =~ s/^ *//;
582    my $basesrc = "";
583    foreach my $i (split(/ +/,$src)) {
584        $basesrc .= " ".basename($i);
585    }
586
587    pb_log(0,"Sources handled ($cmt): $src\n");
588    my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf) = pb_conf_get($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf);
589    pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
590    # Not mandatory
591    my ($testver) = pb_conf_get_if("testver");
592
593    my $mac;
594    # Useless for VE
595    if ($cmt ne "ve") {
596        $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
597        # Overwrite account value if passed as parameter
598        $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
599    }
600
601    my $tdir;
602    my $bdir;
603    if (($cmt eq "Sources") || ($cmt eq "Script")) {
604        $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
605    } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
606        $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
607        $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
608        # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
609        $bdir =~ s|\$ENV.+\}/||;
610    } elsif ($cmt eq "Packages") {
611        $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
612        if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} eq "true")) {
613            # This is a test pkg => target dir is under test
614            $tdir .= "/test";
615        }
616    } else {
617        return;
618    }
619
620    # Useless for VE
621    my $nport;
622    if ($cmt ne "ve") {
623        $nport = $sshport->{$ENV{'PBPROJ'}};
624        $nport = "$pbport" if (defined $pbport);
625    }
626
627    # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
628    $tdir =~ s|\$ENV.+\}/||;
629
630    my $tm = $vtmout->{$ENV{'PBPROJ'}};
631
632    # ssh communication if not VE
633    my ($shcmd,$cpcmd,$cptarget,$cp2target);
634    if ($cmt ne "ve") {
635        $shcmd = "ssh -q -p $nport $mac";
636        $cpcmd = "scp -p -P $nport";
637        $cptarget = "$mac:$tdir";
638        $cp2target = "$mac:$bdir";
639    } else {
640        my $tp = $vepath->{$ENV{'PBPROJ'}};
641        $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
642        $cpcmd = "cp -a ";
643        $cptarget = "$tp/$tdir";
644        $cp2target = "$tp/$bdir";
645    }
646
647    pb_system("$shcmd \"mkdir -p $tdir ; cd $tdir ; echo \'for i in $basesrc; do if [ -f \$i ]; then rm -f \$i; fi; done\ ; $cmd' | bash\"","Preparing $tdir on $cptarget");
648    pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
649    # For VE we need to change the owner manually - To be tested if needed
650    #if ($cmt eq "ve") {
651    #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
652    #}
653    pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi\' | bash\"","Executing pbscript on $cptarget if needed");
654    if (($cmt eq "vm") || ($cmt eq "ve")) {
655        # Get back info on pkg produced, compute their name and get them from the VM
656        pb_system("$cpcmd $cp2target/pbgen-$pbprojver-$pbprojtag $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
657        open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag";
658        my $src = <KEEP>;
659        chomp($src);
660        close(KEEP);
661        $src =~ s/^ *//;
662        pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
663        # Change pgben to make the next send2target happy
664        my $made = "";
665        open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$pbprojver-$pbprojtag";
666        foreach my $p (split(/ +/,$src)) {
667            my $j = basename($p);
668            pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
669            $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
670        }
671        print KEEP "$made\n";
672        close(KEEP);
673        pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
674        pb_send2target("Packages","$odir"."_"."$over");
675        if ((! $vmexist) && ($cmt eq "vm")) {
676            pb_system("$shcmd \"sudo /sbin/halt -p \"; sleep $tm ; echo \'if [ -d /proc/$vmpid ]; then kill -9 $vmpid; fi \' | bash ; sleep 10","VM $v halt (pid $vmpid)");
677        }
678        pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
679    }
680}
681
682sub pb_script2v {
683    my $pbscript=shift;
684    my $vtype=shift;
685
686    # Prepare the script to be executed on the VM
687    # in $ENV{'PBDESTDIR'}/pbscript
688    if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
689        copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
690        chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
691    }
692
693    my ($vm,$all) = pb_get_v($vtype);
694    my ($vmexist,$vmpid) = (undef,undef);
695
696    foreach my $v (@$vm) {
697        # Launch the VM/VE
698        if ($vtype eq "vm") {
699            ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
700
701            # Skip that VM if something went wrong
702            next if (($vmpid == 0) && ($vmexist ==0));
703        }
704
705        # Gather all required files to send them to the VM
706        # and launch the build through pbscript
707        pb_send2target("Script","$v",$vmexist,$vmpid);
708
709    }
710}
711
712sub pb_launchv {
713    my $vtype = shift;
714    my $v = shift;
715    my $create = shift || 0;        # By default do not create a VM
716
717    die "No VM/VE defined, unable to launch" if (not defined $v);
718    # Keep only the first VM in case many were given
719    $v =~ s/,.*//;
720
721    # Which is our local arch ? (standardize on i386 for those platforms)
722    my $arch = `uname -m`;
723    chomp($arch);
724    $arch =~ s/i.86/i386/;
725
726    # Launch the VMs/VEs
727    if ($vtype eq "vm") {
728        die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
729
730        my ($ptr,$vmopt,$vmport,$vmpath,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmport","vmpath","vmtmout","vmsize");
731
732        my $vmtype = $ptr->{$ENV{'PBPROJ'}};
733        if (not defined $ENV{'PBVMOPT'}) {
734            $ENV{'PBVMOPT'} = "";
735        }
736        if (defined $vmopt->{$ENV{'PBPROJ'}}) {
737            $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
738        }
739        my $nport = $vmport->{$ENV{'PBPROJ'}};
740        $nport = "$pbport" if (defined $pbport);
741   
742        my $cmd;
743        my $vmcmd;      # has to be used for pb_check_ps
744        my $vmm;        # has to be used for pb_check_ps
745        if ($vmtype eq "qemu") {
746            my $qemucmd32;
747            my $qemucmd64;
748            if ($arch eq "x86_64") {
749                $qemucmd32 = "/usr/bin/qemu-system-i386";
750                $qemucmd64 = "/usr/bin/qemu";
751            } else {
752                $qemucmd32 = "/usr/bin/qemu";
753                $qemucmd64 = "/usr/bin/qemu-system-x86_64";
754            }
755        if ($v =~ /x86_64/) {
756                $vmcmd = "$qemucmd64 -no-kqemu";
757            } else {
758                $vmcmd = "$qemucmd32";
759            }
760            $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
761            if ($create != 0) {
762                $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
763            }
764            $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
765        } elsif ($vmtype eq "xen") {
766        } elsif ($vmtype eq "vmware") {
767        } else {
768            die "VM of type $vmtype not supported. Report to the dev team";
769        }
770        my ($tmpcmd,$void) = split(/ +/,$cmd);
771        my $vmexist = pb_check_ps($tmpcmd,$vmm);
772        my $vmpid = 0;
773        if (! $vmexist) {
774            if ($create != 0) {
775                if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
776                    pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
777                } elsif ($vmtype eq "vmware") {
778                } else {
779                }
780            }
781            if (! -f "$vmm") {
782                pb_log(0,"Unable to find VM $vmm\n");
783            } else {
784                pb_system("$cmd &","Launching the VM $vmm");
785                pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
786                $vmpid = pb_check_ps($tmpcmd,$vmm);
787            }
788        } else {
789            pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
790        }
791        return($vmexist,$vmpid);
792    # VE here
793    } else {
794        # Get VE context
795        my ($ptr,$vepath,$vetmout,$verebuild,$veconf) = pb_conf_get("vetype","vepath","vetmout","verebuild","veconf");
796        my $vetype = $ptr->{$ENV{'PBPROJ'}};
797
798        # Get distro context
799        my ($name,$ver,$darch) = split(/-/,$v);
800        chomp($darch);
801        my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
802
803        if ($vetype eq "chroot") {
804            # Architecture consistency
805            if ($arch ne $darch) {
806                die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
807            }
808
809            if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
810                # We have to rebuild the chroot
811                if ($dtype eq "rpm") {
812                    pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
813                    # Once setup we need to install some packages, the pb account, ...
814                    pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
815                    #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
816                } elsif ($dtype eq "deb") {
817                    pb_system("","Creating the pbuilder VE");
818                } elsif ($dtype eq "ebuild") {
819                    die "Please teach the dev team how to build gentoo chroot";
820                } else {
821                    die "Unknown distribution type $dtype. Report to dev team";
822                }
823            }
824            # Nothing more to do for VE. No real launch
825        } else {
826            die "VE of type $vetype not supported. Report to the dev team";
827        }
828    }
829}
830
831sub pb_build2v {
832
833my $vtype = shift;
834
835# Prepare the script to be executed on the VM/VE
836# in $ENV{'PBDESTDIR'}/pbscript
837my ($ntp) = pb_conf_get($vtype."ntp");
838my $vntp = $ntp->{$ENV{'PBPROJ'}};
839
840open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
841print SCRIPT "#!/bin/bash\n";
842print SCRIPT "echo ... Execution needed\n";
843print SCRIPT "# This is in directory delivery\n";
844print SCRIPT "# Setup the variables required for building\n";
845print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
846print SCRIPT "# Preparation for pb\n";
847print SCRIPT "mv .pbrc \$HOME\n";
848print SCRIPT "cd ..\n";
849# Force new date to be in the future compared to the date of the tar file by adding 1 minute
850my @date=pb_get_date();
851$date[1]++;
852my $upddate = strftime("%m%d%H%M%Y", @date);
853print SCRIPT "echo Setting up date on $vntp...\n";
854# Or use ntpdate if available TBC
855print SCRIPT "sudo date $upddate\n";
856# This exports avoids pb_env_init to deal with PBCONF stuff
857print SCRIPT "export PBCONF=/tmp\n";
858print SCRIPT "export PBVER=$ENV{'PBVER'}\n";
859print SCRIPT "export PBTAG=$ENV{'PBTAG'}\n";
860print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
861print SCRIPT "# Build\n";
862# Get list of packages to build
863my $ptr = pb_get_pkg($defpkgdir,$extpkgdir);
864@pkgs = @$ptr;
865my $p = join(' ',@pkgs) if (@pkgs);
866print SCRIPT "echo Building packages on $vtype...\n";
867print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
868close(SCRIPT);
869chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
870
871my ($v,$all) = pb_get_v($vtype);
872
873# Send tar files when we do a global generation
874pb_build2ssh() if ($all == 1);
875
876my ($vmexist,$vmpid) = (undef,undef);
877
878foreach my $v (@$v) {
879    if ($vtype eq "vm") {
880        # Launch the VM
881        my ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
882
883        # Skip that VM if it something went wrong
884        next if (($vmpid == 0) && ($vmexist == 0));
885    }
886    # Gather all required files to send them to the VM/VE
887    # and launch the build thourgh pbscript
888    pb_send2target($vtype,"$v",$vmexist,$vmpid);
889}
890}
891
892
893sub pb_newver {
894
895    die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
896    my $scheme=pb_cms_init($ENV{'PBPROJ'});
897    if ($scheme ne "svn") {
898        die "Only SVN is supported at the moment";
899    }
900    my $res = pb_cms_isdiff($scheme);
901    die "You need to have no differences before creating a new version" if ($res != 0);
902    my $cmsurl = pb_cms_getinfo($scheme,$ENV{'PBROOT'},"URL:");
903    my $newurl = dirname($cmsurl)."/$newver";
904    pb_cms_copy($scheme,$cmsurl,$newurl);
905    pb_cms_checkout($scheme,$newurl,"$ENV{'PBROOT'}/../$newver");
906    my $oldver=basename($cmsurl);
907    open(FILE,"$ENV{'PBROOT'}/../$newver/pbconf/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOT'}/../$newver/pbconf/$ENV{'PBPROJ'}.pb";
908    open(OUT,"> $ENV{'PBROOT'}/../$newver/pbconf/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOT'}/../$newver/pbconf/$ENV{'PBPROJ'}.pb.new";
909    while(<FILE>) {
910        s/projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
911        print OUT $_;
912    }
913    close(FILE);
914    close(OUT);
915    rename("$ENV{'PBROOT'}/../$newver/pbconf/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOT'}/../$newver/pbconf/$ENV{'PBPROJ'}.pb");
916    pb_cms_checkin($scheme,"$ENV{'PBROOT'}/../$newver");
917}
918
919#
920# Return the list of VMs/VEs we are working on
921# $all is a flag to know if we return all of them
922# or only some (if all we publish also tar files in addition to pkgs
923#
924sub pb_get_v {
925
926my $vtype = shift;
927my @v;
928my $all = 0;
929my $vlist;
930my $pbv = 'PBV';
931
932if ($vtype eq "vm") {
933    $vlist = "vmlist";
934} elsif ($vtype eq "ve") {
935    $vlist = "velist";
936}
937# Get VM/VE list
938if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
939    my ($ptr) = pb_conf_get($vlist);
940    $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
941    $all = 1;
942}
943pb_log(2,"$vtype: $ENV{$pbv}\n");
944@v = split(/,/,$ENV{$pbv});
945return(\@v,$all);
946}
947
948sub pb_setup_v {
949# Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
950# Needs to use root account to connect to the VM/VE
951
952# pb will take your local public SSH key to access
953# the pb account in the VM later on
954
955my $vtype = shift;
956
957my $file = "$ENV{'HOME'}/.ssh/id_dsa.pub";
958die "Unable to find your public ssh key as $file";
959
960open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
961print SCRIPT << 'EOF';
962#!/usr/bin/perl -w
963
964$file="/etc/passwd";
965open(PBFILE,$file) || die "Unable to open $file";
966my $found = 0;
967while (<PBFILE>) {
968    $found = 1 if (/^pb:/);
969}
970close(PBFILE);
971
972if ( $found == 0 ) {
973    if ( ! -d "/home" ) {
974        mkdir "/home";
975    }
976    system "groupadd pb";
977    system "useradd pb -g pb -m -d /home/pb";
978}
979
980# For root
981mkdir ".ssh",0700;
982system 'cp /tmp/pbkey .ssh/authorized_keys';
983chmod 0600,".ssh/authorized_keys";
984
985# For pb
986chdir "/home/pb";
987mkdir ".ssh",0700;
988system 'cp /tmp/pbkey .ssh/authorized_keys';
989chmod 0600,".ssh/authorized_keys";
990system 'chown -R pb:pb .ssh';
991
992# No passwd for pb only keys
993$file="/etc/shadow";
994open(PBFILE,$file) || die "Unable to open $file";
995open(PBOUT,"> $file.new") || die "Unable to open $file.new";
996while (<PBFILE>) {
997    s/^pb:\!\!:/pb:*:/;
998    s/^pb:\!:/pb:*:/;   #SLES 9 e.g.
999    print PBOUT $_;
1000}
1001close(PBFILE);
1002close(PBOUT);
1003rename("$file.new",$file);
1004chmod 0640,$file;
1005
1006# pb has to be added to portage group on gentoo
1007unlink "/tmp/pbkey";
1008
1009my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init(); 
1010print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
1011
1012# Get and install pb
1013if ( $ddir eq "fedora" ) {
1014    system "yum clean all";
1015    system "yum update -y";
1016    my $arch=`uname -m`;
1017    my $opt = "";
1018    chomp($arch);
1019    if ($arch eq "x86_64") {
1020        $opt="--exclude=*.i?86";
1021    }
1022
1023    system "yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-ExtUtils-MakeMaker";
1024} elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || (($ddir eq "mandrake") && ($dver eq "10.1"))) {
1025    # Suppose pkg are installed already
1026    system "rpm -e lsb 2>&1 > /dev/null";
1027    system "rm -rf DateManip* ; wget http://search.cpan.org/CPAN/authors/id/S/SB/SBECK/Date-Manip-5.46.tar.gz ; tar xvfz Date-Manip-5.46.tar.gz ; cd Date-Manip* ; perl Makefile.PL ; make ; make install ; cd .. ";
1028} elsif ($ddir eq "suse") { 
1029    # New OpenSuSE
1030    system "export TERM=linux ; liste=\"\" ; for i in make wget patch sudo perl-DateManip perl-File-HomeDir xntp; do rpm -q \$i 1> /dev/null 2> /dev/null ; if [ \$\? != 0 ]; then liste=\"\$liste \$i\"; fi; done; echo \"Liste: \$liste\" ; if [ \"\$liste\" != \"\" ]; then yast2 -i \$liste ; fi";
1031} elsif ( $dfam eq "md" ) {
1032        system "urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-DateManip";
1033} elsif ( $dfam eq "du" ) {
1034    if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
1035        system "apt-get update; apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libdate-manip-perl";
1036    } else  {
1037        system "apt-get update; apt-get -y install wget patch openssh-server dpkg-dev sudo debian-builder dh-make fakeroot ntpdate rses5-dev libdate-manip-perl";
1038    }
1039} elsif ( $dfam eq "gen" ) {
1040        system "emerge -u system ; emerge wget sudo ntp DateManip";
1041} else {
1042    print "No pkg to install\n";
1043}
1044
1045# Adapt sudoers
1046$file="/etc/sudoers";
1047open(PBFILE,$file) || die "Unable to open $file";
1048open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1049while (<PBFILE>) {
1050    next if (/^pb   /);
1051    s/Defaults[ \t]+requiretty//;
1052    print PBOUT $_;
1053}
1054close(PBFILE);
1055print PBOUT "pb   ALL=(ALL) NOPASSWD:ALL\n";
1056close(PBOUT);
1057rename("$file.new",$file);
1058chmod 0440,$file;
1059
1060# Suse wants sudoers as 640
1061if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
1062    chmod 0640,$file;
1063}
1064
1065# Sync date
1066system "/usr/sbin/ntpdate ntp.pool.org";
1067
1068system "rm -rf project-builder-* ; wget --passive-ftp ftp://ftp.mondorescue.org/src/project-builder-latest.tar.gz ; tar xvfz project-builder-latest.tar.gz ; cd project-builder-* ; perl Makefile.PL ; make ; make install ; cd ..";
1069EOF
1070close(SCRIPT);
1071}
1072
1073# Returns the pid of a running VM command using a specific VM file
1074sub pb_check_ps {
1075    my $vmcmd = shift;
1076    my $vmm = shift;
1077    my $vmexist = 0;        # FALSE by default
1078
1079    open(PS, "ps auxhww|") || die "Unable to call ps";
1080    while (<PS>) {
1081        next if (! /$vmcmd/);
1082        next if (! /$vmm/);
1083        my ($void1, $void2);
1084        ($void1, $vmexist, $void2) = split(/ +/);
1085        last;
1086    }
1087    return($vmexist);
1088}
1089
1090
1091sub pb_extract_build_files {
1092
1093my $src=shift;
1094my $dir=shift;
1095my $ddir=shift;
1096my @files;
1097
1098if ($src =~ /tar\.gz$/) {
1099    pb_system("tar xfpz $src $dir","Extracting build files");
1100} elsif ($src =~ /tar\.bz2$/) {
1101    pb_system("tar xfpj $src $dir","Extracting build files");
1102} else {
1103    die "Unknown compression algorithm for $src";
1104}
1105opendir(DIR,"$dir") || die "Unable to open directory $dir";
1106foreach my $f (readdir(DIR)) {
1107    next if ($f =~ /^\./);
1108    move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
1109    pb_log(2,"mv $dir/$f $ddir\n");
1110    push @files,"$ddir/$f";
1111}
1112closedir(DIR);
1113# Not enough but still a first cleanup
1114pb_rm_rf("$dir");
1115return(@files);
1116}
1117
1118sub pb_list_bfiles {
1119
1120my $dir = shift;
1121my $pbpkg = shift;
1122my $bfiles = shift;
1123my $pkgfiles = shift;
1124my $supfiles = shift;
1125
1126opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
1127foreach my $f (readdir(BDIR)) {
1128    next if ($f =~ /^\./);
1129    $bfiles->{$f} = "$dir/$f";
1130    $bfiles->{$f} =~ s~$ENV{'PBROOT'}~~;
1131    if (defined $supfiles->{$pbpkg}) {
1132        $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
1133    }
1134}
1135closedir(BDIR);
1136}
1137
1138sub pb_syntax {
1139
1140    print "pb (aka project-builder) Version $projectbuilderver-$projectbuilderrev\n";
1141    print "\n";
1142    print "Syntax: pb [-vhqt][-r pbroot][-p project][[-s script -a account -P port] -m \"mach-1[,...]\"][-i iso] <action> [<pkg1> ...]\n";
1143    print "\n";
1144    print "-h: This help file\n";
1145    print "-q: Quiet mode\n";
1146    print "-t: Test mode (not done yet)\n";
1147    print "-v: Verbose mode\n";
1148    print "\n";
1149    print "-m machine: Name of the Virtual Machines (VM) you want\n";
1150    print "            to build on (coma separated). All if none precised\n";
1151    print "            (or use the env variable PBV)       \n";
1152    print "\n";
1153    print "-s script:  Name of the script you want\n";
1154    print "            to execute on the related VMs.\n";
1155    print "\n";
1156    print "-i iso:     Name of the ISO image of the distribution you want\n";
1157    print "            to install on the related VMs.\n";
1158    print "\n";
1159    print "-a account: Name of the account to use\n";
1160    print "            to connect on the related VMs.\n";
1161    print "\n";
1162    print "-P port:    Port number to use\n";
1163    print "            to connect on the related VMs.\n";
1164    print "\n";
1165    print "-p project: Name of the project you're working on\n";
1166    print "            (or use the env variable PBPROJ)     \n";
1167    print "\n";
1168    print "-r pbroot:  Path Name of project under the CMS \n";
1169    print "            (or use the env variable PBROOT)   \n";
1170    print "\n";
1171    print "-V newver:  New version of the project to create\n";
1172    print "            from the current one.              \n";
1173    print "\n";
1174    print "<action> can be:\n";
1175    print "\n";
1176    print "\tcms2build:    Create tar files for the project under your CMS\n";
1177    print "\t              CMS supported are SVN and CVS\n";
1178    print "\t              parameters are packages to build\n";
1179    print "\t              if not using default list\n";
1180    print "\n";
1181    print "\tbuild2pkg:    Create packages for your running distribution  \n";
1182    print "\n";
1183    print "\tcms2pkg:      cms2build + build2pkg\n";
1184    print "\n";
1185    print "\tbuild2ssh:    Send the tar files to a SSH host               \n";
1186    print "\n";
1187    print "\tcms2ssh:      cms2build + build2ssh\n";
1188    print "\n";
1189    print "\tpkg2ssh:      Send the packages built to a SSH host          \n";
1190    print "\n";
1191    print "\tbuild2vm:     Create packages in VMs, launching them if needed\n";
1192    print "\t              and send those packages to a SSH host once built\n";
1193    print "\t              VM type supported are QEMU            \n";
1194    print "\n";
1195    print "\tbuild2ve:     Create packages in VEs, creating it if needed\n";
1196    print "\t              and send those packages to a SSH host once built\n";
1197    print "\n";
1198    print "\tcms2vm:       cms2build + build2vm\n";
1199    print "\n";
1200    print "\tcms2ve:       cms2build + build2ve\n";
1201    print "\n";
1202    print "\tlaunchvm:     Launch one virtual machine\n";
1203    print "\n";
1204    print "\tlaunchve:     Launch one virtual environment\n";
1205    print "\n";
1206    print "\tscript2vm:    Launch one virtual machine if needed        \n";
1207    print "\t              and executes a script on it                 \n";
1208    print "\n";
1209    print "\tscript2ve:    Execute a script in a virtual environment       \n";
1210    print "\n";
1211    print "\tnewvm:        Create a new virtual machine\n";
1212    print "\n";
1213    print "\tnewve:        Create a new virtual environment\n";
1214    print "\n";
1215    print "\tnewver:       Create a new version of the project derived \n";
1216    print "\t              from the current one                        \n";
1217    print "\n";
1218    print "\tnewproj:      Create a new project and a template set of  \n";
1219    print "\t              configuration files under pbconf            \n";
1220    print "\n";
1221}
Note: See TracBrowser for help on using the repository browser.