source: ProjectBuilder/devel/pb/bin/pb@ 163

Last change on this file since 163 was 163, checked in by Bruno Cornec, 17 years ago

Sets date in the VM to avoid build problem with configure
Improve the example script for VM

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