source: devel/pb/bin/pb @ 320

Last change on this file since 320 was 320, checked in by Bruno Cornec, 12 years ago
  • Param packager => pbpackager for consistency, and PBPACKAGER is an env var usable
  • Base is now a perl package
  • Multiple fixes all around the place with a correct collectl build from http URL
  • Add build2ve/cms2ve/newve/script2ve and mock support
  • build2vm/launchvm => build2v/launchv and has now a parameter
  • send2ssh => send2target, will be able to evolve later + lots of parameter changes to support VE
  • Add file support
  • Add -f option to force rebuilding the chroot
  • Env var PBVM => PBV
  • Update the concepts doc
  • 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 = "pbdir";
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 = "pbdir";
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.