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

Last change on this file since 453 was 453, checked in by Bruno Cornec, 16 years ago
  • Sort output of build files
  • adds pbrepo entry when using newproj
  • Property svn:executable set to *
File size: 56.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
[448]490 # Get project info on authors and log file
491 $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
492 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
493 $chglog = undef if (! -f $chglog);
[285]494
[448]495 my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
496 $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
497 $authors = "/dev/null" if (! -f $authors);
[435]498
[448]499 # Extract cms log history and store it
500 if ((defined $chglog) && (! -f "$dest/NEWS")) {
501 pb_log(2,"Generating NEWS file from $chglog\n");
502 copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
[285]503 }
[448]504 pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors,$testver);
[29]505
[21]506 my %build;
[435]507 my @pt;
508 my $tmpl = "";
[91]509
[328]510 @pt = pb_conf_get_if("vmlist","velist");
[340]511 if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
512 $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
513 }
514 if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
515 # the 2 lists needs to be grouped with a ',' separated them
516 if ($tmpl ne "") {
517 $tmpl .= ",";
518 }
519 $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
520 }
521 foreach my $d (split(/,/,$tmpl)) {
[315]522 my ($name,$ver,$arch) = split(/-/,$d);
523 chomp($arch);
[99]524 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
[315]525 pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n");
526 pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
[13]527
[16]528 # Filter build files from the less precise up to the most with overloading
[13]529 # Filter all files found, keeping the name, and generating in dest
[16]530
[340]531 # Find all build files first relatively to PBROOTDIR
[300]532 # Find also all specific files referenced in the .pb conf file
[320]533 my %bfiles = ();
534 my %pkgfiles = ();
[21]535 $build{"$ddir-$dver"} = "yes";
[315]536
[340]537 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dtype") {
538 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dtype",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
539 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dfam") {
540 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
541 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir") {
542 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
543 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver") {
544 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
[13]545 } else {
[21]546 $build{"$ddir-$dver"} = "no";
[13]547 next;
548 }
[315]549 pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
[13]550
[15]551 # Get all filters to apply
[77]552 my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
[15]553
[19]554 # Apply now all the filters on all the files concerned
555 # destination dir depends on the type of file
556 if (defined $ptr) {
[300]557 foreach my $f (values %bfiles,values %pkgfiles) {
[429]558 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]559 }
[15]560 }
[18]561 }
[315]562 my @found;
563 my @notfound;
564 foreach my $b (keys %build) {
565 push @found,$b if ($build{$b} =~ /yes/);
566 push @notfound,$b if ($build{$b} =~ /no/);
[21]567 }
[453]568 pb_log(0,"Build files generated for ".join(',',sort(@found))."\n");
569 pb_log(0,"No Build files found for ".join(',',sort(@notfound))."\n") if (@notfound);
[236]570 # Get the generic filter (all.pbf) and
571 # apply those to the non-build files including those
572 # generated by pbinit if applicable
573
574 # Get only all.pbf filter
[357]575 my $ptr = pb_get_filters($pbpkg);
[236]576
577 my $liste ="";
578 if (defined $filteredfiles->{$pbpkg}) {
579 foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
[429]580 pb_filter_file_inplace($ptr,"$dest/$f",$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'},$ENV{'PBPROJ'},$ENV{'PBREPO'});
[238]581 $liste = "$f $liste";
[236]582 }
583 }
[315]584 pb_log(2,"Files ".$liste."have been filtered\n");
[236]585
[265]586 # Prepare the dest directory for archive
[340]587 if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
[429]588 pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'},$ENV{'PBPROJ'},$ENV{'PBREPO'});
[266]589 chmod 0755,"$ENV{'PBTMP'}/pbinit";
[340]590 pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit");
[265]591 }
592
[18]593 # Archive dest dir
[69]594 chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
[25]595 # Possibility to look at PBSRC to guess more the filename
[94]596 pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
[344]597 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
[83]598
[357]599 # Keep track of version-tag per pkg
600 $pkgs{$pbpkg} = "$pbver-$pbtag";
[83]601
[288]602 # Final cleanup
603 pb_rm_rf($dest) if (-d $dest);
[9]604 }
[357]605
606 # Keep track of per package version
607 pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
608 open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
609 foreach my $pbpkg (@pkgs) {
610 print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
611 }
612 close(PKG);
613
614 # Keep track of what is generated by default
615 # We need to store the dir and info on version-tag
616 # Base our content on the existing .pb file
617 copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
618 open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
619 print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
620 print LAST "pbprojver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
621 print LAST "pbprojtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
622 print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
623 close(LAST);
[77]624}
[22]625
[77]626sub pb_build2pkg {
627
[22]628 # Get the running distro to build on
[99]629 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
[315]630 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
[22]631
[353]632 # Get list of packages to build
[83]633 # Get content saved in cms2build
[353]634 my $ptr = pb_get_pkg();
635 @pkgs = @$ptr;
636
637 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
[83]638 $pkg = { } if (not defined $pkg);
639
[25]640 chdir "$ENV{'PBBUILDDIR'}";
[126]641 my $made = ""; # pkgs made during build
[27]642 foreach my $pbpkg (@pkgs) {
[88]643 my $vertag = $pkg->{$pbpkg};
[77]644 # get the version of the current package - maybe different
645 ($pbver,$pbtag) = split(/-/,$vertag);
646
[27]647 my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
[315]648 pb_log(2,"Source file: $src\n");
[25]649
[315]650 pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
[25]651 if ($dtype eq "rpm") {
652 foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
[28]653 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
[96]654 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]655 }
[25]656 }
657
[315]658 # Remove in case a previous link/file was there
[301]659 unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
[188]660 symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
[25]661 # We need to first extract the spec file
[28]662 my @specfile;
[77]663 @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
[25]664
[315]665 pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
[25]666 # set LANGUAGE to check for correct log messages
667 $ENV{'LANGUAGE'}="C";
[28]668 foreach my $f (@specfile) {
669 if ($f =~ /\.spec$/) {
[353]670 pb_system("rpmbuild --define \'packager $ENV{'PBPACKAGER'}\' --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
[28]671 last;
672 }
673 }
[136]674 $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
[149]675 if (-f "/usr/bin/rpmlint") {
676 pb_system("rpmlint $made","Checking validity of rpms with rpmlint");
[150]677 }
[118]678 } elsif ($dtype eq "deb") {
[149]679 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
[274]680 pb_system("tar xfz $src","Extracting sources");
[149]681
682 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
[310]683 pb_rm_rf("debian");
[149]684 symlink "pbconf/$ddir-$dver","debian" || die "Unable to symlink to pbconf/$ddir-$dver";
[199]685 chmod 0755,"debian/rules";
[448]686 if ($dver !~ /[0-9]/) {
687 # dpkg-deb doesn't accept non digit versions. removing checks
688 # dpkg-source checks upper case when generating perl modules
689 }
[149]690 pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package");
[136]691 $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
[315]692 if (-f "/usr/bin/lintian") {
693 pb_system("lintian $made","Checking validity of debs with lintian");
694 }
[87]695 } elsif ($dtype eq "ebuild") {
[149]696 my @ebuildfile;
697 # For gentoo we need to take pb as subsystem name
[295]698 # We put every apps here under sys-apps. hope it's correct
[435]699 # We use pb's home dir in order to have a single OVERLAY line
[295]700 my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
701 pb_mkdir_p($tmpd) if (! -d "$tmpd");
702 pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
[149]703
[295]704 # We need to first extract the ebuild file
705 @ebuildfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$tmpd");
[149]706
707 # Prepare the build env for gentoo
708 my $found = 0;
[295]709 my $pbbd = $ENV{'HOME'};
[150]710 $pbbd =~ s|/|\\/|g;
[295]711 if (-r "/etc/make.conf") {
712 open(MAKE,"/etc/make.conf");
713 while (<MAKE>) {
714 $found = 1 if (/$pbbd\/portage/);
715 }
716 close(MAKE);
[149]717 }
718 if ($found == 0) {
[295]719 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
[149]720 }
[295]721 #$found = 0;
722 #if (-r "/etc/portage/package.keywords") {
723 #open(KEYW,"/etc/portage/package.keywords");
724 #while (<KEYW>) {
725 #$found = 1 if (/portage\/pb/);
726 #}
727 #close(KEYW);
728 #}
729 #if ($found == 0) {
730 #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
731 #}
[149]732
733 # Build
734 foreach my $f (@ebuildfile) {
735 if ($f =~ /\.ebuild$/) {
[295]736 move($f,"$tmpd/$pbpkg-$pbver.ebuild");
737 pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package");
738 # Now move it where pb expects it
739 pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
740 move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
[149]741 }
742 }
743
[295]744 $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver.ebuild";
[437]745 } elsif ($dtype eq "tgz") {
746 # Slackware family
[435]747 $made="$made $pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
748
749 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
750 pb_system("tar xfz $src","Extracting sources");
751 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
752 symlink "pbconf/$ddir-$dver","install" || die "Unable to symlink to pbconf/$ddir-$dver";
753 if (-x "install/pbslack") {
754 pb_system("./install/pbslack","Building package");
755 pb_system("sudo /sbin/makepkg -p -l y -c y $pbpkg","Packaging $pbpkg");
756 }
[87]757 } else {
[118]758 die "Unknown dtype format $dtype";
[87]759 }
760 }
[118]761 # Keep track of what is generated so that we can get them back from VMs
[353]762 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
[118]763 print KEEP "$made\n";
764 close(KEEP);
[87]765}
766
[88]767sub pb_build2ssh {
[320]768 pb_send2target("Sources");
[90]769}
[87]770
[90]771sub pb_pkg2ssh {
[320]772 pb_send2target("Packages");
[90]773}
774
[108]775# By default deliver to the the public site hosting the
[320]776# ftp structure (or whatever) or a VM/VE
777sub pb_send2target {
[90]778
779 my $cmt = shift;
[320]780 my $v = shift || undef;
[142]781 my $vmexist = shift || 0; # 0 is FALSE
[200]782 my $vmpid = shift || 0; # 0 is FALSE
[320]783
[444]784 pb_log(2,"DEBUG: pb_send2target($cmt,".Dumper($v).",$vmexist,$vmpid)\n");
[320]785 my $host = "sshhost";
786 my $login = "sshlogin";
787 my $dir = "sshdir";
788 my $port = "sshport";
789 my $conf = "sshconf";
790 my $rebuild = "sshrebuild";
[415]791 my $tmout = "vmtmout";
792 my $path = "vmpath";
[348]793 if (($cmt eq "vm") || ($cmt eq "Script")) {
[320]794 $login = "vmlogin";
[322]795 $dir = "pbdefdir";
[320]796 $tmout = "vmtmout";
797 $rebuild = "vmrebuild";
798 # Specific VM
799 $host = "vmhost";
800 $port = "vmport";
801 } elsif ($cmt eq "ve") {
802 $login = "velogin";
[322]803 $dir = "pbdefdir";
[320]804 $tmout = "vetmout";
805 # Specific VE
806 $path = "vepath";
807 $conf = "veconf";
808 $rebuild = "verebuild";
809 }
[158]810 my $cmd = "";
[90]811
[353]812 my $ptr = pb_get_pkg();
[87]813 @pkgs = @$ptr;
814
[136]815 # Get the running distro to consider
[347]816 my ($odir,$over,$oarch) = (undef, undef, undef);
[320]817 if (defined $v) {
818 ($odir,$over,$oarch) = split(/-/,$v);
[118]819 }
820 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
[315]821 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
[87]822
[353]823 # Get list of packages to build
[87]824 # Get content saved in cms2build
[353]825 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
[87]826 $pkg = { } if (not defined $pkg);
827
[118]828 my $src = "";
[87]829 chdir "$ENV{'PBBUILDDIR'}";
830 foreach my $pbpkg (@pkgs) {
[88]831 my $vertag = $pkg->{$pbpkg};
[87]832 # get the version of the current package - maybe different
833 ($pbver,$pbtag) = split(/-/,$vertag);
834
[320]835 if (($cmt eq "Sources") || ($cmt eq "vm") || ($cmt eq "ve")) {
[158]836 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
[166]837 if ($cmd eq "") {
838 $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
839 } else {
840 $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
841 }
[118]842 }
843 }
[429]844 # Adds conf file for availability of conf elements
[417]845 pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
846
[320]847 if (($cmt eq "vm") || ($cmt eq "ve")) {
[444]848 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc $ENV{'PBDESTDIR'}/pbscript";
[142]849 } elsif ($cmt eq "Script") {
[444]850 $src="$src $ENV{'PBDESTDIR'}/pbscript";
[118]851 } elsif ($cmt eq "Packages") {
852 # Get package list from file made during build2pkg
[353]853 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
[126]854 $src = <KEEP>;
[118]855 chomp($src);
856 close(KEEP);
[444]857 $src="$src $ENV{'PBBUILDDIR'}/pbscript" if ($cmt ne "Sources");
[87]858 }
[320]859 # Remove potential leading spaces (cause problem with basename)
[132]860 $src =~ s/^ *//;
[129]861 my $basesrc = "";
[131]862 foreach my $i (split(/ +/,$src)) {
863 $basesrc .= " ".basename($i);
[130]864 }
[118]865
[320]866 pb_log(0,"Sources handled ($cmt): $src\n");
[355]867 pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf))."\n");
[415]868 my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vepath) = pb_conf_get($host,$login,$dir,$port,$tmout,$path);
869 my ($vrebuild,$veconf) = pb_conf_get_if($rebuild,$conf);
[320]870 pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
871 # Not mandatory
872 my ($testver) = pb_conf_get_if("testver");
873
874 my $mac;
875 # Useless for VE
876 if ($cmt ne "ve") {
877 $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
878 # Overwrite account value if passed as parameter
879 $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
[355]880 pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
[320]881 }
882
[108]883 my $tdir;
[136]884 my $bdir;
[142]885 if (($cmt eq "Sources") || ($cmt eq "Script")) {
[108]886 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
[435]887 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
888 # This is a test pkg => target dir is under test
889 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/test/src";
890 }
[320]891 } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
892 $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
893 $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
[136]894 # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
895 $bdir =~ s|\$ENV.+\}/||;
[90]896 } elsif ($cmt eq "Packages") {
[108]897 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
[429]898
[337]899 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
[289]900 # This is a test pkg => target dir is under test
[428]901 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/test/$ddir/$dver";
[291]902 }
[429]903
904 my $repodir = $tdir;
905 $repodir =~ s|^$sshdir->{$ENV{'PBPROJ'}}/||;
906
907 my ($pbrepo) = pb_conf_get("pbrepo");
908
909 # Repository management
[444]910 open(PBS,"> $ENV{'PBBUILDDIR'}/pbscript") || die "Unable to create $ENV{'PBBUILDDIR'}/pbscript";
[429]911 if ($dtype eq "rpm") {
912 # Also make a pbscript to generate yum/urpmi bases
913 print PBS << "EOF";
[433]914#!/bin/bash
[429]915# Prepare a script to ease yum setup
916cat > $ENV{'PBPROJ'}.repo << EOT
917[$ENV{'PBPROJ'}]
918name=$ddir $dver - $ENV{'PBPROJ'} Vanilla Packages
[433]919baseurl=$pbrepo->{$ENV{'PBPROJ'}}/$repodir
[429]920enabled=1
921gpgcheck=0
922EOT
923chmod 644 $ENV{'PBPROJ'}.repo
924
925# Clean up old repo content
926rm -rf headers/ repodata/
927# Create yum repo
928yum-arch .
929# Create repodata
930createrepo .
931EOF
932 if ($dfam eq "md") {
933 # For Mandriva add urpmi management
934 print PBS << "EOF";
935# Prepare a script to ease urpmi setup
936cat > $ENV{'PBPROJ'}.addmedia << EOT
[433]937urpmi.addmedia $ENV{'PBPROJ'} $pbrepo->{$ENV{'PBPROJ'}}/$repodir with hdlist.cz
[429]938EOT
939chmod 755 $ENV{'PBPROJ'}.addmedia
940
941# Clean up old repo content
[437]942rm -f hdlist.cz synthesis.hdlist.cz
[429]943# Create urpmi repo
944genhdlist .
945EOF
946 }
947 } elsif ($dtype eq "deb") {
948 # Also make a pbscript to generate apt bases
949 }
950 close(PBS);
[444]951 chmod 0755,"$ENV{'PBBUILDDIR'}/pbscript";
[429]952
[90]953 } else {
954 return;
[22]955 }
[239]956
[320]957 # Useless for VE
958 my $nport;
959 if ($cmt ne "ve") {
960 $nport = $sshport->{$ENV{'PBPROJ'}};
961 $nport = "$pbport" if (defined $pbport);
962 }
963
[136]964 # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
[132]965 $tdir =~ s|\$ENV.+\}/||;
966
[320]967 my $tm = $vtmout->{$ENV{'PBPROJ'}};
968
969 # ssh communication if not VE
[349]970 # should use a hash instead...
[320]971 my ($shcmd,$cpcmd,$cptarget,$cp2target);
972 if ($cmt ne "ve") {
[347]973 my $keyfile = pb_ssh_get(0);
[435]974 $shcmd = "ssh -i $keyfile -q -o UserKnownHostsFile=/dev/null -p $nport $mac";
975 $cpcmd = "scp -i $keyfile -p -o UserKnownHostsFile=/dev/null -P $nport";
[320]976 $cptarget = "$mac:$tdir";
[351]977 if ($cmt eq "vm") {
978 $cp2target = "$mac:$bdir";
979 }
[320]980 } else {
981 my $tp = $vepath->{$ENV{'PBPROJ'}};
982 $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
983 $cpcmd = "cp -a ";
984 $cptarget = "$tp/$tdir";
985 $cp2target = "$tp/$bdir";
986 }
987
988 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");
989 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
[444]990
[320]991 # For VE we need to change the owner manually - To be tested if needed
992 #if ($cmt eq "ve") {
993 #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
994 #}
[434]995 pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi ; rm -f ./pbscript\' | bash\"","Executing pbscript on $cptarget if needed");
[320]996 if (($cmt eq "vm") || ($cmt eq "ve")) {
[128]997 # Get back info on pkg produced, compute their name and get them from the VM
[353]998 pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
999 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
[118]1000 my $src = <KEEP>;
1001 chomp($src);
1002 close(KEEP);
[131]1003 $src =~ s/^ *//;
[136]1004 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
[320]1005 # Change pgben to make the next send2target happy
[143]1006 my $made = "";
[353]1007 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
[136]1008 foreach my $p (split(/ +/,$src)) {
[139]1009 my $j = basename($p);
[320]1010 pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
[144]1011 $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
[136]1012 }
[143]1013 print KEEP "$made\n";
[139]1014 close(KEEP);
[320]1015 pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
[355]1016
1017 # We want to send them to the ssh account so overwrite what has been done before
1018 undef $pbaccount;
[357]1019 pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
[355]1020 pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
[141]1021 pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
[108]1022 }
[442]1023 pb_log(2,"Before halt, vmexist: $vmexist, vmpid: $vmpid\n");
1024 if ((! $vmexist) && (($cmt eq "vm") || ($cmt eq "Script"))) {
1025 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)");
1026 }
[9]1027}
[16]1028
[320]1029sub pb_script2v {
[142]1030 my $pbscript=shift;
[320]1031 my $vtype=shift;
[442]1032 my $force=shift || 0; # Force stop of VM. Default not
1033 my $vm1=shift || undef; # Only that VM to treat
1034 my $vm;
1035 my $all;
[141]1036
[442]1037 pb_log(2,"DEBUG: pb_script2v($pbscript,$vtype,$force,$vm1)\n");
[141]1038 # Prepare the script to be executed on the VM
1039 # in $ENV{'PBDESTDIR'}/pbscript
[142]1040 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
1041 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1042 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1043 }
[141]1044
[442]1045 if (not defined $vm1) {
1046 ($vm,$all) = pb_get_v($vtype);
1047 } else {
1048 @$vm = ($vm1);
1049 }
[320]1050 my ($vmexist,$vmpid) = (undef,undef);
[142]1051
[141]1052 foreach my $v (@$vm) {
[320]1053 # Launch the VM/VE
1054 if ($vtype eq "vm") {
1055 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
[442]1056 pb_log(2,"DEBUG: After pb_launchv, vmexist: $vmexist, vmpid: $vmpid\n");
[141]1057
[320]1058 # Skip that VM if something went wrong
[442]1059 next if (($vmpid == 0) && ($vmexist == 0));
1060
1061 # If force stopping the VM then reset vmexist
1062 if ($force == 1) {
1063 $vmpid = $vmexist;
1064 $vmexist = 0;
1065 }
[320]1066 }
[274]1067
[142]1068 # Gather all required files to send them to the VM
[320]1069 # and launch the build through pbscript
[442]1070 pb_log(2,"DEBUG: Before send2target, vmexist: $vmexist, vmpid: $vmpid\n");
[320]1071 pb_send2target("Script","$v",$vmexist,$vmpid);
[169]1072
[142]1073 }
1074}
1075
[320]1076sub pb_launchv {
1077 my $vtype = shift;
1078 my $v = shift;
1079 my $create = shift || 0; # By default do not create a VM
[310]1080
[442]1081 pb_log(2,"DEBUG: pb_launchv($vtype,$v,$create)\n");
[320]1082 die "No VM/VE defined, unable to launch" if (not defined $v);
1083 # Keep only the first VM in case many were given
1084 $v =~ s/,.*//;
[310]1085
[320]1086 # Which is our local arch ? (standardize on i386 for those platforms)
1087 my $arch = `uname -m`;
1088 chomp($arch);
1089 $arch =~ s/i.86/i386/;
[310]1090
[320]1091 # Launch the VMs/VEs
1092 if ($vtype eq "vm") {
1093 die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
[310]1094
[415]1095 my ($ptr,$vmopt,$vmpath,$vmport,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmpath","vmport","vmtmout","vmsize");
[320]1096
1097 my $vmtype = $ptr->{$ENV{'PBPROJ'}};
1098 if (not defined $ENV{'PBVMOPT'}) {
1099 $ENV{'PBVMOPT'} = "";
[310]1100 }
[320]1101 if (defined $vmopt->{$ENV{'PBPROJ'}}) {
1102 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
1103 }
1104 my $nport = $vmport->{$ENV{'PBPROJ'}};
1105 $nport = "$pbport" if (defined $pbport);
1106
1107 my $cmd;
1108 my $vmcmd; # has to be used for pb_check_ps
1109 my $vmm; # has to be used for pb_check_ps
1110 if ($vmtype eq "qemu") {
1111 my $qemucmd32;
1112 my $qemucmd64;
1113 if ($arch eq "x86_64") {
1114 $qemucmd32 = "/usr/bin/qemu-system-i386";
1115 $qemucmd64 = "/usr/bin/qemu";
1116 } else {
1117 $qemucmd32 = "/usr/bin/qemu";
1118 $qemucmd64 = "/usr/bin/qemu-system-x86_64";
1119 }
1120 if ($v =~ /x86_64/) {
1121 $vmcmd = "$qemucmd64 -no-kqemu";
1122 } else {
1123 $vmcmd = "$qemucmd32";
1124 }
1125 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
1126 if ($create != 0) {
1127 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
1128 }
1129 $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
1130 } elsif ($vmtype eq "xen") {
1131 } elsif ($vmtype eq "vmware") {
[310]1132 } else {
[320]1133 die "VM of type $vmtype not supported. Report to the dev team";
[310]1134 }
[320]1135 my ($tmpcmd,$void) = split(/ +/,$cmd);
1136 my $vmexist = pb_check_ps($tmpcmd,$vmm);
1137 my $vmpid = 0;
1138 if (! $vmexist) {
1139 if ($create != 0) {
1140 if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
1141 pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
1142 } elsif ($vmtype eq "vmware") {
1143 } else {
1144 }
1145 }
1146 if (! -f "$vmm") {
1147 pb_log(0,"Unable to find VM $vmm\n");
1148 } else {
1149 pb_system("$cmd &","Launching the VM $vmm");
1150 pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
1151 $vmpid = pb_check_ps($tmpcmd,$vmm);
[357]1152 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
[320]1153 }
[310]1154 } else {
[320]1155 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
[310]1156 }
[442]1157 pb_log(2,"DEBUG: pb_launchv returns ($vmexist,$vmpid)\n");
[320]1158 return($vmexist,$vmpid);
1159 # VE here
[310]1160 } else {
[320]1161 # Get VE context
[415]1162 my ($ptr,$vetmout,$vepath,$verebuild,$veconf) = pb_conf_get("vetype","vetmout","vepath","verebuild","veconf");
[320]1163 my $vetype = $ptr->{$ENV{'PBPROJ'}};
[310]1164
[320]1165 # Get distro context
1166 my ($name,$ver,$darch) = split(/-/,$v);
1167 chomp($darch);
1168 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
[142]1169
[320]1170 if ($vetype eq "chroot") {
1171 # Architecture consistency
1172 if ($arch ne $darch) {
1173 die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
1174 }
[142]1175
[320]1176 if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
1177 # We have to rebuild the chroot
1178 if ($dtype eq "rpm") {
1179 pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1180 # Once setup we need to install some packages, the pb account, ...
1181 pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
1182 #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1183 } elsif ($dtype eq "deb") {
1184 pb_system("","Creating the pbuilder VE");
1185 } elsif ($dtype eq "ebuild") {
1186 die "Please teach the dev team how to build gentoo chroot";
1187 } else {
1188 die "Unknown distribution type $dtype. Report to dev team";
1189 }
[310]1190 }
[320]1191 # Nothing more to do for VE. No real launch
[274]1192 } else {
[320]1193 die "VE of type $vetype not supported. Report to the dev team";
[262]1194 }
[141]1195 }
1196}
[142]1197
[320]1198sub pb_build2v {
[118]1199
[320]1200my $vtype = shift;
[142]1201
[320]1202# Prepare the script to be executed on the VM/VE
1203# in $ENV{'PBDESTDIR'}/pbscript
[353]1204#my ($ntp) = pb_conf_get($vtype."ntp");
1205#my $vntp = $ntp->{$ENV{'PBPROJ'}};
[118]1206
[320]1207open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1208print SCRIPT "#!/bin/bash\n";
1209print SCRIPT "echo ... Execution needed\n";
1210print SCRIPT "# This is in directory delivery\n";
1211print SCRIPT "# Setup the variables required for building\n";
1212print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
1213print SCRIPT "# Preparation for pb\n";
1214print SCRIPT "mv .pbrc \$HOME\n";
1215print SCRIPT "cd ..\n";
1216# Force new date to be in the future compared to the date of the tar file by adding 1 minute
1217my @date=pb_get_date();
1218$date[1]++;
1219my $upddate = strftime("%m%d%H%M%Y", @date);
[353]1220#print SCRIPT "echo Setting up date on $vntp...\n";
[320]1221# Or use ntpdate if available TBC
1222print SCRIPT "sudo date $upddate\n";
[353]1223# Get list of packages to build and get some ENV vars as well
1224my $ptr = pb_get_pkg();
1225@pkgs = @$ptr;
1226my $p = join(' ',@pkgs) if (@pkgs);
1227print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
1228print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
[320]1229print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
1230print SCRIPT "# Build\n";
1231print SCRIPT "echo Building packages on $vtype...\n";
1232print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
1233close(SCRIPT);
1234chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1235
1236my ($v,$all) = pb_get_v($vtype);
1237
1238# Send tar files when we do a global generation
1239pb_build2ssh() if ($all == 1);
1240
1241my ($vmexist,$vmpid) = (undef,undef);
1242
1243foreach my $v (@$v) {
1244 if ($vtype eq "vm") {
[142]1245 # Launch the VM
[357]1246 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
[118]1247
[274]1248 # Skip that VM if it something went wrong
1249 next if (($vmpid == 0) && ($vmexist == 0));
[118]1250 }
[320]1251 # Gather all required files to send them to the VM/VE
[347]1252 # and launch the build through pbscript
[357]1253 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
[320]1254 pb_send2target($vtype,"$v",$vmexist,$vmpid);
[105]1255}
[320]1256}
[105]1257
[262]1258
[199]1259sub pb_newver {
1260
[204]1261 die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
[340]1262
[366]1263 # Need this call for PBDIR
1264 my ($scheme2,$uri) = pb_cms_init($pbinit);
[361]1265
[415]1266 my ($pbconf) = pb_conf_get("pbconfurl");
[366]1267 $uri = $pbconf->{$ENV{'PBPROJ'}};
1268 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1269
[361]1270 # Checking CMS repositories status
[358]1271 my ($pburl) = pb_conf_get("pburl");
[366]1272 ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
[340]1273
1274 if ($scheme !~ /^svn/) {
[199]1275 die "Only SVN is supported at the moment";
1276 }
[358]1277 my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
[361]1278 die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
[358]1279
1280 $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
[361]1281 die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
[358]1282
1283 # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
1284 # we want to get for the root of the new URL
1285
1286 my $tmp = $ENV{'PBROOTDIR'};
1287 $tmp =~ s|^$ENV{'PBCONFDIR'}||;
1288
1289 my $newurl = "$uri/".dirname($tmp)."/$newver";
[366]1290 # Should probably use projver in the old file
1291 my $oldver= basename($tmp);
[361]1292
1293 # Checking pbcl files
[366]1294 foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
[361]1295 open(PBCL,$f) || die "Unable to open $f";
1296 my $foundnew = 0;
1297 while (<PBCL>) {
[363]1298 $foundnew = 1 if (/^$newver \(/);
[361]1299 }
1300 close(PBCL);
[362]1301 die "ERROR: version $newver not found in $f" if ($foundnew == 0);
[361]1302 }
1303
[366]1304 # Duplicate and extract project-builder part
[361]1305 pb_log(2,"Copying $uri/$tmp to $newurl\n");
[366]1306 pb_cms_copy($scheme,"$uri/$tmp",$newurl);
1307 pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
[383]1308 pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
[361]1309
[366]1310 # Duplicate and extract project
1311 my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
1312
1313 pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
1314 pb_cms_copy($scheme,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
1315 pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
[383]1316 pb_cms_up($scheme,"$ENV{'PBDIR'}/..");
[366]1317
[361]1318 # Update the .pb file
[358]1319 open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
1320 open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
[208]1321 while(<FILE>) {
[361]1322 s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
1323 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/);
1324 s/^testver/#testver/;
1325 pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
[211]1326 print OUT $_;
[208]1327 }
1328 close(FILE);
[211]1329 close(OUT);
[358]1330 rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
[363]1331
[358]1332 pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
[452]1333 pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver",undef);
[199]1334}
1335
[293]1336#
[320]1337# Return the list of VMs/VEs we are working on
[105]1338# $all is a flag to know if we return all of them
1339# or only some (if all we publish also tar files in addition to pkgs
1340#
[320]1341sub pb_get_v {
[91]1342
[320]1343my $vtype = shift;
1344my @v;
[105]1345my $all = 0;
[320]1346my $vlist;
1347my $pbv = 'PBV';
[91]1348
[320]1349if ($vtype eq "vm") {
1350 $vlist = "vmlist";
1351} elsif ($vtype eq "ve") {
1352 $vlist = "velist";
1353}
1354# Get VM/VE list
1355if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
1356 my ($ptr) = pb_conf_get($vlist);
1357 $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
[105]1358 $all = 1;
[91]1359}
[320]1360pb_log(2,"$vtype: $ENV{$pbv}\n");
1361@v = split(/,/,$ENV{$pbv});
1362return(\@v,$all);
[91]1363}
1364
[320]1365# Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
1366# Needs to use root account to connect to the VM/VE
1367# pb will take your local public SSH key to access
[346]1368# the pb account in the VM later on if needed
1369sub pb_setup_v {
[320]1370
1371my $vtype = shift;
1372
[353]1373my ($vm,$all) = pb_get_v($vtype);
1374
[346]1375# Script generated
1376my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
[320]1377
[353]1378foreach my $v (@$vm) {
1379 # Name of the account to deal with for VM/VE
1380 # Do not use the one passed potentially with -a
1381 my ($pbac) = pb_conf_get($vtype."login");
[354]1382 my ($key,$zero0,$zero1,$zero2);
[357]1383 my ($vmexist,$vmpid);
[346]1384
[353]1385 if ($vtype eq "vm") {
1386 # Prepare the key to be used and transfered remotely
1387 my $keyfile = pb_ssh_get(1);
1388
1389 my ($vmhost,$vmport) = pb_conf_get("vmhost","vmport");
1390 my $nport = $vmport->{$ENV{'PBPROJ'}};
1391 $nport = "$pbport" if (defined $pbport);
[347]1392
[353]1393 # Launch the VM
[357]1394 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
[347]1395
[353]1396 # Skip that VM if something went wrong
[442]1397 next if (($vmpid == 0) && ($vmexist == 0));
[353]1398
[354]1399 # Store the pub key part in a variable
1400 open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
1401 ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
1402 close(FILE);
1403
1404 $key = "\Q$zero1";
1405
[435]1406 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]1407 # once this is done, we can do what we want on the VM remotely
1408 }
1409
1410 # Prepare the script to be executed on the VM/VE
1411 # in $ENV{'PBDESTDIR'}/setupv
1412
1413 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
1414 print SCRIPT << 'EOF';
[320]1415#!/usr/bin/perl -w
1416
[346]1417use strict;
1418use File::Copy;
1419
[427]1420our $debug;
1421our $LOG;
1422our $synmsg = "pbscript";
1423pb_log_init($debug, $LOG);
1424pb_temp_init();
1425
[354]1426EOF
1427 if ($vtype eq "vm") {
1428 print SCRIPT << 'EOF';
1429# Removes duplicate in .ssh/authorized_keys of our key if needed
1430#
1431my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
1432open(PBFILE,$file1) || die "Unable to open $file1";
1433open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
1434my $count = 0;
1435while (<PBFILE>) {
1436EOF
1437 print SCRIPT << "EOF";
1438 if (/ $key /) {
1439 \$count++;
1440 }
1441print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
1442}
1443close(PBFILE);
1444close(PBOUT);
1445rename("\$file1.new",\$file1);
1446chmod 0600,\$file1;
1447EOF
1448 }
1449 print SCRIPT << 'EOF';
1450
1451# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
1452#
[346]1453my $file="/etc/passwd";
[320]1454open(PBFILE,$file) || die "Unable to open $file";
1455my $found = 0;
1456while (<PBFILE>) {
[346]1457EOF
[353]1458 print SCRIPT << "EOF";
1459 \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
[346]1460EOF
[353]1461 print SCRIPT << 'EOF';
[320]1462}
1463close(PBFILE);
1464
1465if ( $found == 0 ) {
1466 if ( ! -d "/home" ) {
[427]1467 pb_mkdir("/home");
[320]1468 }
[346]1469EOF
[353]1470 print SCRIPT << "EOF";
[427]1471pb_system("groupadd $pbac->{$ENV{'PBPROJ'}}","Adding group $pbac->{$ENV{'PBPROJ'}}");
1472pb_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'}}");
1473}
[320]1474
[354]1475# allow ssh entry to build
1476#
[427]1477mkdir "/home/$pbac->{$ENV{'PBPROJ'}}/.ssh",0700;
[347]1478# Allow those accessing root to access the build account
[427]1479copy("\$ENV{'HOME'}/.ssh/authorized_keys","/home/$pbac->{$ENV{'PBPROJ'}}/.ssh/authorized_keys");
[320]1480chmod 0600,".ssh/authorized_keys";
[427]1481pb_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]1482
[346]1483EOF
[353]1484 print SCRIPT << 'EOF';
[347]1485# No passwd for build account only keys
[320]1486$file="/etc/shadow";
1487open(PBFILE,$file) || die "Unable to open $file";
1488open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1489while (<PBFILE>) {
[346]1490EOF
[353]1491 print SCRIPT << "EOF";
1492 s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
1493 s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
[346]1494EOF
[353]1495 print SCRIPT << 'EOF';
[320]1496 print PBOUT $_;
1497}
1498close(PBFILE);
1499close(PBOUT);
1500rename("$file.new",$file);
1501chmod 0640,$file;
1502
[448]1503# Keep the VM in text mode
1504$file="/etc/inittab";
[450]1505if (-f $file) {
1506 open(PBFILE,$file) || die "Unable to open $file";
1507 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1508 while (<PBFILE>) {
1509 s/^(..):5:initdefault:$/$1:3:initdefault:/;
1510 print PBOUT $_;
1511 }
1512 close(PBFILE);
1513 close(PBOUT);
1514 rename("$file.new",$file);
1515 chmod 0640,$file;
[448]1516}
1517
[320]1518# pb has to be added to portage group on gentoo
1519
[346]1520# Adapt sudoers
1521$file="/etc/sudoers";
1522open(PBFILE,$file) || die "Unable to open $file";
1523open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1524while (<PBFILE>) {
1525EOF
[353]1526 print SCRIPT << "EOF";
1527 next if (/^$pbac->{$ENV{'PBPROJ'}} /);
[346]1528EOF
[353]1529 print SCRIPT << 'EOF';
[346]1530 s/Defaults[ \t]+requiretty//;
1531 print PBOUT $_;
1532}
1533close(PBFILE);
1534EOF
[353]1535 print SCRIPT << "EOF";
1536# This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
1537print PBOUT "$pbac->{$ENV{'PBPROJ'}} ALL=(ALL) NOPASSWD:ALL\n";
[346]1538EOF
[353]1539 print SCRIPT << 'EOF';
[346]1540close(PBOUT);
1541rename("$file.new",$file);
1542chmod 0440,$file;
1543
1544EOF
[353]1545
1546 my $SCRIPT = \*SCRIPT;
1547
1548 pb_install_deps($SCRIPT);
1549
1550 print SCRIPT << 'EOF';
[346]1551# Suse wants sudoers as 640
1552if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
1553 chmod 0640,$file;
1554}
1555
1556# Sync date
[353]1557#system "/usr/sbin/ntpdate ntp.pool.org";
[346]1558
[427]1559pb_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]1560system "pb 2>&1 | head -5";
[357]1561EOF
[353]1562 # Adds pb_distro_init from ProjectBuilder::Distribution
1563 foreach my $d (@INC) {
[405]1564 my @f = ("$d/ProjectBuilder/Base.pm","$d/ProjectBuilder/Distribution.pm");
1565 foreach my $f (@f) {
1566 if (-f "$f") {
1567 open(PBD,"$f") || die "Unable to open $f";
1568 while (<PBD>) {
[427]1569 next if (/^package/);
1570 next if (/^use Exporter/);
1571 next if (/^use ProjectBuilder::/);
1572 next if (/^our /);
[405]1573 print SCRIPT $_;
1574 }
1575 close(PBD);
[353]1576 }
[347]1577 }
1578 }
[353]1579 close(SCRIPT);
1580 chmod 0755,"$pbscript";
1581
[442]1582 # That build script needs to be run as root and force stop of VM at end
[353]1583 $pbaccount = "root";
[442]1584
1585 # Force shutdown of VM exept if it was already launched
1586 my $force = 0;
1587 if ((! $vmexist) && ($vtype eq "vm")) {
1588 $force = 1;
1589 }
1590
1591 pb_script2v($pbscript,$vtype,$force,$v);
[347]1592}
[353]1593return;
[346]1594}
1595
[347]1596sub pb_install_deps {
[346]1597
[348]1598my $SCRIPT = shift;
[346]1599
[348]1600print {$SCRIPT} << 'EOF';
[346]1601# We need to have that pb_distro_init function
[347]1602# Get it from Project-Builder::Distribution
[320]1603my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
1604print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
1605
1606# Get and install pb
[437]1607my $insdm = "rm -rf Date-Manip* ; wget http://search.cpan.org/CPAN/authors/id/S/SB/SBECK/Date-Manip-5.54.tar.gz ; tar xvfz Date-Manip-5.54.tar.gz ; cd Date-Manip* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf Date-Manip*";
[357]1608my $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*";
1609my $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*";
1610my $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]1611my $cmtdm = "Installing Date-Manip perl module";
1612my $cmtmb = "Installing Module-Build perl module";
1613my $cmtfm = "Installing File-MimeInfo perl module";
1614my $cmtfb = "Installing File-Basedir perl module";
1615my $cmtall = "Installing required modules";
[357]1616
[320]1617if ( $ddir eq "fedora" ) {
[427]1618 pb_system("yum clean all","Cleaning yum env");
[346]1619 #system "yum update -y";
[320]1620 my $arch=`uname -m`;
1621 my $opt = "";
1622 chomp($arch);
1623 if ($arch eq "x86_64") {
1624 $opt="--exclude=*.i?86";
1625 }
1626
[427]1627 pb_system("yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker",$cmtall);
[357]1628 if ($dver eq 4) {
[427]1629 pb_system("$insmb","$cmtmb");
1630 pb_system("$insfm","$cmtfm");
1631 pb_system("$insfb","$cmtfb");
[357]1632 }
1633} elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
[358]1634 # Suppose pkg are installed already as no online mirror available
[427]1635 pb_system("rpm -e lsb 2>&1 > /dev/null","Removing lsb package");
1636 pb_system("$insdm","$cmtdm");
1637 pb_system("$insmb","$cmtmb");
1638 pb_system("$insfm","$cmtfm");
1639 pb_system("$insfb","$cmtfb");
[320]1640} elsif ($ddir eq "suse") {
1641 # New OpenSuSE
[427]1642 pb_system("$insmb","$cmtmb");
1643 pb_system("$insfm","$cmtfm");
1644 pb_system("$insfb","$cmtfb");
1645 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]1646} elsif ( $dfam eq "md" ) {
[427]1647 pb_system("urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo","$cmtall");
[357]1648 if (($ddir eq "mandrake") && ($dver eq "10.1")) {
[427]1649 pb_system("$insdm","$cmtdm");
[357]1650 } else {
[427]1651 pb_system("urpmi --auto perl-DateManip","$cmtdm");
[357]1652 }
[320]1653} elsif ( $dfam eq "du" ) {
1654 if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
[346]1655 #system "apt-get update";
[427]1656 pb_system("$insfb","$cmtfb");
1657 pb_system("$insfm","$cmtfm");
1658 pb_system("apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl","$cmtall");
[320]1659 } else {
[427]1660 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]1661 }
1662} elsif ( $dfam eq "gen" ) {
[427]1663 #system "emerge -u system";
1664 pb_system("emerge wget sudo ntp DateManip File-MimeInfo","$cmtall");
[320]1665} else {
1666 print "No pkg to install\n";
1667}
1668EOF
1669}
1670
[347]1671# Return the SSH key file to use
1672# Potentially create it if needed
1673
1674sub pb_ssh_get {
1675
1676my $create = shift || 0; # Do not create keys by default
1677
1678# Check the SSH environment
1679my $keyfile = undef;
1680
1681# We have specific keys by default
1682$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
[348]1683if (!(-e $keyfile) && ($create eq 1)) {
[347]1684 pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
1685}
1686
1687$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
1688$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
1689$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
1690die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
1691return($keyfile);
1692}
1693
1694
[145]1695# Returns the pid of a running VM command using a specific VM file
[142]1696sub pb_check_ps {
1697 my $vmcmd = shift;
1698 my $vmm = shift;
1699 my $vmexist = 0; # FALSE by default
1700
1701 open(PS, "ps auxhww|") || die "Unable to call ps";
1702 while (<PS>) {
1703 next if (! /$vmcmd/);
1704 next if (! /$vmm/);
1705 my ($void1, $void2);
1706 ($void1, $vmexist, $void2) = split(/ +/);
1707 last;
1708 }
1709 return($vmexist);
1710}
1711
1712
[77]1713sub pb_extract_build_files {
[25]1714
1715my $src=shift;
1716my $dir=shift;
[26]1717my $ddir=shift;
[28]1718my @files;
[25]1719
[188]1720if ($src =~ /tar\.gz$/) {
1721 pb_system("tar xfpz $src $dir","Extracting build files");
1722} elsif ($src =~ /tar\.bz2$/) {
1723 pb_system("tar xfpj $src $dir","Extracting build files");
1724} else {
1725 die "Unknown compression algorithm for $src";
1726}
[25]1727opendir(DIR,"$dir") || die "Unable to open directory $dir";
1728foreach my $f (readdir(DIR)) {
1729 next if ($f =~ /^\./);
[26]1730 move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
[315]1731 pb_log(2,"mv $dir/$f $ddir\n");
[28]1732 push @files,"$ddir/$f";
[25]1733}
1734closedir(DIR);
[26]1735# Not enough but still a first cleanup
[74]1736pb_rm_rf("$dir");
[28]1737return(@files);
[25]1738}
1739
[315]1740sub pb_list_bfiles {
1741
1742my $dir = shift;
1743my $pbpkg = shift;
1744my $bfiles = shift;
1745my $pkgfiles = shift;
1746my $supfiles = shift;
1747
1748opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
1749foreach my $f (readdir(BDIR)) {
1750 next if ($f =~ /^\./);
1751 $bfiles->{$f} = "$dir/$f";
[340]1752 $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
[315]1753 if (defined $supfiles->{$pbpkg}) {
1754 $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
1755 }
1756}
1757closedir(BDIR);
1758}
1759
[395]1760
1761#
1762# Return the list of packages we are working on in a non CMS action
1763#
1764sub pb_get_pkg {
1765
1766my @pkgs = ();
1767
1768my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
1769@pkgs = keys %$var;
1770
1771pb_log(0,"Packages: ".join(',',@pkgs)."\n");
1772return(\@pkgs);
1773}
1774
17751;
Note: See TracBrowser for help on using the repository browser.