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

Last change on this file since 435 was 435, checked in by Bruno Cornec, 16 years ago
  • Property svn:executable set to *
File size: 55.1 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';
[331]13use Getopt::Long qw(:config auto_abbrev no_ignore_case);
[9]14use Data::Dumper;
15use English;
[16]16use File::Basename;
[26]17use File::Copy;
[395]18use File::stat;
19use File::Temp qw(tempdir);
[13]20use POSIX qw(strftime);
[17]21use lib qw (lib);
[329]22use ProjectBuilder::Version;
[318]23use ProjectBuilder::Base;
[405]24use ProjectBuilder::Conf;
25use ProjectBuilder::Distribution;
26use ProjectBuilder::CMS;
[416]27use ProjectBuilder::Env;
[405]28use ProjectBuilder::Filter;
[5]29
[397]30# Global variables
[5]31my %opts; # CLI Options
[9]32my $action; # action to realize
[320]33my $test = "FALSE"; # Not used
34my $force = 0; # Force VE/VM rebuild
35my $option = ""; # Not used
36my @pkgs; # list of packages
[95]37my $pbtag; # Global Tag variable
38my $pbver; # Global Version variable
[141]39my $pbscript; # Name of the script
[77]40my %pbver; # per package
41my %pbtag; # per package
[53]42my $pbrev; # Global REVISION variable
[152]43my $pbaccount; # Login to use to connect to the VM
[162]44my $pbport; # Port to use to connect to the VM
[199]45my $newver; # New version to create
[331]46my $iso; # ISO image for the VM to create
[5]47
[320]48my @date = pb_get_date();
49my $pbdate = strftime("%Y-%m-%d", @date);
[5]50
[331]51=pod
52
53=head1 NAME
54
55pb, aka project-builder.org - builds packages for your projects
56
57=head1 DESCRIPTION
58
59pb helps you build various packages directly from your project sources.
60Those sources could be handled by a CMS (Configuration Management System)
61such as Subversion, CVS, ... or being a simple reference to a compressed tar file.
62It's based on a set of configuration files, a set of provided macros to help
63you keeping build files as generic as possible. For example, a single .spec
64file should be required to generate for all rpm based distributions, even
65if you could also have multiple .spec files if required.
66
67=head1 SYNOPSIS
68
[332]69pb [-vhq][-r pbroot][-p project][[-s script -a account -P port][-m mach-1[,...]]][-i iso] <action> [<pkg1> ...]
[331]70
[332]71pb [--verbose][--help][--man][--quiet][--revision pbroot][--project project][[--script script --account account --port port][--machine mach-1[,...]]][--iso iso] <action> [<pkg1> ...]
[331]72
73=head1 OPTIONS
74
75=over 4
76
77=item B<-v|--verbose>
78
79Print a brief help message and exits.
80
81=item B<-q|--quiet>
82
83Do not print any output.
84
85=item B<-h|--help>
86
87Print a brief help message and exits.
88
89=item B<--man>
90
91Prints the manual page and exits.
92
93=item B<-m|--machine machine1[,machine2,...]>
94
95Name of the Virtual Machines (VM) or Virtual Environments (VE) you want to build on (coma separated).
96All if none precised (or use the env variable PBV).
97
98=item B<-s|--script script>
99
100Name of the script you want to execute on the related VMs or VEs.
101
102=item B<-i|--iso iso_image>
103
104Name of the ISO image of the distribution you want to install on the related VMs.
105
106=item B<-a|--account account>
107
108Name of the account to use to connect on the related VMs.
109
110=item B<-P|--port port_number>
111
112Port number to use to connect on the related VMs.\n";
113
114=item B<-p|--project project_name>
115
116Name of the project you're working on (or use the env variable PBPROJ)
117
118=item B<-r|--revision revision>
119
120Path Name of the project revision under the CMS (or use the env variable PBROOT)
121
122=item B<-V|--version new_version>
123
124New version of the project to create based on the current one.
125
126=back
127
128=head1 ARGUMENTS
129
130<action> can be:
131
132=over 4
133
134=item B<cms2build>
135
136Create tar files for the project under your CMS.
137CMS supported are SVN and CVS
138parameters are packages to build
139if not using default list
140
141=item B<build2pkg>
142
143Create packages for your running distribution
144
145=item B<cms2pkg>
146
147cms2build + build2pkg
148
149=item B<build2ssh>
150
151Send the tar files to a SSH host
152
153=item B<cms2ssh>
154
155cms2build + build2ssh
156
157=item B<pkg2ssh>
158
159Send the packages built to a SSH host
160
161=item B<build2vm>
162
163Create packages in VMs, launching them if needed
164and send those packages to a SSH host once built
165VM type supported are QEMU
166
167=item B<build2ve>
168
169Create packages in VEs, creating it if needed
170and send those packages to a SSH host once built
171
172=item B<cms2vm>
173
174cms2build + build2vm
175
176=item B<cms2ve>
177
178cms2build + build2ve
179
180=item B<launchvm>
181
182Launch one virtual machine
183
184=item B<launchve>
185
186Launch one virtual environment
187
188=item B<script2vm>
189
190Launch one virtual machine if needed
191and executes a script on it
192
193=item B<script2ve>
194
195Execute a script in a virtual environment
196
197=item B<newvm>
198
199Create a new virtual machine
200
201=item B<newve>
202
203Create a new virtual environment
204
[346]205=item B<setupvm>
206
207Setup a virtual machine for pb usage
208
209=item B<setupve>
210
211Setup a virtual environment for pb usage
212
[331]213=item B<newver>
214
215Create a new version of the project derived
216from the current one
217
218=item B<newproj>
219
220Create a new project and a template set of
221configuration files under pbconf
222
223=back
224
225<pkgs> can be a list of packages, the keyword 'all' or nothing, in which case the default list of packages is taken (corresponding to the defpkgdir list of arguments in the configuration file).
226
227=head1 WEB SITES
228
229The main Web site of the project is available at L<http://www.project-builder.org/>. Bug reports should be filled using the trac instance of the project at L<http://trac.project-builder.org/>.
230
231=head1 USER MAILING LIST
232
233None exists for the moment.
234
235=head1 CONFIGURATION FILES
236
237Each pb user may have a configuration in F<$HOME/.pbrc>. The values in this file may overwrite any other configuration file value.
238
239Here is an example of such a configuration file:
240
241 #
242 # Define for each project the URL of its pbconf repository
243 # No default option allowed here as they need to be all different
244 #
245 # URL of the pbconf content
246 # This is the format of a classical URL with the extension of additional schema such as
247 # svn+ssh, cvs+ssh, ...
248 #
249 pbconfurl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe/pbconf
250
251 # This is normaly defined in the project's configuration file
252 # Url of the project
253 #
254 pburl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe
255
256 # All these URLs needs to be defined here as the are the entry point
257 # for how to build packages for the project
258 #
259 pbconfurl pb = svn+ssh://svn.project-builder.org/mondo/svn/pb/pbconf
260 pbconfurl mondorescue = svn+ssh://svn.project-builder.org/mondo/svn/project-builder/mondorescue/pbconf
261 pbconfurl collectl = svn+ssh://bruno@svn.mondorescue.org/mondo/svn/project-builder/collectl/pbconf
262 pbconfurl netperf = svn+ssh://svn.mondorescue.org/mondo/svn/project-builder/netperf/pbconf
263
264 # Under that dir will take place everything related to pb
265 # If you want to use VMs/chroot/..., then use $ENV{'HOME'} to make it portable
266 # to your VMs/chroot/...
267 # if not defined then /var/cache
268 pbdefdir default = $ENV{'HOME'}/project-builder
269 pbdefdir pb = $ENV{'HOME'}
270 pbdefdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
271 pbdefdir mondorescue = $ENV{'HOME'}/mondo/svn
272
273 # pbconfdir points to the directory where the CMS content of the pbconfurl is checked out
274 # If not defined, pbconfdir is under pbdefdir/pbproj/pbconf
275 pbconfdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs/pbconf
276 pbconfdir mondorescue = $ENV{'HOME'}/mondo/svn/pbconf
277
278 # pbdir points to the directory where the CMS content of the pburl is checked out
279 # If not defined, pbdir is under pbdefdir/pbproj
280 # Only defined if we have access to the dev of the project
281 pbdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
282 pbdir mondorescue = $ENV{'HOME'}/mondo/svn
283
284 # -daemonize doesn't work with qemu 0.8.2
285 vmopt default = -m 384
286
287=head1 AUTHORS
288
289The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
290
291=head1 COPYRIGHT
292
293Project-Builder.org is distributed under the GPL v2.0 license
294described in the file C<COPYING> included with the distribution.
295
296=cut
297
298# ---------------------------------------------------------------------------
299
300# Old syntax
301#getopts('a:fhi:l:m:P:p:qr:s:vV:',\%opts);
302
[75]303my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
[331]304
[397]305# Initialize the syntax string
306
307pb_syntax_init("pb (aka project-builder.org) Version $projectbuilderver-$projectbuilderrev\n");
308
[331]309GetOptions("help|?|h" => \$opts{'h'},
310 "man" => \$opts{'man'},
311 "verbose|v+" => \$opts{'v'},
312 "quiet|q" => \$opts{'q'},
313 "log-files|l=s" => \$opts{'l'},
314 "force|f" => \$opts{'f'},
315 "account|a=s" => \$opts{'a'},
316 "revision|r=s" => \$opts{'r'},
317 "script|s=s" => \$opts{'s'},
318 "machines|mock|m=s" => \$opts{'m'},
319 "port|P=i" => \$opts{'P'},
320 "project|p=s" => \$opts{'p'},
321 "iso|i=s" => \$opts{'i'},
322 "version|V=s" => \$opts{'V'},
323) || pb_syntax(-1,0);
324
[21]325if (defined $opts{'h'}) {
[331]326 pb_syntax(0,1);
[21]327}
[331]328if (defined $opts{'man'}) {
329 pb_syntax(0,2);
330}
[21]331if (defined $opts{'v'}) {
[331]332 $debug = $opts{'v'};
[21]333}
[320]334if (defined $opts{'f'}) {
335 $force=1;
336}
[21]337if (defined $opts{'q'}) {
338 $debug=-1;
339}
[22]340if (defined $opts{'l'}) {
341 open(LOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
[348]342 $LOG = \*LOG;
[22]343 $debug = 0 if ($debug == -1);
344 }
[315]345pb_log_init($debug, $LOG);
346
[67]347# Handle root of the project if defined
348if (defined $opts{'r'}) {
[340]349 $ENV{'PBROOTDIR'} = $opts{'r'};
[67]350}
[91]351# Handle virtual machines if any
352if (defined $opts{'m'}) {
[320]353 $ENV{'PBV'} = $opts{'m'};
[91]354}
[141]355if (defined $opts{'s'}) {
356 $pbscript = $opts{'s'};
357}
[152]358if (defined $opts{'a'}) {
359 $pbaccount = $opts{'a'};
[347]360 die "option -a requires a -s script option" if (not defined $pbscript);
[152]361}
[162]362if (defined $opts{'P'}) {
363 $pbport = $opts{'P'};
364}
[199]365if (defined $opts{'V'}) {
366 $newver = $opts{'V'};
367}
[262]368if (defined $opts{'i'}) {
369 $iso = $opts{'i'};
370}
[108]371
372# Get Action
373$action = shift @ARGV;
[331]374die pb_syntax(-1,1) if (not defined $action);
[108]375
[314]376my ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir);
[273]377my $pbinit = undef;
378$pbinit = 1 if ($action =~ /^newproj$/);
[108]379
[59]380# Handles project name if any
[108]381# And get global params
[353]382($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) = pb_env_init($opts{'p'},$pbinit,$action);
[59]383
[315]384pb_log(0,"Project: $ENV{'PBPROJ'}\n");
385pb_log(0,"Action: $action\n");
[9]386
387# Act depending on action
388if ($action =~ /^cms2build$/) {
[77]389 pb_cms2build();
390} elsif ($action =~ /^build2pkg$/) {
391 pb_build2pkg();
392} elsif ($action =~ /^cms2pkg$/) {
393 pb_cms2build();
394 pb_build2pkg();
[88]395} elsif ($action =~ /^build2ssh$/) {
396 pb_build2ssh();
[220]397} elsif ($action =~ /^cms2ssh$/) {
398 pb_cms2build();
399 pb_build2ssh();
[88]400} elsif ($action =~ /^pkg2ssh$/) {
401 pb_pkg2ssh();
[320]402} elsif ($action =~ /^build2ve$/) {
403 pb_build2v("ve");
[91]404} elsif ($action =~ /^build2vm$/) {
[320]405 pb_build2v("vm");
406} elsif ($action =~ /^cms2ve$/) {
407 pb_cms2build();
408 pb_build2v("ve");
[91]409} elsif ($action =~ /^cms2vm$/) {
410 pb_cms2build();
[320]411 pb_build2v("vm");
[141]412} elsif ($action =~ /^launchvm$/) {
[320]413 pb_launchv("vm",$ENV{'PBV'},0);
414} elsif ($action =~ /^launchve$/) {
415 pb_launchv("ve",$ENV{'PBV'},0);
[142]416} elsif ($action =~ /^script2vm$/) {
[320]417 pb_script2v($pbscript,"vm");
418} elsif ($action =~ /^script2ve$/) {
419 pb_script2v($pbscript,"ve");
[199]420} elsif ($action =~ /^newver$/) {
421 pb_newver();
[320]422} elsif ($action =~ /^newve$/) {
423 pb_launchv("ve",$ENV{'PBV'},1);
[262]424} elsif ($action =~ /^newvm$/) {
[320]425 pb_launchv("vm",$ENV{'PBV'},1);
[346]426} elsif ($action =~ /^setupve$/) {
[353]427 pb_setup_v("ve");
[346]428} elsif ($action =~ /^setupvm$/) {
[353]429 pb_setup_v("vm");
[273]430} elsif ($action =~ /^newproj$/) {
431 # Nothing to do - already done in pb_env_init
[106]432} elsif ($action =~ /^clean$/) {
[77]433} else {
[315]434 pb_log(0,"\'$action\' is not available\n");
[331]435 pb_syntax(-2,1);
[77]436}
437
438sub pb_cms2build {
439
[357]440 my $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
441 my @pkgs = @$pkg;
442 my %pkgs;
[9]443
[341]444 my ($scheme, $uri) = pb_cms_init($pbinit);
[331]445
[313]446 my ($pkgv, $pkgt) = pb_conf_get_if("pkgver","pkgtag");
[174]447
[429]448 # declare packager and repo for filtering
449 my ($tmp1, $tmp2) = pb_conf_get("pbpackager","pbrepo");
450 $ENV{'PBPACKAGER'} = $tmp1->{$ENV{'PBPROJ'}};
451 $ENV{'PBREPO'} = $tmp2->{$ENV{'PBPROJ'}};
[174]452
[27]453 foreach my $pbpkg (@pkgs) {
[115]454 $ENV{'PBPKG'} = $pbpkg;
[98]455 if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
456 $pbver = $pkgv->{$pbpkg};
[9]457 } else {
[353]458 $pbver = $ENV{'PBPROJVER'};
[9]459 }
[98]460 if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
461 $pbtag = $pkgt->{$pbpkg};
[9]462 } else {
[353]463 $pbtag = $ENV{'PBPROJTAG'};
[9]464 }
[95]465
[16]466 $pbrev = $ENV{'PBREVISION'};
[319]467 pb_log(0,"\n");
468 pb_log(0,"Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n");
[9]469 die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
[16]470 # Clean up dest if necessary. The export will recreate it
[27]471 my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver";
[74]472 pb_rm_rf($dest) if (-d $dest);
[9]473
474 # Export CMS tree for the concerned package to dest
475 # And generate some additional files
476 $OUTPUT_AUTOFLUSH=1;
[29]477
[9]478 # computes in which dir we have to work
[113]479 my $dir = $defpkgdir->{$pbpkg};
480 $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
[315]481 pb_log(2,"def:".Dumper($defpkgdir)." ext: ".Dumper($extpkgdir)." \n");
[9]482
[340]483 # Exporting from CMS
484 pb_cms_export($uri,"$ENV{'PBDIR'}/$dir",$dest);
[315]485
[435]486 # Generated fake content for test versions to speed up stuff
487 my ($testver) = pb_conf_get_if("testver");
488 my $chglog;
[285]489
[435]490 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
491 if (! -f "$dest/NEWS") {
492 open(NEWS,"> $dest/NEWS") || die "Unable to create $dest/NEWS";
493 close(NEWS);
494 }
495 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
496 close(CL);
497 open(CL,"> $dest/$ENV{'PBCMSLOGFILE'}") || die "Unable to create $dest/$ENV{'PBCMSLOGFILE'}";
498 close(CL);
499 $chglog = undef;
500 } else {
[285]501
[435]502 # Get project info on authors and log file
503 $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
504 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
505 $chglog = undef if (! -f $chglog);
506
507 my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
508 $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
509 $authors = "/dev/null" if (! -f $authors);
510
511 # Extract cms log history and store it
512 if ((defined $chglog) && (! -f "$dest/NEWS")) {
513 pb_log(2,"Generating NEWS file from $chglog\n");
514 copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
515 }
516 pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors);
[285]517 }
[29]518
[21]519 my %build;
[435]520 my @pt;
521 my $tmpl = "";
[91]522
[328]523 @pt = pb_conf_get_if("vmlist","velist");
[340]524 if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
525 $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
526 }
527 if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
528 # the 2 lists needs to be grouped with a ',' separated them
529 if ($tmpl ne "") {
530 $tmpl .= ",";
531 }
532 $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
533 }
534 foreach my $d (split(/,/,$tmpl)) {
[315]535 my ($name,$ver,$arch) = split(/-/,$d);
536 chomp($arch);
[99]537 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
[315]538 pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n");
539 pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
[13]540
[16]541 # Filter build files from the less precise up to the most with overloading
[13]542 # Filter all files found, keeping the name, and generating in dest
[16]543
[340]544 # Find all build files first relatively to PBROOTDIR
[300]545 # Find also all specific files referenced in the .pb conf file
[320]546 my %bfiles = ();
547 my %pkgfiles = ();
[21]548 $build{"$ddir-$dver"} = "yes";
[315]549
[340]550 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dtype") {
551 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dtype",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
552 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dfam") {
553 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
554 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir") {
555 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
556 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver") {
557 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
[13]558 } else {
[21]559 $build{"$ddir-$dver"} = "no";
[13]560 next;
561 }
[315]562 pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
[13]563
[15]564 # Get all filters to apply
[77]565 my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
[15]566
[19]567 # Apply now all the filters on all the files concerned
568 # destination dir depends on the type of file
569 if (defined $ptr) {
[300]570 foreach my $f (values %bfiles,values %pkgfiles) {
[429]571 pb_filter_file_pb("$ENV{'PBROOTDIR'}/$f",$ptr,"$dest/pbconf/$ddir-$dver/".basename($f),$dtype,$pbsuf,$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$defpkgdir,$extpkgdir,$ENV{'PBPACKAGER'},$chglog,$ENV{'PBPROJ'},$ENV{'PBREPO'});
[16]572 }
[15]573 }
[18]574 }
[315]575 my @found;
576 my @notfound;
577 foreach my $b (keys %build) {
578 push @found,$b if ($build{$b} =~ /yes/);
579 push @notfound,$b if ($build{$b} =~ /no/);
[21]580 }
[315]581 pb_log(0,"Build files generated for ".join(',',@found)."\n");
582 pb_log(0,"No Build files found for ".join(',',@notfound)."\n") if (@notfound);
[236]583 # Get the generic filter (all.pbf) and
584 # apply those to the non-build files including those
585 # generated by pbinit if applicable
586
587 # Get only all.pbf filter
[357]588 my $ptr = pb_get_filters($pbpkg);
[236]589
590 my $liste ="";
591 if (defined $filteredfiles->{$pbpkg}) {
592 foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
[429]593 pb_filter_file_inplace($ptr,"$dest/$f",$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'},$ENV{'PBPROJ'},$ENV{'PBREPO'});
[238]594 $liste = "$f $liste";
[236]595 }
596 }
[315]597 pb_log(2,"Files ".$liste."have been filtered\n");
[236]598
[265]599 # Prepare the dest directory for archive
[340]600 if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
[429]601 pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'},$ENV{'PBPROJ'},$ENV{'PBREPO'});
[266]602 chmod 0755,"$ENV{'PBTMP'}/pbinit";
[340]603 pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit");
[265]604 }
605
[18]606 # Archive dest dir
[69]607 chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
[25]608 # Possibility to look at PBSRC to guess more the filename
[94]609 pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
[344]610 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
[83]611
[357]612 # Keep track of version-tag per pkg
613 $pkgs{$pbpkg} = "$pbver-$pbtag";
[83]614
[288]615 # Final cleanup
616 pb_rm_rf($dest) if (-d $dest);
[9]617 }
[357]618
619 # Keep track of per package version
620 pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
621 open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
622 foreach my $pbpkg (@pkgs) {
623 print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
624 }
625 close(PKG);
626
627 # Keep track of what is generated by default
628 # We need to store the dir and info on version-tag
629 # Base our content on the existing .pb file
630 copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
631 open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
632 print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
633 print LAST "pbprojver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
634 print LAST "pbprojtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
635 print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
636 close(LAST);
[77]637}
[22]638
[77]639sub pb_build2pkg {
640
[22]641 # Get the running distro to build on
[99]642 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
[315]643 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
[22]644
[353]645 # Get list of packages to build
[83]646 # Get content saved in cms2build
[353]647 my $ptr = pb_get_pkg();
648 @pkgs = @$ptr;
649
650 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
[83]651 $pkg = { } if (not defined $pkg);
652
[25]653 chdir "$ENV{'PBBUILDDIR'}";
[126]654 my $made = ""; # pkgs made during build
[27]655 foreach my $pbpkg (@pkgs) {
[88]656 my $vertag = $pkg->{$pbpkg};
[77]657 # get the version of the current package - maybe different
658 ($pbver,$pbtag) = split(/-/,$vertag);
659
[27]660 my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
[315]661 pb_log(2,"Source file: $src\n");
[25]662
[315]663 pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
[25]664 if ($dtype eq "rpm") {
665 foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
[28]666 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
[96]667 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]668 }
[25]669 }
670
[315]671 # Remove in case a previous link/file was there
[301]672 unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
[188]673 symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
[25]674 # We need to first extract the spec file
[28]675 my @specfile;
[77]676 @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
[25]677
[315]678 pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
[25]679 # set LANGUAGE to check for correct log messages
680 $ENV{'LANGUAGE'}="C";
[28]681 foreach my $f (@specfile) {
682 if ($f =~ /\.spec$/) {
[353]683 pb_system("rpmbuild --define \'packager $ENV{'PBPACKAGER'}\' --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
[28]684 last;
685 }
686 }
[136]687 $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
[149]688 if (-f "/usr/bin/rpmlint") {
689 pb_system("rpmlint $made","Checking validity of rpms with rpmlint");
[150]690 }
[118]691 } elsif ($dtype eq "deb") {
[149]692 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
[274]693 pb_system("tar xfz $src","Extracting sources");
[149]694
695 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
[310]696 pb_rm_rf("debian");
[149]697 symlink "pbconf/$ddir-$dver","debian" || die "Unable to symlink to pbconf/$ddir-$dver";
[199]698 chmod 0755,"debian/rules";
[149]699 pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package");
[136]700 $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
[315]701 if (-f "/usr/bin/lintian") {
702 pb_system("lintian $made","Checking validity of debs with lintian");
703 }
[87]704 } elsif ($dtype eq "ebuild") {
[149]705 my @ebuildfile;
706 # For gentoo we need to take pb as subsystem name
[295]707 # We put every apps here under sys-apps. hope it's correct
[435]708 # We use pb's home dir in order to have a single OVERLAY line
[295]709 my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
710 pb_mkdir_p($tmpd) if (! -d "$tmpd");
711 pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
[149]712
[295]713 # We need to first extract the ebuild file
714 @ebuildfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$tmpd");
[149]715
716 # Prepare the build env for gentoo
717 my $found = 0;
[295]718 my $pbbd = $ENV{'HOME'};
[150]719 $pbbd =~ s|/|\\/|g;
[295]720 if (-r "/etc/make.conf") {
721 open(MAKE,"/etc/make.conf");
722 while (<MAKE>) {
723 $found = 1 if (/$pbbd\/portage/);
724 }
725 close(MAKE);
[149]726 }
727 if ($found == 0) {
[295]728 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
[149]729 }
[295]730 #$found = 0;
731 #if (-r "/etc/portage/package.keywords") {
732 #open(KEYW,"/etc/portage/package.keywords");
733 #while (<KEYW>) {
734 #$found = 1 if (/portage\/pb/);
735 #}
736 #close(KEYW);
737 #}
738 #if ($found == 0) {
739 #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
740 #}
[149]741
742 # Build
743 foreach my $f (@ebuildfile) {
744 if ($f =~ /\.ebuild$/) {
[295]745 move($f,"$tmpd/$pbpkg-$pbver.ebuild");
746 pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package");
747 # Now move it where pb expects it
748 pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
749 move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
[149]750 }
751 }
752
[295]753 $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver.ebuild";
[118]754 } elsif ($dtype eq "slackware") {
[435]755 $made="$made $pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
756
757 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
758 pb_system("tar xfz $src","Extracting sources");
759 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
760 symlink "pbconf/$ddir-$dver","install" || die "Unable to symlink to pbconf/$ddir-$dver";
761 if (-x "install/pbslack") {
762 pb_system("./install/pbslack","Building package");
763 pb_system("sudo /sbin/makepkg -p -l y -c y $pbpkg","Packaging $pbpkg");
764 }
[87]765 } else {
[118]766 die "Unknown dtype format $dtype";
[87]767 }
768 }
[118]769 # Keep track of what is generated so that we can get them back from VMs
[353]770 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
[118]771 print KEEP "$made\n";
772 close(KEEP);
[87]773}
774
[88]775sub pb_build2ssh {
[320]776 pb_send2target("Sources");
[90]777}
[87]778
[90]779sub pb_pkg2ssh {
[320]780 pb_send2target("Packages");
[90]781}
782
[108]783# By default deliver to the the public site hosting the
[320]784# ftp structure (or whatever) or a VM/VE
785sub pb_send2target {
[90]786
787 my $cmt = shift;
[320]788 my $v = shift || undef;
[142]789 my $vmexist = shift || 0; # 0 is FALSE
[200]790 my $vmpid = shift || 0; # 0 is FALSE
[320]791
792 my $host = "sshhost";
793 my $login = "sshlogin";
794 my $dir = "sshdir";
795 my $port = "sshport";
796 my $conf = "sshconf";
797 my $rebuild = "sshrebuild";
[415]798 my $tmout = "vmtmout";
799 my $path = "vmpath";
[348]800 if (($cmt eq "vm") || ($cmt eq "Script")) {
[320]801 $login = "vmlogin";
[322]802 $dir = "pbdefdir";
[320]803 $tmout = "vmtmout";
804 $rebuild = "vmrebuild";
805 # Specific VM
806 $host = "vmhost";
807 $port = "vmport";
808 } elsif ($cmt eq "ve") {
809 $login = "velogin";
[322]810 $dir = "pbdefdir";
[320]811 $tmout = "vetmout";
812 # Specific VE
813 $path = "vepath";
814 $conf = "veconf";
815 $rebuild = "verebuild";
816 }
[158]817 my $cmd = "";
[90]818
[353]819 my $ptr = pb_get_pkg();
[87]820 @pkgs = @$ptr;
821
[136]822 # Get the running distro to consider
[347]823 my ($odir,$over,$oarch) = (undef, undef, undef);
[320]824 if (defined $v) {
825 ($odir,$over,$oarch) = split(/-/,$v);
[118]826 }
827 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
[315]828 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
[87]829
[353]830 # Get list of packages to build
[87]831 # Get content saved in cms2build
[353]832 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
[87]833 $pkg = { } if (not defined $pkg);
834
[118]835 my $src = "";
[87]836 chdir "$ENV{'PBBUILDDIR'}";
837 foreach my $pbpkg (@pkgs) {
[88]838 my $vertag = $pkg->{$pbpkg};
[87]839 # get the version of the current package - maybe different
840 ($pbver,$pbtag) = split(/-/,$vertag);
841
[320]842 if (($cmt eq "Sources") || ($cmt eq "vm") || ($cmt eq "ve")) {
[158]843 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
[166]844 if ($cmd eq "") {
845 $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
846 } else {
847 $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
848 }
[118]849 }
850 }
[429]851 # Adds conf file for availability of conf elements
[417]852 pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
853
[320]854 if (($cmt eq "vm") || ($cmt eq "ve")) {
[429]855 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc";
[142]856 } elsif ($cmt eq "Script") {
[429]857 # Nothing special to do
[118]858 } elsif ($cmt eq "Packages") {
859 # Get package list from file made during build2pkg
[353]860 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
[126]861 $src = <KEEP>;
[118]862 chomp($src);
863 close(KEEP);
[429]864
[87]865 }
[429]866 # Systematically adds the pbscript
867 $src="$src $ENV{'PBDESTDIR'}/pbscript";
[320]868 # Remove potential leading spaces (cause problem with basename)
[132]869 $src =~ s/^ *//;
[129]870 my $basesrc = "";
[131]871 foreach my $i (split(/ +/,$src)) {
872 $basesrc .= " ".basename($i);
[130]873 }
[118]874
[320]875 pb_log(0,"Sources handled ($cmt): $src\n");
[355]876 pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf))."\n");
[415]877 my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vepath) = pb_conf_get($host,$login,$dir,$port,$tmout,$path);
878 my ($vrebuild,$veconf) = pb_conf_get_if($rebuild,$conf);
[320]879 pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
880 # Not mandatory
881 my ($testver) = pb_conf_get_if("testver");
882
883 my $mac;
884 # Useless for VE
885 if ($cmt ne "ve") {
886 $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
887 # Overwrite account value if passed as parameter
888 $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
[355]889 pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
[320]890 }
891
[108]892 my $tdir;
[136]893 my $bdir;
[142]894 if (($cmt eq "Sources") || ($cmt eq "Script")) {
[108]895 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
[435]896 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
897 # This is a test pkg => target dir is under test
898 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/test/src";
899 }
[320]900 } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
901 $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
902 $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
[136]903 # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
904 $bdir =~ s|\$ENV.+\}/||;
[90]905 } elsif ($cmt eq "Packages") {
[108]906 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
[429]907
[337]908 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
[289]909 # This is a test pkg => target dir is under test
[428]910 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/test/$ddir/$dver";
[291]911 }
[429]912
913 my $repodir = $tdir;
914 $repodir =~ s|^$sshdir->{$ENV{'PBPROJ'}}/||;
915
916 my ($pbrepo) = pb_conf_get("pbrepo");
917
918 # Repository management
919 open(PBS,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
920 if ($dtype eq "rpm") {
921 # Also make a pbscript to generate yum/urpmi bases
922 print PBS << "EOF";
[433]923#!/bin/bash
[429]924# Prepare a script to ease yum setup
925cat > $ENV{'PBPROJ'}.repo << EOT
926[$ENV{'PBPROJ'}]
927name=$ddir $dver - $ENV{'PBPROJ'} Vanilla Packages
[433]928baseurl=$pbrepo->{$ENV{'PBPROJ'}}/$repodir
[429]929enabled=1
930gpgcheck=0
931EOT
932chmod 644 $ENV{'PBPROJ'}.repo
933
934# Clean up old repo content
935rm -rf headers/ repodata/
936# Create yum repo
937yum-arch .
938# Create repodata
939createrepo .
940EOF
941 if ($dfam eq "md") {
942 # For Mandriva add urpmi management
943 print PBS << "EOF";
944# Prepare a script to ease urpmi setup
945cat > $ENV{'PBPROJ'}.addmedia << EOT
[433]946urpmi.addmedia $ENV{'PBPROJ'} $pbrepo->{$ENV{'PBPROJ'}}/$repodir with hdlist.cz
[429]947EOT
948chmod 755 $ENV{'PBPROJ'}.addmedia
949
950# Clean up old repo content
951rm -f hdlist.cz
952# Create urpmi repo
953genhdlist .
954EOF
955 }
956 } elsif ($dtype eq "deb") {
957 # Also make a pbscript to generate apt bases
958 }
959 close(PBS);
960
[90]961 } else {
962 return;
[22]963 }
[239]964
[320]965 # Useless for VE
966 my $nport;
967 if ($cmt ne "ve") {
968 $nport = $sshport->{$ENV{'PBPROJ'}};
969 $nport = "$pbport" if (defined $pbport);
970 }
971
[136]972 # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
[132]973 $tdir =~ s|\$ENV.+\}/||;
974
[320]975 my $tm = $vtmout->{$ENV{'PBPROJ'}};
976
977 # ssh communication if not VE
[349]978 # should use a hash instead...
[320]979 my ($shcmd,$cpcmd,$cptarget,$cp2target);
980 if ($cmt ne "ve") {
[347]981 my $keyfile = pb_ssh_get(0);
[435]982 $shcmd = "ssh -i $keyfile -q -o UserKnownHostsFile=/dev/null -p $nport $mac";
983 $cpcmd = "scp -i $keyfile -p -o UserKnownHostsFile=/dev/null -P $nport";
[320]984 $cptarget = "$mac:$tdir";
[351]985 if ($cmt eq "vm") {
986 $cp2target = "$mac:$bdir";
987 }
[320]988 } else {
989 my $tp = $vepath->{$ENV{'PBPROJ'}};
990 $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
991 $cpcmd = "cp -a ";
992 $cptarget = "$tp/$tdir";
993 $cp2target = "$tp/$bdir";
994 }
995
996 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");
997 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
998 # For VE we need to change the owner manually - To be tested if needed
999 #if ($cmt eq "ve") {
1000 #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
1001 #}
[434]1002 pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi ; rm -f ./pbscript\' | bash\"","Executing pbscript on $cptarget if needed");
[320]1003 if (($cmt eq "vm") || ($cmt eq "ve")) {
[128]1004 # Get back info on pkg produced, compute their name and get them from the VM
[353]1005 pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
1006 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
[118]1007 my $src = <KEEP>;
1008 chomp($src);
1009 close(KEEP);
[131]1010 $src =~ s/^ *//;
[136]1011 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
[320]1012 # Change pgben to make the next send2target happy
[143]1013 my $made = "";
[353]1014 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
[136]1015 foreach my $p (split(/ +/,$src)) {
[139]1016 my $j = basename($p);
[320]1017 pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
[144]1018 $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
[136]1019 }
[143]1020 print KEEP "$made\n";
[139]1021 close(KEEP);
[320]1022 pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
[355]1023
1024 # We want to send them to the ssh account so overwrite what has been done before
1025 undef $pbaccount;
[357]1026 pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
[355]1027 pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
[320]1028 if ((! $vmexist) && ($cmt eq "vm")) {
1029 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)");
[142]1030 }
[141]1031 pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
[108]1032 }
[9]1033}
[16]1034
[320]1035sub pb_script2v {
[142]1036 my $pbscript=shift;
[320]1037 my $vtype=shift;
[141]1038
1039 # Prepare the script to be executed on the VM
1040 # in $ENV{'PBDESTDIR'}/pbscript
[142]1041 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
1042 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1043 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1044 }
[141]1045
[320]1046 my ($vm,$all) = pb_get_v($vtype);
1047 my ($vmexist,$vmpid) = (undef,undef);
[142]1048
[141]1049 foreach my $v (@$vm) {
[320]1050 # Launch the VM/VE
1051 if ($vtype eq "vm") {
1052 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
[141]1053
[320]1054 # Skip that VM if something went wrong
1055 next if (($vmpid == 0) && ($vmexist ==0));
1056 }
[274]1057
[142]1058 # Gather all required files to send them to the VM
[320]1059 # and launch the build through pbscript
1060 pb_send2target("Script","$v",$vmexist,$vmpid);
[169]1061
[142]1062 }
1063}
1064
[320]1065sub pb_launchv {
1066 my $vtype = shift;
1067 my $v = shift;
1068 my $create = shift || 0; # By default do not create a VM
[310]1069
[320]1070 die "No VM/VE defined, unable to launch" if (not defined $v);
1071 # Keep only the first VM in case many were given
1072 $v =~ s/,.*//;
[310]1073
[320]1074 # Which is our local arch ? (standardize on i386 for those platforms)
1075 my $arch = `uname -m`;
1076 chomp($arch);
1077 $arch =~ s/i.86/i386/;
[310]1078
[320]1079 # Launch the VMs/VEs
1080 if ($vtype eq "vm") {
1081 die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
[310]1082
[415]1083 my ($ptr,$vmopt,$vmpath,$vmport,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmpath","vmport","vmtmout","vmsize");
[320]1084
1085 my $vmtype = $ptr->{$ENV{'PBPROJ'}};
1086 if (not defined $ENV{'PBVMOPT'}) {
1087 $ENV{'PBVMOPT'} = "";
[310]1088 }
[320]1089 if (defined $vmopt->{$ENV{'PBPROJ'}}) {
1090 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
1091 }
1092 my $nport = $vmport->{$ENV{'PBPROJ'}};
1093 $nport = "$pbport" if (defined $pbport);
1094
1095 my $cmd;
1096 my $vmcmd; # has to be used for pb_check_ps
1097 my $vmm; # has to be used for pb_check_ps
1098 if ($vmtype eq "qemu") {
1099 my $qemucmd32;
1100 my $qemucmd64;
1101 if ($arch eq "x86_64") {
1102 $qemucmd32 = "/usr/bin/qemu-system-i386";
1103 $qemucmd64 = "/usr/bin/qemu";
1104 } else {
1105 $qemucmd32 = "/usr/bin/qemu";
1106 $qemucmd64 = "/usr/bin/qemu-system-x86_64";
1107 }
1108 if ($v =~ /x86_64/) {
1109 $vmcmd = "$qemucmd64 -no-kqemu";
1110 } else {
1111 $vmcmd = "$qemucmd32";
1112 }
1113 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
1114 if ($create != 0) {
1115 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
1116 }
1117 $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
1118 } elsif ($vmtype eq "xen") {
1119 } elsif ($vmtype eq "vmware") {
[310]1120 } else {
[320]1121 die "VM of type $vmtype not supported. Report to the dev team";
[310]1122 }
[320]1123 my ($tmpcmd,$void) = split(/ +/,$cmd);
1124 my $vmexist = pb_check_ps($tmpcmd,$vmm);
1125 my $vmpid = 0;
1126 if (! $vmexist) {
1127 if ($create != 0) {
1128 if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
1129 pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
1130 } elsif ($vmtype eq "vmware") {
1131 } else {
1132 }
1133 }
1134 if (! -f "$vmm") {
1135 pb_log(0,"Unable to find VM $vmm\n");
1136 } else {
1137 pb_system("$cmd &","Launching the VM $vmm");
1138 pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
1139 $vmpid = pb_check_ps($tmpcmd,$vmm);
[357]1140 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
[320]1141 }
[310]1142 } else {
[320]1143 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
[310]1144 }
[320]1145 return($vmexist,$vmpid);
1146 # VE here
[310]1147 } else {
[320]1148 # Get VE context
[415]1149 my ($ptr,$vetmout,$vepath,$verebuild,$veconf) = pb_conf_get("vetype","vetmout","vepath","verebuild","veconf");
[320]1150 my $vetype = $ptr->{$ENV{'PBPROJ'}};
[310]1151
[320]1152 # Get distro context
1153 my ($name,$ver,$darch) = split(/-/,$v);
1154 chomp($darch);
1155 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
[142]1156
[320]1157 if ($vetype eq "chroot") {
1158 # Architecture consistency
1159 if ($arch ne $darch) {
1160 die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
1161 }
[142]1162
[320]1163 if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
1164 # We have to rebuild the chroot
1165 if ($dtype eq "rpm") {
1166 pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1167 # Once setup we need to install some packages, the pb account, ...
1168 pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
1169 #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1170 } elsif ($dtype eq "deb") {
1171 pb_system("","Creating the pbuilder VE");
1172 } elsif ($dtype eq "ebuild") {
1173 die "Please teach the dev team how to build gentoo chroot";
1174 } else {
1175 die "Unknown distribution type $dtype. Report to dev team";
1176 }
[310]1177 }
[320]1178 # Nothing more to do for VE. No real launch
[274]1179 } else {
[320]1180 die "VE of type $vetype not supported. Report to the dev team";
[262]1181 }
[141]1182 }
1183}
[142]1184
[320]1185sub pb_build2v {
[118]1186
[320]1187my $vtype = shift;
[142]1188
[320]1189# Prepare the script to be executed on the VM/VE
1190# in $ENV{'PBDESTDIR'}/pbscript
[353]1191#my ($ntp) = pb_conf_get($vtype."ntp");
1192#my $vntp = $ntp->{$ENV{'PBPROJ'}};
[118]1193
[320]1194open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1195print SCRIPT "#!/bin/bash\n";
1196print SCRIPT "echo ... Execution needed\n";
1197print SCRIPT "# This is in directory delivery\n";
1198print SCRIPT "# Setup the variables required for building\n";
1199print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
1200print SCRIPT "# Preparation for pb\n";
1201print SCRIPT "mv .pbrc \$HOME\n";
1202print SCRIPT "cd ..\n";
1203# Force new date to be in the future compared to the date of the tar file by adding 1 minute
1204my @date=pb_get_date();
1205$date[1]++;
1206my $upddate = strftime("%m%d%H%M%Y", @date);
[353]1207#print SCRIPT "echo Setting up date on $vntp...\n";
[320]1208# Or use ntpdate if available TBC
1209print SCRIPT "sudo date $upddate\n";
[353]1210# Get list of packages to build and get some ENV vars as well
1211my $ptr = pb_get_pkg();
1212@pkgs = @$ptr;
1213my $p = join(' ',@pkgs) if (@pkgs);
1214print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
1215print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
[320]1216print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
1217print SCRIPT "# Build\n";
1218print SCRIPT "echo Building packages on $vtype...\n";
1219print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
1220close(SCRIPT);
1221chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1222
1223my ($v,$all) = pb_get_v($vtype);
1224
1225# Send tar files when we do a global generation
1226pb_build2ssh() if ($all == 1);
1227
1228my ($vmexist,$vmpid) = (undef,undef);
1229
1230foreach my $v (@$v) {
1231 if ($vtype eq "vm") {
[142]1232 # Launch the VM
[357]1233 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
[118]1234
[274]1235 # Skip that VM if it something went wrong
1236 next if (($vmpid == 0) && ($vmexist == 0));
[118]1237 }
[320]1238 # Gather all required files to send them to the VM/VE
[347]1239 # and launch the build through pbscript
[357]1240 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
[320]1241 pb_send2target($vtype,"$v",$vmexist,$vmpid);
[105]1242}
[320]1243}
[105]1244
[262]1245
[199]1246sub pb_newver {
1247
[204]1248 die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
[340]1249
[366]1250 # Need this call for PBDIR
1251 my ($scheme2,$uri) = pb_cms_init($pbinit);
[361]1252
[415]1253 my ($pbconf) = pb_conf_get("pbconfurl");
[366]1254 $uri = $pbconf->{$ENV{'PBPROJ'}};
1255 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1256
[361]1257 # Checking CMS repositories status
[358]1258 my ($pburl) = pb_conf_get("pburl");
[366]1259 ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
[340]1260
1261 if ($scheme !~ /^svn/) {
[199]1262 die "Only SVN is supported at the moment";
1263 }
[358]1264 my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
[361]1265 die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
[358]1266
1267 $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
[361]1268 die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
[358]1269
1270 # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
1271 # we want to get for the root of the new URL
1272
1273 my $tmp = $ENV{'PBROOTDIR'};
1274 $tmp =~ s|^$ENV{'PBCONFDIR'}||;
1275
1276 my $newurl = "$uri/".dirname($tmp)."/$newver";
[366]1277 # Should probably use projver in the old file
1278 my $oldver= basename($tmp);
[361]1279
1280 # Checking pbcl files
[366]1281 foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
[361]1282 open(PBCL,$f) || die "Unable to open $f";
1283 my $foundnew = 0;
1284 while (<PBCL>) {
[363]1285 $foundnew = 1 if (/^$newver \(/);
[361]1286 }
1287 close(PBCL);
[362]1288 die "ERROR: version $newver not found in $f" if ($foundnew == 0);
[361]1289 }
1290
[366]1291 # Duplicate and extract project-builder part
[361]1292 pb_log(2,"Copying $uri/$tmp to $newurl\n");
[366]1293 pb_cms_copy($scheme,"$uri/$tmp",$newurl);
1294 pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
[383]1295 pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
[361]1296
[366]1297 # Duplicate and extract project
1298 my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
1299
1300 pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
1301 pb_cms_copy($scheme,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
1302 pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
[383]1303 pb_cms_up($scheme,"$ENV{'PBDIR'}/..");
[366]1304
[361]1305 # Update the .pb file
[358]1306 open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
1307 open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
[208]1308 while(<FILE>) {
[361]1309 s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
1310 pb_log(0,"Changing projver from $oldver to $newver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/);
1311 s/^testver/#testver/;
1312 pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
[211]1313 print OUT $_;
[208]1314 }
1315 close(FILE);
[211]1316 close(OUT);
[358]1317 rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
[363]1318
[358]1319 pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
[363]1320 pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver");
[199]1321}
1322
[293]1323#
[320]1324# Return the list of VMs/VEs we are working on
[105]1325# $all is a flag to know if we return all of them
1326# or only some (if all we publish also tar files in addition to pkgs
1327#
[320]1328sub pb_get_v {
[91]1329
[320]1330my $vtype = shift;
1331my @v;
[105]1332my $all = 0;
[320]1333my $vlist;
1334my $pbv = 'PBV';
[91]1335
[320]1336if ($vtype eq "vm") {
1337 $vlist = "vmlist";
1338} elsif ($vtype eq "ve") {
1339 $vlist = "velist";
1340}
1341# Get VM/VE list
1342if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
1343 my ($ptr) = pb_conf_get($vlist);
1344 $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
[105]1345 $all = 1;
[91]1346}
[320]1347pb_log(2,"$vtype: $ENV{$pbv}\n");
1348@v = split(/,/,$ENV{$pbv});
1349return(\@v,$all);
[91]1350}
1351
[320]1352# Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
1353# Needs to use root account to connect to the VM/VE
1354# pb will take your local public SSH key to access
[346]1355# the pb account in the VM later on if needed
1356sub pb_setup_v {
[320]1357
1358my $vtype = shift;
1359
[353]1360my ($vm,$all) = pb_get_v($vtype);
1361
[346]1362# Script generated
1363my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
[320]1364
[353]1365foreach my $v (@$vm) {
1366 # Name of the account to deal with for VM/VE
1367 # Do not use the one passed potentially with -a
1368 my ($pbac) = pb_conf_get($vtype."login");
[354]1369 my ($key,$zero0,$zero1,$zero2);
[357]1370 my ($vmexist,$vmpid);
[346]1371
[353]1372 if ($vtype eq "vm") {
1373 # Prepare the key to be used and transfered remotely
1374 my $keyfile = pb_ssh_get(1);
1375
1376 my ($vmhost,$vmport) = pb_conf_get("vmhost","vmport");
1377 my $nport = $vmport->{$ENV{'PBPROJ'}};
1378 $nport = "$pbport" if (defined $pbport);
[347]1379
[353]1380 # Launch the VM
[357]1381 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
[347]1382
[353]1383 # Skip that VM if something went wrong
1384 return if (($vmpid == 0) && ($vmexist == 0));
1385
[354]1386 # Store the pub key part in a variable
1387 open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
1388 ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
1389 close(FILE);
1390
1391 $key = "\Q$zero1";
1392
[435]1393 pb_system("cat $keyfile.pub | ssh -q -o UserKnownHostsFile=/dev/null -p $nport -i $keyfile root\@$vmhost->{$ENV{'PBPROJ'}} \"mkdir -p .ssh ; chmod 700 .ssh ; cat >> .ssh/authorized_keys ; chmod 600 .ssh/authorized_keys\"","Copying local keys to $vtype. This will require the root password");
[353]1394 # once this is done, we can do what we want on the VM remotely
1395 }
1396
1397 # Prepare the script to be executed on the VM/VE
1398 # in $ENV{'PBDESTDIR'}/setupv
1399
1400 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
1401 print SCRIPT << 'EOF';
[320]1402#!/usr/bin/perl -w
1403
[346]1404use strict;
1405use File::Copy;
1406
[427]1407our $debug;
1408our $LOG;
1409our $synmsg = "pbscript";
1410pb_log_init($debug, $LOG);
1411pb_temp_init();
1412
[354]1413EOF
1414 if ($vtype eq "vm") {
1415 print SCRIPT << 'EOF';
1416# Removes duplicate in .ssh/authorized_keys of our key if needed
1417#
1418my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
1419open(PBFILE,$file1) || die "Unable to open $file1";
1420open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
1421my $count = 0;
1422while (<PBFILE>) {
1423EOF
1424 print SCRIPT << "EOF";
1425 if (/ $key /) {
1426 \$count++;
1427 }
1428print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
1429}
1430close(PBFILE);
1431close(PBOUT);
1432rename("\$file1.new",\$file1);
1433chmod 0600,\$file1;
1434EOF
1435 }
1436 print SCRIPT << 'EOF';
1437
1438# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
1439#
[346]1440my $file="/etc/passwd";
[320]1441open(PBFILE,$file) || die "Unable to open $file";
1442my $found = 0;
1443while (<PBFILE>) {
[346]1444EOF
[353]1445 print SCRIPT << "EOF";
1446 \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
[346]1447EOF
[353]1448 print SCRIPT << 'EOF';
[320]1449}
1450close(PBFILE);
1451
1452if ( $found == 0 ) {
1453 if ( ! -d "/home" ) {
[427]1454 pb_mkdir("/home");
[320]1455 }
[346]1456EOF
[353]1457 print SCRIPT << "EOF";
[427]1458pb_system("groupadd $pbac->{$ENV{'PBPROJ'}}","Adding group $pbac->{$ENV{'PBPROJ'}}");
1459pb_system("useradd $pbac->{$ENV{'PBPROJ'}} -g $pbac->{$ENV{'PBPROJ'}} -m -d /home/$pbac->{$ENV{'PBPROJ'}}","Adding user $pbac->{$ENV{'PBPROJ'}} (group $pbac->{$ENV{'PBPROJ'}} - home /home/$pbac->{$ENV{'PBPROJ'}}");
1460}
[320]1461
[354]1462# allow ssh entry to build
1463#
[427]1464mkdir "/home/$pbac->{$ENV{'PBPROJ'}}/.ssh",0700;
[347]1465# Allow those accessing root to access the build account
[427]1466copy("\$ENV{'HOME'}/.ssh/authorized_keys","/home/$pbac->{$ENV{'PBPROJ'}}/.ssh/authorized_keys");
[320]1467chmod 0600,".ssh/authorized_keys";
[427]1468pb_system("chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} /home/$pbac->{$ENV{'PBPROJ'}}/.ssh","Finish setting up the SSH env for $pbac->{$ENV{'PBPROJ'}}");
[320]1469
[346]1470EOF
[353]1471 print SCRIPT << 'EOF';
[347]1472# No passwd for build account only keys
[320]1473$file="/etc/shadow";
1474open(PBFILE,$file) || die "Unable to open $file";
1475open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1476while (<PBFILE>) {
[346]1477EOF
[353]1478 print SCRIPT << "EOF";
1479 s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
1480 s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
[346]1481EOF
[353]1482 print SCRIPT << 'EOF';
[320]1483 print PBOUT $_;
1484}
1485close(PBFILE);
1486close(PBOUT);
1487rename("$file.new",$file);
1488chmod 0640,$file;
1489
1490# pb has to be added to portage group on gentoo
1491
[346]1492# Adapt sudoers
1493$file="/etc/sudoers";
1494open(PBFILE,$file) || die "Unable to open $file";
1495open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1496while (<PBFILE>) {
1497EOF
[353]1498 print SCRIPT << "EOF";
1499 next if (/^$pbac->{$ENV{'PBPROJ'}} /);
[346]1500EOF
[353]1501 print SCRIPT << 'EOF';
[346]1502 s/Defaults[ \t]+requiretty//;
1503 print PBOUT $_;
1504}
1505close(PBFILE);
1506EOF
[353]1507 print SCRIPT << "EOF";
1508# This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
1509print PBOUT "$pbac->{$ENV{'PBPROJ'}} ALL=(ALL) NOPASSWD:ALL\n";
[346]1510EOF
[353]1511 print SCRIPT << 'EOF';
[346]1512close(PBOUT);
1513rename("$file.new",$file);
1514chmod 0440,$file;
1515
1516EOF
[353]1517
1518 my $SCRIPT = \*SCRIPT;
1519
1520 pb_install_deps($SCRIPT);
1521
1522 print SCRIPT << 'EOF';
[346]1523# Suse wants sudoers as 640
1524if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
1525 chmod 0640,$file;
1526}
1527
1528# Sync date
[353]1529#system "/usr/sbin/ntpdate ntp.pool.org";
[346]1530
[427]1531pb_system("rm -rf perl-ProjectBuilder-* ; wget --passive-ftp ftp://ftp.mondorescue.org/src/perl-ProjectBuilder-latest.tar.gz ; tar xvfz perl-ProjectBuilder-latest.tar.gz ; cd perl-ProjectBuilder-* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf perl-ProjectBuilder-* ; 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 .. ; rm -rf project-builder-* ;","Building Project-Builder");
[358]1532system "pb 2>&1 | head -5";
[357]1533EOF
1534 if ((! $vmexist) && ($vtype eq "vm")) {
1535 print SCRIPT << 'EOF';
[427]1536pb_system("sudo /sbin/halt -p","Halting the $vtype");
[346]1537EOF
[357]1538 }
[353]1539
1540 # Adds pb_distro_init from ProjectBuilder::Distribution
1541 foreach my $d (@INC) {
[405]1542 my @f = ("$d/ProjectBuilder/Base.pm","$d/ProjectBuilder/Distribution.pm");
1543 foreach my $f (@f) {
1544 if (-f "$f") {
1545 open(PBD,"$f") || die "Unable to open $f";
1546 while (<PBD>) {
[427]1547 next if (/^package/);
1548 next if (/^use Exporter/);
1549 next if (/^use ProjectBuilder::/);
1550 next if (/^our /);
[405]1551 print SCRIPT $_;
1552 }
1553 close(PBD);
[353]1554 }
[347]1555 }
1556 }
[353]1557 close(SCRIPT);
1558 chmod 0755,"$pbscript";
1559
1560 # That build script needs to be run as root
1561 $pbaccount = "root";
1562 pb_script2v($pbscript,$vtype);
[347]1563}
[353]1564return;
[346]1565}
1566
[347]1567sub pb_install_deps {
[346]1568
[348]1569my $SCRIPT = shift;
[346]1570
[348]1571print {$SCRIPT} << 'EOF';
[346]1572# We need to have that pb_distro_init function
[347]1573# Get it from Project-Builder::Distribution
[320]1574my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
1575print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
1576
1577# Get and install pb
[357]1578my $insdm = "rm -rf Date-Manip* ; wget http://search.cpan.org/CPAN/authors/id/S/SB/SBECK/Date-Manip-5.48.tar.gz ; tar xvfz Date-Manip-5.48.tar.gz ; cd Date-Manip* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf Date-Manip*";
1579my $insmb = "rm -rf Module-Build* ; wget http://search.cpan.org/CPAN/authors/id/K/KW/KWILLIAMS/Module-Build-0.2808.tar.gz ; tar xvfz Module-Build-0.2808.tar.gz ; cd Module-Build* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf Module-Build*";
1580my $insfm = "rm -rf File-MimeInfo* ; wget http://search.cpan.org/CPAN/authors/id/P/PA/PARDUS/File-MimeInfo/File-MimeInfo-0.15.tar.gz ; tar xvfz File-MimeInfo-0.15.tar.gz ; cd File-MimeInfo* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf File-MimeInfo*";
1581my $insfb = "rm -rf File-Basedir* ; wget http://search.cpan.org/CPAN/authors/id/P/PA/PARDUS/File-BaseDir-0.03.tar.gz ; tar xvfz File-BaseDir-0.03.tar.gz ; cd File-BaseDir* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf File-BaseDir*";
[427]1582my $cmtdm = "Installing Date-Manip perl module";
1583my $cmtmb = "Installing Module-Build perl module";
1584my $cmtfm = "Installing File-MimeInfo perl module";
1585my $cmtfb = "Installing File-Basedir perl module";
1586my $cmtall = "Installing required modules";
[357]1587
[320]1588if ( $ddir eq "fedora" ) {
[427]1589 pb_system("yum clean all","Cleaning yum env");
[346]1590 #system "yum update -y";
[320]1591 my $arch=`uname -m`;
1592 my $opt = "";
1593 chomp($arch);
1594 if ($arch eq "x86_64") {
1595 $opt="--exclude=*.i?86";
1596 }
1597
[427]1598 pb_system("yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker",$cmtall);
[357]1599 if ($dver eq 4) {
[427]1600 pb_system("$insmb","$cmtmb");
1601 pb_system("$insfm","$cmtfm");
1602 pb_system("$insfb","$cmtfb");
[357]1603 }
1604} elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
[358]1605 # Suppose pkg are installed already as no online mirror available
[427]1606 pb_system("rpm -e lsb 2>&1 > /dev/null","Removing lsb package");
1607 pb_system("$insdm","$cmtdm");
1608 pb_system("$insmb","$cmtmb");
1609 pb_system("$insfm","$cmtfm");
1610 pb_system("$insfb","$cmtfb");
[320]1611} elsif ($ddir eq "suse") {
1612 # New OpenSuSE
[427]1613 pb_system("$insmb","$cmtmb");
1614 pb_system("$insfm","$cmtfm");
1615 pb_system("$insfb","$cmtfb");
1616 pb_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","$cmtall");
[320]1617} elsif ( $dfam eq "md" ) {
[427]1618 pb_system("urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo","$cmtall");
[357]1619 if (($ddir eq "mandrake") && ($dver eq "10.1")) {
[427]1620 pb_system("$insdm","$cmtdm");
[357]1621 } else {
[427]1622 pb_system("urpmi --auto perl-DateManip","$cmtdm");
[357]1623 }
[320]1624} elsif ( $dfam eq "du" ) {
1625 if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
[346]1626 #system "apt-get update";
[427]1627 pb_system("$insfb","$cmtfb");
1628 pb_system("$insfm","$cmtfm");
1629 pb_system("apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl","$cmtall");
[320]1630 } else {
[427]1631 pb_system("apt-get update; apt-get -y install wget patch openssh-server dpkg-dev sudo debian-builder dh-make fakeroot ntpdate libfile-mimeinfo-perl libmodule-build-perl libdate-manip-perl","$cmtall");
[320]1632 }
1633} elsif ( $dfam eq "gen" ) {
[427]1634 #system "emerge -u system";
1635 pb_system("emerge wget sudo ntp DateManip File-MimeInfo","$cmtall");
[320]1636} else {
1637 print "No pkg to install\n";
1638}
1639EOF
1640}
1641
[347]1642# Return the SSH key file to use
1643# Potentially create it if needed
1644
1645sub pb_ssh_get {
1646
1647my $create = shift || 0; # Do not create keys by default
1648
1649# Check the SSH environment
1650my $keyfile = undef;
1651
1652# We have specific keys by default
1653$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
[348]1654if (!(-e $keyfile) && ($create eq 1)) {
[347]1655 pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
1656}
1657
1658$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
1659$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
1660$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
1661die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
1662return($keyfile);
1663}
1664
1665
[145]1666# Returns the pid of a running VM command using a specific VM file
[142]1667sub pb_check_ps {
1668 my $vmcmd = shift;
1669 my $vmm = shift;
1670 my $vmexist = 0; # FALSE by default
1671
1672 open(PS, "ps auxhww|") || die "Unable to call ps";
1673 while (<PS>) {
1674 next if (! /$vmcmd/);
1675 next if (! /$vmm/);
1676 my ($void1, $void2);
1677 ($void1, $vmexist, $void2) = split(/ +/);
1678 last;
1679 }
1680 return($vmexist);
1681}
1682
1683
[77]1684sub pb_extract_build_files {
[25]1685
1686my $src=shift;
1687my $dir=shift;
[26]1688my $ddir=shift;
[28]1689my @files;
[25]1690
[188]1691if ($src =~ /tar\.gz$/) {
1692 pb_system("tar xfpz $src $dir","Extracting build files");
1693} elsif ($src =~ /tar\.bz2$/) {
1694 pb_system("tar xfpj $src $dir","Extracting build files");
1695} else {
1696 die "Unknown compression algorithm for $src";
1697}
[25]1698opendir(DIR,"$dir") || die "Unable to open directory $dir";
1699foreach my $f (readdir(DIR)) {
1700 next if ($f =~ /^\./);
[26]1701 move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
[315]1702 pb_log(2,"mv $dir/$f $ddir\n");
[28]1703 push @files,"$ddir/$f";
[25]1704}
1705closedir(DIR);
[26]1706# Not enough but still a first cleanup
[74]1707pb_rm_rf("$dir");
[28]1708return(@files);
[25]1709}
1710
[315]1711sub pb_list_bfiles {
1712
1713my $dir = shift;
1714my $pbpkg = shift;
1715my $bfiles = shift;
1716my $pkgfiles = shift;
1717my $supfiles = shift;
1718
1719opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
1720foreach my $f (readdir(BDIR)) {
1721 next if ($f =~ /^\./);
1722 $bfiles->{$f} = "$dir/$f";
[340]1723 $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
[315]1724 if (defined $supfiles->{$pbpkg}) {
1725 $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
1726 }
1727}
1728closedir(BDIR);
1729}
1730
[395]1731
1732#
1733# Return the list of packages we are working on in a non CMS action
1734#
1735sub pb_get_pkg {
1736
1737my @pkgs = ();
1738
1739my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
1740@pkgs = keys %$var;
1741
1742pb_log(0,"Packages: ".join(',',@pkgs)."\n");
1743return(\@pkgs);
1744}
1745
17461;
Note: See TracBrowser for help on using the repository browser.