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

Last change on this file since 1102 was 1102, checked in by Bruno Cornec, 13 years ago
  • Fix sbx2ssh call
  • Improve yum-arch call
  • Property svn:executable set to *
File size: 99.8 KB
Line 
1#!/usr/bin/perl -w
2#
3# Project Builder main application
4#
5# $Id$
6#
7# Copyright B. Cornec 2007
8# Provided under the GPL v2
9
10# Syntax: see at end
11
12use strict 'vars';
13use Getopt::Long qw(:config auto_abbrev no_ignore_case);
14use Data::Dumper;
15use English;
16use File::Basename;
17use File::Copy;
18use File::stat;
19use File::Temp qw(tempdir);
20use File::Find;
21use Time::localtime qw(localtime);
22use POSIX qw(strftime);
23use lib qw (lib);
24use ProjectBuilder::Version;
25use ProjectBuilder::Base;
26use ProjectBuilder::Display;
27use ProjectBuilder::Conf;
28use ProjectBuilder::Distribution;
29use ProjectBuilder::CMS;
30use ProjectBuilder::Env;
31use ProjectBuilder::Filter;
32use ProjectBuilder::Changelog;
33use Mail::Sendmail;
34
35# Global variables
36my %opts; # CLI Options
37my $action; # action to realize
38my $test = "FALSE"; # Not used
39my $pbforce = 0; # Force VE/VM rebuild
40my $pbsnap = 0; # Do not use snapshot mode for VM/VE by default
41my $option = ""; # Not used
42my @pkgs; # list of packages
43my $pbtag; # Global Tag variable
44my $pbver; # Global Version variable
45my $pbscript; # Name of the script
46my %pbver; # per package
47my %pbtag; # per package
48my $pbrev; # Global REVISION variable
49my $pbaccount; # Login to use to connect to the VM
50my $pbport; # Port to use to connect to the VM
51my $newver; # New version to create
52my $iso = undef; # ISO image for the VM to create
53
54my @date = pb_get_date();
55my $pbdate = strftime("%Y-%m-%d", @date);
56
57=pod
58
59=head1 NAME
60
61pb, aka project-builder.org - builds packages for your projects
62
63=head1 DESCRIPTION
64
65pb helps you build various packages directly from your project sources.
66Those sources could be handled by a CMS (Configuration Management System)
67such as Subversion, CVS, Git, Mercurial... or being a simple reference to a compressed tar file.
68It's based on a set of configuration files, a set of provided macros to help
69you keeping build files as generic as possible. For example, a single .spec
70file should be required to generate for all rpm based distributions, even
71if you could also have multiple .spec files if required.
72
73=head1 SYNOPSIS
74
75pb [-vhSq][-r pbroot][-p project][[-s script -a account -P port][-m mach-1[,...]]][-i iso] <action> [<pkg1> ...]
76
77pb [--verbose][--help][--man][--quiet][--snapshot][--revision pbroot][--project project][[--script script --account account --port port][--machine mach-1[,...]]][--iso iso] <action> [<pkg1> ...]
78
79=head1 OPTIONS
80
81=over 4
82
83=item B<-v|--verbose>
84
85Print a brief help message and exits.
86
87=item B<-q|--quiet>
88
89Do not print any output.
90
91=item B<-h|--help>
92
93Print a brief help message and exits.
94
95=item B<-S|--snapshot>
96
97Use the snapshot mode of VMs or VEs
98
99=item B<--man>
100
101Prints the manual page and exits.
102
103=item B<-m|--machine machine1[,machine2,...]>
104
105Name of the Virtual Machines (VM) or Virtual Environments (VE) you want to build on (coma separated).
106All if none precised (or use the env variable PBV).
107
108=item B<-s|--script script>
109
110Name of the script you want to execute on the related VMs or VEs.
111
112=item B<-i|--iso iso_image>
113
114Name of the ISO image of the distribution you want to install on the related VMs.
115
116=item B<-a|--account account>
117
118Name of the account to use to connect on the related VMs.
119
120=item B<-P|--port port_number>
121
122Port number to use to connect on the related VMs.\n";
123
124=item B<-p|--project project_name>
125
126Name of the project you're working on (or use the env variable PBPROJ)
127
128=item B<-r|--revision revision>
129
130Path Name of the project revision under the CMS (or use the env variable PBROOT)
131
132=item B<-V|--version new_version>
133
134New version of the project to create based on the current one.
135
136=back
137
138=head1 ARGUMENTS
139
140<action> can be:
141
142=over 4
143
144=item B<sbx2build>
145
146Create tar files for the project under your CMS.
147Current state of the exported content is taken.
148CMS supported are SVN, SVK, CVS, Git and Mercurial
149parameters are packages to build
150if not using default list
151
152=item B<cms2build>
153
154Create tar files for the project under your CMS.
155Current state of the CMS is taken.
156CMS supported are SVN, SVK, CVS, Git and Mercurial
157parameters are packages to build
158if not using default list
159
160=item B<build2pkg>
161
162Create packages for your running distribution
163
164=item B<cms2pkg>
165
166cms2build + build2pkg
167
168=item B<sbx2pkg>
169
170sbx2build + build2pkg
171
172=item B<build2ssh>
173
174Send the tar files to a SSH host
175
176=item B<sbx2ssh>
177
178sbx2build + build2ssh
179
180=item B<cms2ssh>
181
182cms2build + build2ssh
183
184=item B<pkg2ssh>
185
186Send the packages built to a SSH host
187
188=item B<build2vm>
189
190Create packages in VMs, launching them if needed
191and send those packages to a SSH host once built
192VM type supported are QEMU
193
194=item B<build2ve>
195
196Create packages in VEs, creating it if needed
197and send those packages to a SSH host once built
198
199=item B<sbx2vm>
200
201sbx2build + build2vm
202
203=item B<sbx2ve>
204
205sbx2build + build2ve
206
207=item B<cms2vm>
208
209cms2build + build2vm
210
211=item B<cms2ve>
212
213cms2build + build2ve
214
215=item B<launchvm>
216
217Launch one virtual machine
218
219=item B<launchve>
220
221Launch one virtual environment
222
223=item B<script2vm>
224
225Launch one virtual machine if needed
226and executes a script on it
227
228=item B<script2ve>
229
230Execute a script in a virtual environment
231
232=item B<newvm>
233
234Create a new virtual machine
235
236=item B<newve>
237
238Create a new virtual environment
239
240=item B<setupvm>
241
242Setup a virtual machine for pb usage
243
244=item B<setupve>
245
246Setup a virtual environment for pb usage
247
248=item B<snapvm>
249
250Snapshot a virtual machine for pb usage
251
252=item B<snapve>
253
254Snapshot a virtual environment for pb usage
255
256=item B<test2pkg>
257
258Test a package locally
259
260=item B<test2vm>
261
262Test a package in a virtual machine
263
264=item B<test2ve>
265
266Test a package in a virtual environment
267
268=item B<newver>
269
270Create a new version of the project derived
271from the current one
272
273=item B<newproj>
274
275Create a new project and a template set of
276configuration files under pbconf
277
278=item B<announce>
279
280Announce the availability of the project through various means
281
282=item B<web2ssh>
283
284Deliver the Web site content to the target server using ssh.
285
286=item B<clean>
287
288Purge the build and delivery directories related to the current project
289
290=back
291
292<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).
293
294=head1 WEB SITES
295
296The 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/>.
297
298=head1 USER MAILING LIST
299
300None exists for the moment.
301
302=head1 CONFIGURATION FILES
303
304Each pb user may have a configuration in F<$HOME/.pbrc>. The values in this file may overwrite any other configuration file value.
305
306Here is an example of such a configuration file:
307
308 #
309 # Define for each project the URL of its pbconf repository
310 # No default option allowed here as they need to be all different
311 #
312 # URL of the pbconf content
313 # This is the format of a classical URL with the extension of additional schema such as
314 # svn+ssh, cvs+ssh, ...
315 #
316 pbconfurl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe/pbconf
317
318 # This is normaly defined in the project's configuration file
319 # Url of the project
320 #
321 pburl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe
322
323 # All these URLs needs to be defined here as the are the entry point
324 # for how to build packages for the project
325 #
326 pbconfurl pb = svn+ssh://svn.project-builder.org/mondo/svn/pb/pbconf
327 pbconfurl mondorescue = svn+ssh://svn.project-builder.org/mondo/svn/project-builder/mondorescue/pbconf
328 pbconfurl collectl = svn+ssh://bruno@svn.mondorescue.org/mondo/svn/project-builder/collectl/pbconf
329 pbconfurl netperf = svn+ssh://svn.mondorescue.org/mondo/svn/project-builder/netperf/pbconf
330
331 # Under that dir will take place everything related to pb
332 # If you want to use VMs/chroot/..., then use $ENV{'HOME'} to make it portable
333 # to your VMs/chroot/...
334 # if not defined then /var/cache
335 pbdefdir default = $ENV{'HOME'}/project-builder
336 pbdefdir pb = $ENV{'HOME'}
337 pbdefdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
338 pbdefdir mondorescue = $ENV{'HOME'}/mondo/svn
339
340 # pbconfdir points to the directory where the CMS content of the pbconfurl is checked out
341 # If not defined, pbconfdir is under pbdefdir/pbproj/pbconf
342 pbconfdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs/pbconf
343 pbconfdir mondorescue = $ENV{'HOME'}/mondo/svn/pbconf
344
345 # pbdir points to the directory where the CMS content of the pburl is checked out
346 # If not defined, pbdir is under pbdefdir/pbproj
347 # Only defined if we have access to the dev of the project
348 pbdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
349 pbdir mondorescue = $ENV{'HOME'}/mondo/svn
350
351 # -daemonize doesn't work with qemu 0.8.2
352 vmopt default = -m 384
353
354=head1 AUTHORS
355
356The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
357
358=head1 COPYRIGHT
359
360Project-Builder.org is distributed under the GPL v2.0 license
361described in the file C<COPYING> included with the distribution.
362
363=cut
364
365# ---------------------------------------------------------------------------
366
367my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
368my $appname = "pb";
369
370# Initialize the syntax string
371
372pb_syntax_init("$appname (aka project-builder.org) Version $projectbuilderver-$projectbuilderrev\n");
373
374GetOptions("help|?|h" => \$opts{'h'},
375 "man" => \$opts{'man'},
376 "verbose|v+" => \$opts{'v'},
377 "snapshot|S" => \$opts{'S'},
378 "quiet|q" => \$opts{'q'},
379 "log-files|l=s" => \$opts{'l'},
380 "force|f" => \$opts{'f'},
381 "account|a=s" => \$opts{'a'},
382 "revision|r=s" => \$opts{'r'},
383 "script|s=s" => \$opts{'s'},
384 "machines|mock|m=s" => \$opts{'m'},
385 "port|P=i" => \$opts{'P'},
386 "project|p=s" => \$opts{'p'},
387 "iso|i=s" => \$opts{'i'},
388 "version|V=s" => \$opts{'V'},
389) || pb_syntax(-1,0);
390
391if (defined $opts{'h'}) {
392 pb_syntax(0,1);
393}
394if (defined $opts{'man'}) {
395 pb_syntax(0,2);
396}
397if (defined $opts{'v'}) {
398 $pbdebug = $opts{'v'};
399}
400if (defined $opts{'f'}) {
401 $pbforce=1;
402}
403if (defined $opts{'q'}) {
404 $pbdebug=-1;
405}
406if (defined $opts{'S'}) {
407 $pbsnap=1;
408}
409if (defined $opts{'l'}) {
410 open(pbLOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
411 $pbLOG = \*pbLOG;
412 $pbdebug = 0 if ($pbdebug == -1);
413 }
414pb_log_init($pbdebug, $pbLOG);
415pb_display_init("text","");
416
417# Handle root of the project if defined
418if (defined $opts{'r'}) {
419 $ENV{'PBROOTDIR'} = $opts{'r'};
420}
421# Handle virtual machines if any
422if (defined $opts{'m'}) {
423 $ENV{'PBV'} = $opts{'m'};
424}
425if (defined $opts{'s'}) {
426 $pbscript = $opts{'s'};
427}
428if (defined $opts{'a'}) {
429 $pbaccount = $opts{'a'};
430 die "option -a requires a -s script option" if (not defined $pbscript);
431}
432if (defined $opts{'P'}) {
433 $pbport = $opts{'P'};
434}
435if (defined $opts{'V'}) {
436 $newver = $opts{'V'};
437}
438if (defined $opts{'i'}) {
439 $iso = $opts{'i'};
440}
441
442# Get Action
443$action = shift @ARGV;
444die pb_syntax(-1,1) if (not defined $action);
445
446my ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir);
447my $pbinit = undef;
448$pbinit = 1 if ($action =~ /^newproj$/);
449
450# Handles project name if any
451# And get global params
452($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) = pb_env_init($opts{'p'},$pbinit,$action);
453
454#
455# Check for command requirements
456#
457my ($req,$opt) = pb_conf_get_if("oscmd","oscmdopt");
458my ($req2,$opt2) = (undef,undef);
459$req2 = $req->{$appname} if (defined $req);
460$opt2 = $opt->{$appname} if (defined $opt);
461pb_check_requirements($req2,$opt2);
462
463pb_log(0,"Project: $ENV{'PBPROJ'}\n");
464pb_log(0,"Action: $action\n");
465
466# Act depending on action
467if ($action =~ /^cms2build$/) {
468 pb_cms2build("CMS");
469} elsif ($action =~ /^sbx2build$/) {
470 pb_cms2build("SandBox");
471} elsif ($action =~ /^build2pkg$/) {
472 pb_build2pkg();
473} elsif ($action =~ /^cms2pkg$/) {
474 pb_cms2build("CMS");
475 pb_build2pkg();
476} elsif ($action =~ /^sbx2pkg$/) {
477 pb_cms2build("SandBox");
478 pb_build2pkg();
479} elsif ($action =~ /^build2ssh$/) {
480 pb_build2ssh();
481} elsif ($action =~ /^cms2ssh$/) {
482 pb_cms2build("CMS");
483 pb_build2ssh();
484} elsif ($action =~ /^sbx2ssh$/) {
485 pb_cms2build("SandBox");
486 pb_build2ssh();
487} elsif ($action =~ /^pkg2ssh$/) {
488 pb_pkg2ssh();
489} elsif ($action =~ /^build2ve$/) {
490 pb_build2v("ve","build");
491} elsif ($action =~ /^build2vm$/) {
492 pb_build2v("vm","build");
493} elsif ($action =~ /^cms2ve$/) {
494 pb_cms2build("CMS");
495 pb_build2v("ve","build");
496} elsif ($action =~ /^sbx2ve$/) {
497 pb_cms2build("SandBox");
498 pb_build2v("ve","build");
499} elsif ($action =~ /^cms2vm$/) {
500 pb_cms2build("CMS");
501 pb_build2v("vm","build");
502} elsif ($action =~ /^sbx2vm$/) {
503 pb_cms2build("SandBox");
504 pb_build2v("vm","build");
505} elsif ($action =~ /^launchvm$/) {
506 pb_launchv("vm",$ENV{'PBV'},0);
507} elsif ($action =~ /^launchve$/) {
508 pb_launchv("ve",$ENV{'PBV'},0);
509} elsif ($action =~ /^script2vm$/) {
510 pb_script2v($pbscript,"vm");
511} elsif ($action =~ /^script2ve$/) {
512 pb_script2v($pbscript,"ve");
513} elsif ($action =~ /^newver$/) {
514 pb_newver();
515} elsif ($action =~ /^newve$/) {
516 pb_launchv("ve",$ENV{'PBV'},1);
517} elsif ($action =~ /^newvm$/) {
518 pb_launchv("vm",$ENV{'PBV'},1);
519 pb_log(0, "Please ensure that sshd is running in your VM by default\n");
520 pb_log(0, "and that it allows remote root login (PermitRootLogin yes in /etc/ssh/sshd_config)\n");
521 pb_log(0, "Also ensure that network is up, firewalling correctly configured, and perl and scp/ssh installed\n");
522 pb_log(0, "You should then be able to login with ssh -p VMPORT root\@localhost (if VM started with pb)\n");
523} elsif ($action =~ /^setupve$/) {
524 pb_setup2v("ve");
525} elsif ($action =~ /^setupvm$/) {
526 pb_setup2v("vm");
527} elsif ($action =~ /^snapve$/) {
528 pb_snap2v("ve");
529} elsif ($action =~ /^snapvm$/) {
530 pb_snap2v("vm");
531} elsif ($action =~ /^test2pkg$/) {
532 pb_test2pkg();
533} elsif ($action =~ /^test2ve$/) {
534 pb_build2v("ve","test");
535} elsif ($action =~ /^test2vm$/) {
536 pb_build2v("vm","test");
537} elsif ($action =~ /^newproj$/) {
538 # Nothing to do - already done in pb_env_init
539} elsif ($action =~ /^clean$/) {
540 pb_clean();
541} elsif ($action =~ /^announce$/) {
542 # For announce only. Require avoids the systematic load of these modules
543 require DBI;
544 require DBD::SQLite;
545
546 pb_announce();
547} elsif ($action =~ /^web2ssh$/) {
548 require DBI;
549 require DBD::SQLite;
550
551 pb_cms2build("Web");
552 pb_send2target("Web");
553} else {
554 pb_log(0,"\'$action\' is not available\n");
555 pb_syntax(-2,1);
556}
557
558sub pb_cms2build {
559
560 my $param = shift || undef;
561
562 my $pkg;
563 my @pkgs;
564 my $webdir;
565
566 my %pkgs;
567 my %pb; # Structure to store conf info
568
569 die "pb_cms2build requires a parameter: Web, SandBox or CMS" if (not defined $param);
570
571 # If Website, then pkg is only the website
572 if ($param eq "Web") {
573 ($webdir) = pb_conf_get("webdir");
574 pb_log(2,"webdir: ".Dumper($webdir)."\n");
575 $pkgs[0] = $webdir->{$ENV{'PBPROJ'}};
576 $extpkgdir = $webdir;
577 pb_log(0,"Package: $pkgs[0]\n");
578 } else {
579 $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
580 @pkgs = @$pkg;
581 }
582
583 my ($scheme, $uri) = pb_cms_init($pbinit,$param);
584
585 # We need 2 lines here
586 my ($pkgv, $pkgt, $testver) = pb_conf_get_if("pkgver","pkgtag","testver");
587 my @pt = pb_conf_get_if("vmlist","velist");
588
589 # declare packager and repo for filtering
590 # TODO: Is pbrepo needed so early in the process ?
591 my ($tmp1, $tmp2) = pb_conf_get("pbpackager","pbrepo");
592 $ENV{'PBPACKAGER'} = $tmp1->{$ENV{'PBPROJ'}};
593 $ENV{'PBREPO'} = $tmp2->{$ENV{'PBPROJ'}};
594
595 foreach my $pbpkg (@pkgs) {
596 $ENV{'PBPKG'} = $pbpkg;
597
598 if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
599 $pbver = $pkgv->{$pbpkg};
600 } else {
601 $pbver = $ENV{'PBPROJVER'};
602 }
603 # If it's a test version, then tag == 0.date
604 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
605 $pbtag = "0.".strftime("%Y%m%d%H%M%S", @date);
606 $ENV{'PBPROJTAG'} = $pbtag;
607 } elsif ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
608 $pbtag = $pkgt->{$pbpkg};
609 } else {
610 $pbtag = $ENV{'PBPROJTAG'};
611 }
612
613 $pbrev = $ENV{'PBREVISION'};
614 pb_log(0,"\n");
615 pb_log(0,"Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n");
616 die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
617
618 # Clean up dest if necessary. The export will recreate it
619 my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver";
620 pb_rm_rf($dest) if (-d $dest);
621
622 # Export CMS tree for the concerned package to dest
623 # And generate some additional files
624 $OUTPUT_AUTOFLUSH=1;
625
626 # computes in which dir we have to work
627 my $dir = $defpkgdir->{$pbpkg};
628 $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
629 $dir = $webdir->{$ENV{'PBPROJ'}} if ($param eq "Web");
630 pb_log(2,"def:".Dumper($defpkgdir)." ext: ".Dumper($extpkgdir)." \n");
631
632 # Exporting content from CMS
633 my $sourcedir = undef;
634 my $sourceuri = $uri;
635 if ($param eq "SandBox") {
636 # Point to the local instance
637 $sourcedir = "$ENV{'PBDIR'}/$dir";
638 } else {
639 # Get it from a subdir of the URI with same version as localy but different root
640 $sourceuri = "$ENV{'PBDIR'}/$dir";
641 $sourceuri =~ s|^$ENV{'PBPROJDIR'}/|$uri|;
642 }
643 my $preserve = pb_cms_export($sourceuri,$sourcedir,$dest);
644
645 # Generated fake content for test versions to speed up stuff
646 my $chglog;
647
648 # Get project info on authors and log file
649 $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
650 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
651 $chglog = undef if (! -f $chglog);
652
653 my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
654 $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
655 $authors = "/dev/null" if (! -f $authors);
656
657 # Extract cms log history and store it
658 if ((defined $chglog) && (! -f "$dest/NEWS")) {
659 pb_log(2,"Generating NEWS file from $chglog\n");
660 copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
661 }
662 pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors,$testver);
663
664 my %build;
665 # We want to at least build for the underlying distro
666 my ($ddir, $dver, $dfam, $dtype, $dos, $pbsuf, $pbupd, $arch) = pb_distro_init();
667 my $tmpl = "$ddir-$dver-$arch,";
668 my %patches;
669
670 # Get list of distributions for which we need to generate build files
671 if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
672 $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
673 }
674 if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
675 # The 2 lists needs to be grouped with a ',' separating them
676 if ($tmpl ne "") {
677 $tmpl .= ",";
678 }
679 $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
680 }
681
682 # Setup %pb structure to allow filtering later on, on files using that structure
683 $pb{'tag'} = $pbtag;
684 $pb{'rev'} = $pbrev;
685 $pb{'ver'} = $pbver;
686 $pb{'pkg'} = $pbpkg;
687 $pb{'date'} = $pbdate;
688 $pb{'defpkgdir'} = $defpkgdir;
689 $pb{'extpkgdir'} = $extpkgdir;
690 $pb{'chglog'} = $chglog;
691 $pb{'packager'} = $ENV{'PBPACKAGER'};
692 $pb{'proj'} = $ENV{'PBPROJ'};
693 $pb{'repo'} = $ENV{'PBREPO'};
694 $pb{'patches'} = \%patches;
695 pb_log(2,"DEBUG: pb: ".Dumper(%pb)."\n");
696
697 # Do not do that for website
698 if ($param ne "Web") {
699 pb_log(0,"Build files are being generated for ...\n");
700 my %virt;
701 # De-duplicate similar VM and VE
702 foreach my $d (split(/,/,$tmpl)) {
703 # skip ill-formatted vms (name-ver-arch)
704 next if ($d !~ /-/);
705 $virt{$d} = $d;
706 }
707
708 foreach my $d (keys %virt) {
709 my ($name,$ver,$arch) = split(/-/,$d);
710 pb_log(0,"Bad format for $d") if ((not defined $name) || (not defined $ver) || (not defined $arch)) ;
711 chomp($arch);
712 my ($ddir, $dver, $dfam);
713 ($ddir, $dver, $dfam, $pb{'dtype'}, $pb{'os'}, $pb{'suf'}, $pb{'upd'}, $pb{'arch'}) = pb_distro_init($name,$ver,$arch);
714 pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $pb{'dtype'}, $pb{'suf'})."\n");
715 pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
716
717 # We need to compute the real name of the package
718 my $pbrealpkg = pb_cms_get_real_pkg($pbpkg,$pb{'dtype'});
719 $pb{'realpkg'} = $pbrealpkg;
720 pb_log(1,"Virtual package $pbpkg has a real package name of $pbrealpkg on $ddir-$dver\n") if ($pbrealpkg ne $pbpkg);
721
722 # Filter build files from the less precise up to the most with overloading
723 # Filter all files found, keeping the name, and generating in dest
724
725 # Find all build files first relatively to PBROOTDIR
726 # Find also all specific files referenced in the .pb conf file
727 my %bfiles = ();
728 my %pkgfiles = ();
729 $build{"$ddir-$dver-$arch"} = "yes";
730
731 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$pb{'dtype'}") {
732 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$pb{'dtype'}",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
733 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dfam") {
734 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
735 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir") {
736 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
737 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver") {
738 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
739 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver-$arch") {
740 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver-$arch",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
741 } else {
742 $build{"$ddir-$dver-$arch"} = "no";
743 next;
744 }
745 pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
746
747 # Get all filters to apply
748 my $ptr = pb_get_filters($pbpkg, $pb{'dtype'}, $dfam, $ddir, $dver);
749
750 # Prepare local patches for this distro - They are always applied first - May be a problem one day
751 foreach my $p (sort(<$ENV{'PBROOTDIR'}/$pbpkg/pbpatch/*>)) {
752 $patches{"$ddir-$dver-$arch"} .= "," if ((defined $patches{"$ddir-$dver-$arch"}) and ($p =~ /\.all$/));
753 $patches{"$ddir-$dver-$arch"} .= "file://$p" if ($p =~ /\.all$/);
754 $patches{"$ddir-$dver-$arch"} .= "," if ((defined $patches{"$ddir-$dver-$arch"}) and ($p =~ /\.$pb{'dtype'}$/));
755 $patches{"$ddir-$dver-$arch"} .= "file://$p" if ($p =~ /\.$pb{'dtype'}$/);
756 $patches{"$ddir-$dver-$arch"} .= "," if ((defined $patches{"$ddir-$dver-$arch"}) and ($p =~ /\.$dfam$/));
757 $patches{"$ddir-$dver-$arch"} .= "file://$p" if ($p =~ /\.$dfam$/);
758 $patches{"$ddir-$dver-$arch"} .= "," if ((defined $patches{"$ddir-$dver-$arch"}) and ($p =~ /\.$ddir$/));
759 $patches{"$ddir-$dver-$arch"} .= "file://$p" if ($p =~ /\.$ddir$/);
760 $patches{"$ddir-$dver-$arch"} .= "," if ((defined $patches{"$ddir-$dver-$arch"}) and ($p =~ /\.$ddir-$dver$/));
761 $patches{"$ddir-$dver-$arch"} .= "file://$p" if ($p =~ /\.$ddir-$dver$/);
762 $patches{"$ddir-$dver-$arch"} .= "," if ((defined $patches{"$ddir-$dver-$arch"}) and ($p =~ /\.$ddir-$dver-$arch$/));
763 $patches{"$ddir-$dver-$arch"} .= "file://$p" if ($p =~ /\.$ddir-$dver-$arch$/);
764 }
765
766 # Prepare also remote patches to be included - Applied after the local ones
767 foreach my $p ("all","$pb{'dtype'}","$dfam","$ddir","$ddir-$dver","$ddir-$dver-$arch") {
768 my $f = "$ENV{'PBROOTDIR'}/$pbpkg/pbextpatch.$p";
769 next if (not -f $f);
770 if (not open(PATCH,$f)) {
771 pb_display("Unable to open existing external patch file content $f\n");
772 next;
773 }
774 while (<PATCH>) {
775 chomp();
776 $patches{"$ddir-$dver-$arch"} .= "," if (defined $patches{"$ddir-$dver-$arch"});
777 $patches{"$ddir-$dver-$arch"} .= "$_";
778 }
779 close(PATCH);
780 }
781 pb_log(2,"DEBUG: pb->patches: ".Dumper($pb{'patches'})."\n");
782
783 # Apply now all the filters on all the files concerned
784 # destination dir depends on the type of file
785 if (defined $ptr) {
786 # For patch support
787 $pb{'tuple'} = "$ddir-$dver-$arch";
788 foreach my $f (values %bfiles,values %pkgfiles) {
789 pb_filter_file("$ENV{'PBROOTDIR'}/$f",$ptr,"$dest/pbconf/$ddir-$dver-$arch/".basename($f),\%pb);
790 }
791 }
792 }
793 my @found;
794 my @notfound;
795 foreach my $b (keys %build) {
796 push @found,$b if ($build{$b} =~ /yes/);
797 push @notfound,$b if ($build{$b} =~ /no/);
798 }
799 pb_log(0," ... ".join(',',sort(@found))."\n");
800 pb_log(0,"No Build files found for ".join(',',sort(@notfound))."\n") if (@notfound);
801 pb_log(2,"DEBUG: patches: ".Dumper(%patches)."\n");
802 }
803
804 # Get the generic filter (all.pbf) and
805 # apply those to the non-build files including those
806 # generated by pbinit if applicable
807
808 # Get only all.pbf filter
809 my $ptr = pb_get_filters($pbpkg);
810
811 my $liste ="";
812 if (defined $filteredfiles->{$pbpkg}) {
813 foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
814 pb_filter_file_inplace($ptr,"$dest/$f",\%pb);
815 $liste = "$f $liste";
816 }
817 }
818 pb_log(2,"Files ".$liste."have been filtered\n");
819
820 # Do not do that for website
821 if ($param ne "Web") {
822 my %tmp;
823 my $warnflag = 0;
824 # Filter potential patches (local + remote)
825 pb_log(0,"Delivering and compressing patches ");
826 foreach my $v (keys %patches) {
827 pb_mkdir_p("$dest/pbconf/$v/pbpatch");
828 foreach my $pf (split(/,/,$patches{$v})) {
829 my $pp = basename($pf);
830 if ($param eq "SandBox") {
831 $warnflag = 1;
832 }
833 pb_cms_export($pf,undef,"$dest/pbconf/$v/pbpatch");
834 pb_filter_file_inplace($ptr,"$dest/pbconf/$v/pbpatch/$pp",\%pb);
835 pb_system("gzip -9f $dest/pbconf/$v/pbpatch/$pp","","quiet");
836 $tmp{$pf} = "";
837 }
838 }
839 foreach my $v (keys %tmp) {
840 pb_log(0,"$v ");
841 }
842 pb_log(0,"\n");
843 pb_log(0,"WARNING: Patches are always taken from repository not local export\n") if ($warnflag == 1);
844 } else {
845 # Instead call News generation
846 pb_web_news2html($dest);
847 # And create an empty pbconf
848 pb_mkdir_p("$dest/pbconf");
849 # And prepare the pbscript to execute remotely
850 open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
851 print SCRIPT "#!/bin/bash\n";
852 print SCRIPT "#set -x\n";
853 print SCRIPT "echo ... Extracting Website content\n";
854 print SCRIPT "find . -type f | grep -Ev '^./$pbpkg-$pbver.tar.gz|^./pbscript' | xargs rm -f non-existent\n";
855 print SCRIPT "find * -type d -depth | xargs rmdir 2> /dev/null \n";
856 print SCRIPT "tar xfz $pbpkg-$pbver.tar.gz\n";
857 print SCRIPT "mv $pbpkg-$pbver/* .\n";
858 print SCRIPT "rm -f $pbpkg-$pbver.tar.gz\n";
859 print SCRIPT "rmdir $pbpkg-$pbver\n";
860 close(SCRIPT);
861 }
862
863 # Prepare the dest directory for archive
864 if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
865 pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",\%pb);
866 chmod 0755,"$ENV{'PBTMP'}/pbinit";
867 pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit","verbose");
868 }
869
870 # Do we have additional script to run to prepare the environement for the project ?
871 # Then include it in the pbconf delivery
872 foreach my $pbvf (<$ENV{'PBROOTDIR'}/pbv*.pre>,<$ENV{'PBROOTDIR'}/pbv*.post>, <$ENV{'PBROOTDIR'}/pbtest*>) {
873 if (-x "$pbvf") {
874 my $target = "$ENV{'PBDESTDIR'}/".basename($pbvf);
875 pb_filter_file("$pbvf",$ptr,$target,\%pb);
876 chmod 0755,"$target";
877 }
878 }
879
880 # Archive dest dir
881 chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
882 if (defined $preserve) {
883 # In that case we want to preserve the original tar file for checksum purposes
884 # The one created is btw equivalent in that case to this one
885 # Maybe check basename of both to be sure they are the same ?
886 pb_log(0,"Preserving original tar file ");
887 move("$preserve","$pbpkg-$pbver.tar.gz");
888 } else {
889 # Possibility to look at PBSRC to guess more the filename
890 pb_system("tar cfz $pbpkg-$pbver.tar.gz --exclude=$pbpkg-$pbver/pbconf $pbpkg-$pbver","Creating $pbpkg tar files compressed");
891 }
892 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
893 pb_system("tar cfz $pbpkg-$pbver.pbconf.tar.gz $pbpkg-$pbver/pbconf","Creating pbconf tar files compressed");
894 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.pbconf.tar.gz\n");
895
896 # Keep track of version-tag per pkg
897 $pkgs{$pbpkg} = "$pbver-$pbtag";
898
899 # Final cleanup
900 pb_rm_rf($dest) if (-d $dest);
901 }
902
903 # Keep track of per package version
904 pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
905 open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
906 foreach my $pbpkg (keys %pkgs) {
907 print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
908 }
909 close(PKG);
910
911 # Keep track of what is generated by default
912 # We need to store the dir and info on version-tag
913 # Base our content on the existing .pb file
914 copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
915 open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
916 print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
917 print LAST "projver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
918 print LAST "projtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
919 print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
920 close(LAST);
921}
922
923sub pb_test2pkg {
924 # Get the running distro to test on
925 my ($ddir, $dver, $dfam, $dtype, $dos, $pbsuf, $pbupd, $arch) = pb_distro_init();
926 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf, $pbupd, $arch))."\n");
927
928 # Get list of packages to test
929 # Get content saved in cms2build
930 my $ptr = pb_get_pkg();
931 @pkgs = @$ptr;
932
933 # Additional potential repo
934 pb_distro_setuprepo($ddir,$dver,$arch,$dtype);
935 foreach my $pbpkg (@pkgs) {
936 # We need to install the package to test, and deps brought with it
937 pb_distro_installdeps(undef,$dtype,$pbupd,$pbpkg);
938 pb_system("$ENV{'PBDESTDIR'}/pbtest","Launching test for $pbpkg","verbose");
939 }
940}
941
942sub pb_build2pkg {
943
944 # Get the running distro to build on
945 my ($ddir, $dver, $dfam, $dtype, $dos, $pbsuf, $pbupd, $arch) = pb_distro_init();
946 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf, $pbupd, $arch))."\n");
947
948 # Get list of packages to build
949 my $ptr = pb_get_pkg();
950 @pkgs = @$ptr;
951
952 # Get content saved in cms2build
953 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
954 $pkg = { } if (not defined $pkg);
955
956 chdir "$ENV{'PBBUILDDIR'}";
957 my $made = ""; # pkgs made during build
958 foreach my $pbpkg (@pkgs) {
959 my $vertag = $pkg->{$pbpkg};
960 # get the version of the current package - maybe different
961 ($pbver,$pbtag) = split(/-/,$vertag);
962
963 my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
964 my $src2="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.pbconf.tar.gz";
965 pb_log(2,"Source file: $src\n");
966 pb_log(2,"Pbconf file: $src2\n");
967
968 pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
969 if ($dtype eq "rpm") {
970 foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
971 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
972 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";
973 }
974 }
975
976 # Remove in case a previous link/file was there
977 unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
978 symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
979 # We need to first extract the spec file
980 my @specfile = pb_extract_build_files($src2,"$pbpkg-$pbver/pbconf/$ddir-$dver-$arch/","$ENV{'PBBUILDDIR'}/SPECS","spec");
981
982 # We need to handle potential patches to upstream sources
983 pb_extract_build_files($src2,"$pbpkg-$pbver/pbconf/$ddir-$dver-$arch/pbpatch/","$ENV{'PBBUILDDIR'}/SOURCES","patch");
984
985 pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
986 # set LANGUAGE to check for correct log messages
987 $ENV{'LANGUAGE'}="C";
988 # Older Redhat use _target_platform in %configure incorrectly
989 my $specialdef = "";
990 if (($ddir eq "redhat") || (($ddir eq "rhel") && ($dver eq "2.1"))) {
991 $specialdef = "--define \'_target_platform \"\"\'";
992 }
993
994 # If needed we may add repository to the build env
995 pb_distro_setuprepo($ddir,$dver,$arch,$dtype);
996 foreach my $f (@specfile) {
997 if ($f =~ /\.spec$/) {
998 pb_distro_installdeps($f,$dtype,$pbupd);
999 pb_system("rpmbuild $specialdef --define \"packager $ENV{'PBPACKAGER'}\" --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}","verbose");
1000 last;
1001 }
1002 }
1003 # Get the name of the generated packages
1004 open(LOG,"$ENV{'PBTMP'}/system.log") || die "Unable to open $ENV{'PBTMP'}/system.log";
1005 while (<LOG>) {
1006 chomp($_);
1007 next if ($_ !~ /^Wrote:/);
1008 s|.*/([S]*RPMS.*)|$1|;
1009 $made .=" $_";
1010 }
1011 close(LOG);
1012
1013 } elsif ($dtype eq "deb") {
1014 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
1015 pb_system("tar xfz $src","Extracting sources");
1016 pb_system("tar xfz $src2","Extracting pbconf");
1017
1018 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
1019 pb_rm_rf("debian");
1020 symlink "pbconf/$ddir-$dver-$arch","debian" || die "Unable to symlink to pbconf/$ddir-$dver-$arch";
1021 chmod 0755,"debian/rules";
1022
1023 pb_distro_setuprepo($ddir,$dver,$arch,$dtype);
1024 pb_distro_installdeps("debian/control",$dtype,$pbupd);
1025 pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package","verbose");
1026 # Get the name of the generated packages
1027 open(LOG,"$ENV{'PBTMP'}/system.log") || die "Unable to open $ENV{'PBTMP'}/system.log";
1028 while (<LOG>) {
1029 chomp();
1030 my $tmp = $_;
1031 next if ($tmp !~ /^dpkg-deb.*:/);
1032 $tmp =~ s|.*../(.*)_(.*).deb.*|$1|;
1033 $made="$made $tmp.dsc $tmp.tar.gz $tmp"."_*.deb $tmp"."_*.changes";
1034 }
1035 close(LOG);
1036 } elsif ($dtype eq "ebuild") {
1037 my @ebuildfile;
1038 # For gentoo we need to take pb as subsystem name
1039 # We put every apps here under sys-apps. hope it's correct
1040 # We use pb's home dir in order to have a single OVERLAY line
1041 my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
1042 pb_mkdir_p($tmpd) if (! -d "$tmpd");
1043 pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
1044
1045 # We need to first extract the ebuild file
1046 @ebuildfile = pb_extract_build_files($src2,"$pbpkg-$pbver/pbconf/$ddir-$dver-$arch/","$tmpd","ebuild");
1047
1048 # Prepare the build env for gentoo
1049 my $found = 0;
1050 my $pbbd = $ENV{'HOME'};
1051 $pbbd =~ s|/|\\/|g;
1052 if (-r "/etc/make.conf") {
1053 open(MAKE,"/etc/make.conf");
1054 while (<MAKE>) {
1055 $found = 1 if (/$pbbd\/portage/);
1056 }
1057 close(MAKE);
1058 }
1059 if ($found == 0) {
1060 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
1061 }
1062 #$found = 0;
1063 #if (-r "/etc/portage/package.keywords") {
1064 #open(KEYW,"/etc/portage/package.keywords");
1065 #while (<KEYW>) {
1066 #$found = 1 if (/portage\/pb/);
1067 #}
1068 #close(KEYW);
1069 #}
1070 #if ($found == 0) {
1071 #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
1072 #}
1073
1074 # Build
1075 foreach my $f (@ebuildfile) {
1076 if ($f =~ /\.ebuild$/) {
1077 pb_distro_installdeps($f,$dtype,$pbupd);
1078 move($f,"$tmpd/$pbpkg-$pbver.ebuild");
1079 pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package","verbose");
1080 # Now move it where pb expects it
1081 pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
1082 move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver-r$pbtag.ebuild");
1083 }
1084 }
1085
1086 $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver-r$pbtag.ebuild";
1087 } elsif ($dtype eq "tgz") {
1088 # Slackware family
1089 $made="$made $pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
1090
1091 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
1092 pb_system("tar xfz $src","Extracting sources");
1093 pb_system("tar xfz $src2","Extracting pbconf");
1094 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
1095 symlink "pbconf/$ddir-$dver-$arch","install" || die "Unable to symlink to pbconf/$ddir-$dver-$arch";
1096 if (-x "install/pbslack") {
1097 pb_distro_installdeps("./install/pbslack",$dtype,$pbupd);
1098 pb_system("./install/pbslack","Building software");
1099 pb_system("sudo /sbin/makepkg -p -l y -c y $pbpkg","Packaging $pbpkg","verbose");
1100 }
1101 } elsif ($dtype eq "pkg") {
1102 # Solaris
1103 $made="$made $pbpkg-$pbver-$pbtag.pkg.gz";
1104 my $pkgdestdir="$ENV{'PBBUILDDIR'}/install";
1105
1106 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
1107 # Will host resulting packages
1108 pb_mkdir_p("$dtype");
1109 pb_mkdir_p("$pkgdestdir/delivery");
1110 pb_system("tar xfz $src","Extracting sources under $ENV{'PBBUILDDIR'}");
1111 pb_system("tar xfz $src2","Extracting pbconf under $ENV{'PBBUILDDIR'}");
1112 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
1113 if (-f "pbconf/$ddir-$dver-$arch/pbbuild") {
1114 chmod 0755,"pbconf/$ddir-$dver-$arch/pbbuild";
1115 # pkginfo file is mandatory
1116 die "Unable to find pkginfo file in pbconf/$ddir-$dver-$arch" if (! -f "pbconf/$ddir-$dver-$arch/pkginfo");
1117 # Build
1118 pb_system("pbconf/$ddir-$dver-$arch/pbbuild $pkgdestdir/delivery","Building software and installing under $pkgdestdir/delivery");
1119 # Copy complementary files
1120 if (-f "pbconf/$ddir-$dver-$arch/prototype") {
1121 copy("pbconf/$ddir-$dver-$arch/prototype", $pkgdestdir)
1122 } else {
1123 # No prototype provided, calculating it
1124 open(PROTO,"> $pkgdestdir/prototype") || die "Unable to create prototype file";
1125 print PROTO "i pkginfo\n";
1126 print PROTO "i depend\n" if (-f "pbconf/$ddir-$dver-$arch/depend");
1127 $ENV{'PBSOLDESTDIR'} = "$pkgdestdir/delivery";
1128 find(\&create_solaris_prototype, "$pkgdestdir/delivery");
1129 }
1130 copy("pbconf/$ddir-$dver-$arch/depend", $pkgdestdir) if (-f "pbconf/$ddir-$dver-$arch/depend");
1131 copy("pbconf/$ddir-$dver-$arch/pkginfo", $pkgdestdir);
1132 pb_system("cd $pkgdestdir/delivery ; pkgmk -o -f ../prototype -r $pkgdestdir/delivery -d $ENV{'PBBUILDDIR'}/$dtype","Packaging $pbpkg","verbose");
1133 pb_system("cd $ENV{'PBBUILDDIR'}/$dtype ; echo \"\" | pkgtrans -o -n -s $ENV{'PBBUILDDIR'}/$dtype $ENV{'PBBUILDDIR'}/$pbpkg-$pbver-$pbtag.pkg all","Transforming $pbpkg","verbose");
1134 pb_system("cd $ENV{'PBBUILDDIR'} ; gzip -9f $pbpkg-$pbver-$pbtag.pkg","Compressing $pbpkg-$pbver-$pbtag.pkg","verbose");
1135 } else {
1136 pb_log(0,"No pbconf/$ddir-$dver-$arch/pbbuild file found for $pbpkg-$pbver in \n");
1137 }
1138 chdir ".." || die "Unable to chdir to parent dir";
1139 pb_system("rm -rf $pbpkg-$pbver $ENV{'PBBUILDDIR'}/$dtype $pkgdestdir", "Cleanup");
1140 } else {
1141 die "Unknown dtype format $dtype";
1142 }
1143 }
1144 # Packages check if needed
1145 if ($dtype eq "rpm") {
1146 if (-f "/usr/bin/rpmlint") {
1147 pb_system("rpmlint $made","Checking validity of rpms with rpmlint","verbose");
1148 }
1149 my $rpms ="";
1150 my $srpms ="";
1151 foreach my $f (split(/ /,$made)) {
1152 $rpms .= "$ENV{'PBBUILDDIR'}/$f " if ($f =~ /^RPMS\//);
1153 $srpms .= "$ENV{'PBBUILDDIR'}/$f " if ($f =~ /^SRPMS\//);
1154 }
1155 pb_log(0,"SRPM packages generated: $srpms\n");
1156 pb_log(0,"RPM packages generated: $rpms\n");
1157 } elsif ($dtype eq "deb") {
1158 my $made2 = "";
1159 foreach my $f (split(/ /,$made)) {
1160 $made2 .= "../$f " if ($f =~ /\.changes$/);
1161 }
1162 if (-f "/usr/bin/lintian") {
1163 pb_system("lintian $made2","Checking validity of debs with lintian","verbose");
1164 } else {
1165 pb_log(0,"deb packages generated: $made2\n");
1166 }
1167 } else {
1168 pb_log(0,"No check done for $dtype yet\n");
1169 pb_log(0,"Packages generated: $made\n");
1170 }
1171
1172 # Keep track of what is generated so that we can get them back from VMs
1173 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
1174 print KEEP "$made\n";
1175 close(KEEP);
1176}
1177
1178sub create_solaris_prototype {
1179
1180 my $uidgid = "bin bin";
1181 my $pkgdestdir = $ENV{'PBSOLDESTDIR'};
1182
1183 return if ($_ =~ /^$pkgdestdir$/);
1184 if (-d $_) {
1185 my $n = $File::Find::name;
1186 $n =~ s~$pkgdestdir/~~;
1187 print PROTO "d none $n 0755 $uidgid\n";
1188 } elsif (-x $_) {
1189 my $n = $File::Find::name;
1190 $n =~ s~$pkgdestdir/~~;
1191 print PROTO "f none $n 0755 $uidgid\n";
1192 } elsif (-f $_) {
1193 my $n = $File::Find::name;
1194 $n =~ s~$pkgdestdir/~~;
1195 print PROTO "f none $n 0644 $uidgid\n";
1196 }
1197}
1198
1199sub pb_build2ssh {
1200 pb_send2target("Sources");
1201}
1202
1203sub pb_pkg2ssh {
1204 pb_send2target("Packages");
1205}
1206
1207# By default deliver to the the public site hosting the
1208# ftp structure (or whatever) or a VM/VE
1209sub pb_send2target {
1210
1211 my $cmt = shift;
1212 my $v = shift || undef;
1213 my $vmexist = shift || 0; # 0 is FALSE
1214 my $vmpid = shift || 0; # 0 is FALSE
1215 my $snapme = shift || 0; # 0 is FALSE
1216
1217 pb_log(2,"DEBUG: pb_send2target($cmt,".Dumper($v).",$vmexist,$vmpid)\n");
1218 my $host = "sshhost";
1219 my $login = "sshlogin";
1220 my $dir = "sshdir";
1221 my $port = "sshport";
1222 my $conf = "sshconf";
1223 my $tmout = undef;
1224 my $path = undef;
1225 if ($cmt =~ /^VM/) {
1226 $login = "vmlogin";
1227 $dir = "pbdefdir";
1228 # Specific VM
1229 $tmout = "vmtmout";
1230 $path = "vmpath";
1231 $host = "vmhost";
1232 $port = "vmport";
1233 } elsif ($cmt =~ /^VE/) {
1234 $login = "velogin";
1235 $dir = "pbdefdir";
1236 # Specific VE
1237 $path = "vepath";
1238 $conf = "rbsconf";
1239 } elsif ($cmt eq "Web") {
1240 $host = "websshhost";
1241 $login = "websshlogin";
1242 $dir = "websshdir";
1243 $port = "websshport";
1244 }
1245 my $cmd = "";
1246 my $src = "";
1247 my ($odir,$over,$oarch) = (undef, undef, undef);
1248 my ($ddir, $dver, $dfam, $dtype, $dos, $pbsuf, $pbupd, $darch);
1249
1250 if ($cmt ne "Announce") {
1251 # Get list of packages to build
1252 my $ptr = pb_get_pkg();
1253 @pkgs = @$ptr;
1254
1255 # Get the running distro to consider
1256 if (defined $v) {
1257 ($odir,$over,$oarch) = split(/-/,$v);
1258 }
1259 ($ddir, $dver, $dfam, $dtype, $dos, $pbsuf, $pbupd, $darch) = pb_distro_init($odir,$over,$oarch);
1260 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf, $darch))."\n");
1261
1262 # Get list of packages to build
1263 # Get content saved in cms2build
1264 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
1265 $pkg = { } if (not defined $pkg);
1266
1267 chdir "$ENV{'PBBUILDDIR'}";
1268 foreach my $pbpkg (@pkgs) {
1269 my $vertag = $pkg->{$pbpkg};
1270 # get the version of the current package - maybe different
1271 ($pbver,$pbtag) = split(/-/,$vertag);
1272
1273 if (($cmt eq "Sources") || ($cmt =~ /V[EM]build/)) {
1274 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz $ENV{'PBDESTDIR'}/$pbpkg-$pbver.pbconf.tar.gz";
1275 if ($cmd eq "") {
1276 $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
1277 } else {
1278 $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
1279 }
1280 } elsif ($cmt eq "Web") {
1281 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz"
1282 }
1283 }
1284 # Adds conf file for availability of conf elements
1285 pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
1286 }
1287
1288 if ($cmt =~ /V[EM]build/) {
1289 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc $ENV{'PBDESTDIR'}/pbscript";
1290 } elsif (($cmt =~ /V[EM]Script/) || ($cmt eq "Web")) {
1291 $src="$src $ENV{'PBDESTDIR'}/pbscript";
1292 } elsif ($cmt =~ /V[EM]test/) {
1293 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc $ENV{'PBDESTDIR'}/pbscript $ENV{'PBDESTDIR'}/pbtest";
1294 } elsif ($cmt eq "Announce") {
1295 $src="$src $ENV{'PBTMP'}/pbscript";
1296 } elsif ($cmt eq "Packages") {
1297 # Get package list from file made during build2pkg
1298 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
1299 $src = <KEEP>;
1300 chomp($src);
1301 close(KEEP);
1302 $src="$src $ENV{'PBBUILDDIR'}/pbscript";
1303 }
1304 # Remove potential leading spaces (cause problem with basename)
1305 $src =~ s/^ *//;
1306 my $basesrc = "";
1307 foreach my $i (split(/ +/,$src)) {
1308 $basesrc .= " ".basename($i);
1309 }
1310
1311 pb_log(0,"Sources handled ($cmt): $src\n");
1312 pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$path,$conf))."\n");
1313 my ($sshhost,$sshlogin,$sshdir,$sshport) = pb_conf_get($host,$login,$dir,$port);
1314 # Not mandatory...
1315 my ($rbsconf,$testver,$delivery) = pb_conf_get_if($conf,"testver","delivery");
1316 $delivery->{$ENV{'PBPROJ'}} = "" if (not defined $delivery->{$ENV{'PBPROJ'}});
1317 my ($vtmout,$vepath);
1318 # ...Except those in virtual context
1319 if ($cmt =~ /^VE/) {
1320 ($vepath) = pb_conf_get($path);
1321 }
1322 if ($cmt =~ /^VM/) {
1323 ($vtmout) = pb_conf_get($tmout);
1324 }
1325 pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vepath,$rbsconf))."\n");
1326
1327 my $mac;
1328 if ($cmt !~ /^VE/) {
1329 $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
1330 # Overwrite account value if passed as parameter
1331 $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
1332 pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
1333 } else {
1334 # VE
1335 # Overwrite account value if passed as parameter (typically for setup2ve)
1336 $mac = $sshlogin->{$ENV{'PBPROJ'}};
1337 $mac = $pbaccount if (defined $pbaccount);
1338 }
1339
1340 my $tdir;
1341 my $bdir;
1342 if (($cmt eq "Sources") || ($cmt =~ /V[EM]Script/)) {
1343 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$delivery->{$ENV{'PBPROJ'}}/src";
1344 } elsif (($cmt =~ /V[EM]build/) || ($cmt =~ /V[EM]test/)) {
1345 $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
1346 $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
1347 # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
1348 $bdir =~ s|\$ENV.+\}/||;
1349 } elsif ($cmt eq "Announce") {
1350 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$delivery->{$ENV{'PBPROJ'}}";
1351 } elsif ($cmt eq "Web") {
1352 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$delivery->{$ENV{'PBPROJ'}}";
1353 } elsif ($cmt eq "Packages") {
1354 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$delivery->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch";
1355
1356 my $repodir = $tdir;
1357 $repodir =~ s|^$sshdir->{$ENV{'PBPROJ'}}/||;
1358
1359 my ($pbrepo) = pb_conf_get("pbrepo");
1360
1361 # Repository management
1362 open(PBS,"> $ENV{'PBBUILDDIR'}/pbscript") || die "Unable to create $ENV{'PBBUILDDIR'}/pbscript";
1363 if ($dtype eq "rpm") {
1364 # Also make a pbscript to generate yum/urpmi bases
1365 print PBS << "EOF";
1366#!/bin/bash
1367# Prepare a script to ease yum setup
1368cat > $ENV{'PBPROJ'}.repo << EOT
1369[$ENV{'PBPROJ'}]
1370name=$ddir $dver $darch - $ENV{'PBPROJ'} Vanilla Packages
1371baseurl=$pbrepo->{$ENV{'PBPROJ'}}/$repodir
1372enabled=1
1373gpgcheck=0
1374EOT
1375chmod 644 $ENV{'PBPROJ'}.repo
1376
1377# Clean up old repo content
1378rm -rf headers/ repodata/
1379# Create yum repo
1380if [ -x /usr/bin/yum-arch ]; then
1381 yum-arch .
1382fi
1383# Create repodata
1384createrepo .
1385EOF
1386 if ($dfam eq "md") {
1387 # For Mandriva add urpmi management
1388 print PBS << "EOF";
1389# Prepare a script to ease urpmi setup
1390cat > $ENV{'PBPROJ'}.addmedia << EOT
1391urpmi.addmedia $ENV{'PBPROJ'} $pbrepo->{$ENV{'PBPROJ'}}/$repodir with media_info/hdlist.cz
1392EOT
1393chmod 755 $ENV{'PBPROJ'}.addmedia
1394
1395# Clean up old repo content
1396rm -f hdlist.cz synthesis.hdlist.cz
1397# Create urpmi repo
1398genhdlist2 --clean .
1399if [ \$\? -ne 0 ]; then
1400 genhdlist .
1401fi
1402EOF
1403 }
1404 if ($ddir eq "fedora") {
1405 # Extract the spec file to please Fedora maintainers :-(
1406 print PBS << "EOF";
1407for p in $basesrc; do
1408 echo \$p | grep -q 'src.rpm'
1409 if [ \$\? -eq 0 ]; then
1410 rpm2cpio \$p | cpio -ivdum --quiet '*.spec'
1411 fi
1412done
1413EOF
1414 }
1415 if ($dfam eq "novell") {
1416 # Add ymp scripts for one-click install on SuSE
1417 print PBS << "EOF";
1418# Prepare a script to ease SuSE one-click install
1419# Cf: http://de.opensuse.org/1-Klick-Installation/ISV
1420#
1421cat > $ENV{'PBPROJ'}.ymp << EOT
1422<?xml version="1.0" encoding="utf-8"?>
1423<!-- vim: set sw=2 ts=2 ai et: -->
1424<metapackage xmlns:os="http://opensuse.org/Standards/One_Click_Install" xmlns="http://opensuse.org/Standards/One_Click_Install">
1425 <group><!-- The group of software, typically one for project-builder.org -->
1426 <name>$ENV{'PBPROJ'} Bundle</name> <!-- Name of the software group -->
1427 <summary>Software bundle for the $ENV{'PBPROJ'} project</summary> <!--This message is shown to the user and should describe the whole bundle -->
1428 <description>This is the summary of the $ENV{'PBPROJ'} Project
1429
1430 Details are available on a per package basis below
1431
1432 </description><!--This is also shown to the user -->
1433 <remainSubscribed>false</remainSubscribed> <!-- Don't know what it mean -->
1434 <repositories><!-- List of needed repositories -->
1435 <repository>
1436 <name>$ENV{'PBPROJ'} Repository</name> <!-- Name of the repository -->
1437 <summary>This repository contains the $ENV{'PBPROJ'} project packages.</summary> <!-- Summary of the repository -->
1438 <description>This repository contains the $ENV{'PBPROJ'} project packages.</description><!-- This description is shown to the user -->
1439 <url>$pbrepo->{$ENV{'PBPROJ'}}/$repodir</url><!--URL of repository, which is added -->
1440 </repository>
1441 </repositories>
1442 <software><!-- A List of packages, which should be added through the one-click-installation -->
1443EOT
1444for p in $basesrc; do
1445 sum=`rpm -q --qf '%{SUMMARY}' \$p`
1446 name=`rpm -q --qf '%{NAME}' \$p`
1447 desc=`rpm -q --qf '%{description}' \$p`
1448 cat >> $ENV{'PBPROJ'}.ymp << EOT
1449 <item>
1450 <name>\$name</name><!-- Name of the package, is shown to the user and used to identify the package at the repository -->
1451 <summary>\$sum</summary> <!-- Summary of the package -->
1452 <description>\$desc</description> <!-- Description, is shown to the user -->
1453 </item>
1454EOT
1455done
1456cat >> $ENV{'PBPROJ'}.ymp << EOT
1457 </software>
1458 </group>
1459</metapackage>
1460EOT
1461chmod 644 $ENV{'PBPROJ'}.ymp
1462EOF
1463 }
1464 } elsif ($dtype eq "deb") {
1465 # Also make a pbscript to generate apt bases
1466 # Cf: http://www.debian.org/doc/manuals/repository-howto/repository-howto.fr.html
1467 my $rpd = dirname("$pbrepo->{$ENV{'PBPROJ'}}/$repodir");
1468 print PBS << "EOF";
1469#!/bin/bash
1470# Prepare a script to ease apt setup
1471cat > $ENV{'PBPROJ'}.sources.list << EOT
1472deb $rpd $dver contrib
1473deb-src $rpd $dver contrib
1474EOT
1475chmod 644 $ENV{'PBPROJ'}.sources.list
1476
1477# Prepare a script to create apt info file
1478(cd .. ; for a in i386 amd64 ia64; do mkdir -p dists/$dver/contrib/binary-\$a; dpkg-scanpackages -a\$a $dver/$darch /dev/null | gzip -c9 > dists/$dver/contrib/binary-\$a/Packages.gz; done; mkdir -p dists/$dver/contrib/source; dpkg-scansources $dver/$darch /dev/null | gzip -c9 > dists/$dver/contrib/source/Sources.gz)
1479#(cd .. ; rm -f dists/$dver/Release ; apt-ftparchive release dists/$dver > dists/$dver/Release; gpg --sign -ba -o dists/$dver/Release.gpg dists/$dver/Release)
1480EOF
1481 } elsif ($dtype eq "ebuild") {
1482 # make a pbscript to generate links to latest version
1483 print PBS << "EOF";
1484#!/bin/bash
1485# Prepare a script to create correct links
1486for p in $src; do
1487 echo \$p | grep -q '.ebuild'
1488 if [ \$\? -eq 0 ]; then
1489 j=`basename \$p`
1490 pp=`echo \$j | cut -d'-' -f1`
1491 ln -sf \$j \$pp.ebuild
1492 fi
1493done
1494EOF
1495 }
1496 close(PBS);
1497 chmod 0755,"$ENV{'PBBUILDDIR'}/pbscript";
1498 } else {
1499 return;
1500 }
1501
1502 # Useless for VE
1503 my $nport;
1504 if ($cmt !~ /^VE/) {
1505 $nport = $sshport->{$ENV{'PBPROJ'}};
1506 $nport = "$pbport" if (defined $pbport);
1507 }
1508
1509 # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
1510 $tdir =~ s|\$ENV.+\}/||;
1511
1512 my $tm = undef;
1513 if ($cmt =~ /^VM/) {
1514 $tm = $vtmout->{$ENV{'PBPROJ'}};
1515 }
1516
1517 # ssh communication if not VE
1518 # should use a hash instead...
1519 my ($shcmd,$cpcmd,$cptarget,$cp2target);
1520 if ($cmt !~ /^VE/) {
1521 my $keyfile = pb_ssh_get(0);
1522 $shcmd = "ssh -i $keyfile -q -o UserKnownHostsFile=/dev/null -p $nport $mac";
1523 $cpcmd = "scp -i $keyfile -p -o UserKnownHostsFile=/dev/null -P $nport";
1524 $cptarget = "$mac:$tdir";
1525 if ($cmt =~ /^VMbuild/) {
1526 $cp2target = "$mac:$bdir";
1527 }
1528 } else {
1529 my $tp = $vepath->{$ENV{'PBPROJ'}};
1530 ($odir,$over,$oarch) = split(/-/,$v);
1531 my $tpdir = "$tp/$odir/$over/$oarch";
1532 my ($ptr) = pb_conf_get("vetype");
1533 my $vetype = $ptr->{$ENV{'PBPROJ'}};
1534 if ($vetype eq "chroot") {
1535 $shcmd = "sudo chroot $tpdir /bin/su - $mac -c ";
1536 } elsif ($vetype eq "schroot") {
1537 $shcmd = "schroot $tp -u $mac -- ";
1538 }
1539 $cpcmd = "sudo cp -r ";
1540 # We need to get the home dir of the target account to deliver in the right place
1541 open(PASS,"$tpdir/etc/passwd") || die "Unable to open $tpdir/etc/passwd";
1542 my $homedir = "";
1543 while (<PASS>) {
1544 my ($c1,$c2,$c3,$c4,$c5,$c6,$c7) = split(/:/);
1545 $homedir = $c6 if ($c1 =~ /^$mac$/);
1546 pb_log(3,"Homedir: $homedir - account: $c6\n");
1547 }
1548 close(PASS);
1549 $cptarget = "$tpdir/$homedir/$tdir";
1550 if ($cmt eq "VEbuild") {
1551 $cp2target = "$tpdir/$homedir/$bdir";
1552 }
1553 pb_log(2,"On VE using $cptarget as target dir to copy to\n");
1554 }
1555
1556 my $logres = "";
1557 # Do not touch when just announcing
1558 if ($cmt ne "Announce") {
1559 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");
1560 } else {
1561 $logres = "> ";
1562 }
1563 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
1564
1565 # For VE we need to change the owner manually
1566 if ($cmt =~ /^VE/) {
1567 pb_system("$shcmd \"sudo chown -R $mac $tdir\"","Adapt owner in $tdir to $mac");
1568 }
1569
1570 pb_system("$shcmd \"echo \'cd $tdir ; if [ -x pbscript ]; then ./pbscript; fi ; rm -f ./pbscript\' | bash\"","Executing pbscript on $cptarget if needed","verbose");
1571 if ($cmt =~ /^V[EM]build/) {
1572 # Get back info on pkg produced, compute their name and get them from the VM
1573 pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
1574 # For VE we need to change the owner manually
1575 if ($cmt eq "VEbuild") {
1576 pb_system("sudo chown $UID $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}","Adapt owner in $tdir to $UID");
1577 }
1578 # return here to avoid breaking the load on VMs/VEs in case of a bad one
1579 if (not -f "$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") {
1580 pb_log(0,"Problem with VM $v on $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}");
1581 return;
1582 }
1583 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
1584 my $src = <KEEP>;
1585 chomp($src);
1586 close(KEEP);
1587 $src =~ s/^ *//;
1588 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
1589 # Change pgben to make the next send2target happy
1590 my $made = "";
1591 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
1592 foreach my $p (split(/ +/,$src)) {
1593 my $j = basename($p);
1594 # For VM we don't want shell expansion to hapen locally but remotely
1595 my $delim = '\'';
1596 if ($cmt =~ /^VEbuild/) {
1597 # For VE we need to support shell expansion locally
1598 $delim = "";
1599 }
1600 pb_system("$cpcmd $cp2target/$delim$p$delim $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Recovery of package $j in $ENV{'PBBUILDDIR'}/$odir/$over");
1601 $made="$made $odir/$over/$j"; # if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
1602 }
1603 print KEEP "$made\n";
1604 close(KEEP);
1605 pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
1606
1607 # Sign packages locally
1608 if ($dtype eq "rpm") {
1609 #pb_system("rpm --addsign --define \'_signature gpg\' --define \'_gpg_name \"$ENV{'PBPACKAGER'}\"\' --define \'__gpg_sign_cmd /usr/bin/gpg --batch --no-verbose --no-armor --no-tty --no-secmem-warning -sbo %{__signature_filename} %{__plaintext_filename} --use-agent\' $made","Signing RPM packages packages");
1610 } elsif ($dtype eq "deb") {
1611 #pb_system("debsign $made","Signing DEB packages");
1612 } else {
1613 pb_log(0,"I don't know yet how to sign packages for type $dtype.\nPlease give feedback to dev team\n");
1614 }
1615
1616 # We want to send them to the ssh account so overwrite what has been done before
1617 undef $pbaccount;
1618 pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
1619 pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
1620 pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
1621 }
1622 pb_log(2,"Before halt, vmexist: $vmexist, vmpid: $vmpid\n");
1623 if ((! $vmexist) && ($cmt =~ /^VM/)) {
1624 # If in setupvm then takes a snapshot just before halting
1625 if ($snapme != 0) {
1626 my ($vmmonport,$vmtype) = pb_conf_get("vmmonport","vmtype");
1627 # For monitoring control
1628 if ((($vmtype->{$ENV{'PBPROJ'}}) eq "kvm") || (($vmtype->{$ENV{'PBPROJ'}}) eq "qemu")) {
1629 require Net::Telnet;
1630 my $t = new Net::Telnet (Timeout => 120, Host => "localhost", Port => $vmmonport->{$ENV{'PBPROJ'}}) || die "Unable to dialog on the monitor";
1631 # move to monitor mode
1632 my @lines = $t->cmd("c");
1633 # Create a snapshot named pb
1634 @lines = $t->cmd("savevm pb");
1635 # Write the new status in the VM
1636 @lines = $t->cmd("commit all");
1637 # End
1638 @lines = $t->cmd("quit");
1639 }
1640 }
1641 my $hoption = "-p";
1642 my $hpath = "/sbin";
1643 # Solaris doesn't support -h and has halt elsewhere
1644 if ($dtype eq "pkg") {
1645 $hoption = "" ;
1646 $hpath = "/usr/sbin";
1647 }
1648 pb_system("$shcmd \"sudo $hpath/halt $hoption \"; sleep $tm ; echo \'if [ -d /proc/$vmpid ]; then kill -9 $vmpid; fi \' | bash ; sleep 10","VM $v halt (pid $vmpid)");
1649 }
1650 if (($cmt =~ /^VE/) && ($snapme != 0)) {
1651 ($odir,$over,$oarch) = split(/-/,$v);
1652 my $tpdir = "$vepath->{$ENV{'PBPROJ'}}/$odir/$over/$oarch";
1653 pb_system("sudo tar cz -f $vepath->{$ENV{'PBPROJ'}}/$odir-$over-$oarch.tar.gz -C $tpdir .","Creating a snapshot of $tpdir");
1654 }
1655}
1656
1657sub pb_script2v {
1658 my $pbscript=shift;
1659 my $vtype=shift;
1660 my $pbforce=shift || 0; # Force stop of VM. Default not
1661 my $vm1=shift || undef; # Only that VM to treat
1662 my $snapme=shift || 0; # Do we have to create a snapshot
1663 my $vm;
1664 my $all;
1665
1666 pb_log(2,"DEBUG: pb_script2v($pbscript,$vtype,$pbforce,".Dumper($vm1).",$snapme)\n");
1667 # Prepare the script to be executed on the VM
1668 # in $ENV{'PBDESTDIR'}/pbscript
1669 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
1670 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1671 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1672 }
1673
1674 if (not defined $vm1) {
1675 ($vm,$all) = pb_get2v($vtype);
1676 } else {
1677 @$vm = ($vm1);
1678 }
1679 my ($vmexist,$vmpid) = (undef,undef);
1680
1681 foreach my $v (@$vm) {
1682 # Launch VM/VE
1683 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0,$snapme,$pbsnap);
1684
1685 if ($vtype eq "vm") {
1686 pb_log(2,"DEBUG: After pb_launchv, vmexist: $vmexist, vmpid: $vmpid\n");
1687
1688 # Skip that VM if something went wrong
1689 next if (($vmpid == 0) && ($vmexist == 0));
1690
1691 # If force stopping the VM then reset vmexist
1692 if ($pbforce == 1) {
1693 $vmpid = $vmexist;
1694 $vmexist = 0;
1695 }
1696 } else {
1697 #VE
1698 $vmexist = 0;
1699 $vmpid = 0;
1700 }
1701
1702 # Gather all required files to send them to the VM
1703 # and launch the build through pbscript
1704 pb_log(2,"DEBUG: Before send2target, vmexist: $vmexist, vmpid: $vmpid\n");
1705 pb_send2target(uc($vtype)."Script","$v",$vmexist,$vmpid,$snapme);
1706
1707 }
1708}
1709
1710sub pb_launchv {
1711 my $vtype = shift;
1712 my $v = shift;
1713 my $create = shift || 0; # By default do not create a VM/VE
1714 my $snapme = shift || 0; # By default do not snap a VM/VE
1715 my $usesnap = shift || 1; # By default study the usage of the snapshot feature of VM/VE
1716
1717 # If creation or snapshot creation mode, no snapshot usable
1718 if (($create == 1) || ($snapme == 1)) {
1719 $usesnap = 0;
1720 }
1721
1722 pb_log(2,"DEBUG: pb_launchv($vtype,$v,$create,$snapme,$usesnap)\n");
1723 die "No VM/VE defined, unable to launch" if (not defined $v);
1724 # Keep only the first VM in case many were given
1725 $v =~ s/,.*//;
1726
1727 my $arch = pb_get_arch();
1728
1729 # Launch the VMs/VEs
1730 if ($vtype eq "vm") {
1731 die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
1732
1733 # TODO: vmmonport should be optional
1734 my ($ptr,$ptr2,$vmpath,$vmport,$vmsize,$vmmonport) = pb_conf_get("vmtype","vmcmd","vmpath","vmport","vmsize","vmmonport");
1735 my ($vmopt,$vmtmout,$vmsnap) = pb_conf_get_if("vmopt","vmtmout","vmsnap");
1736
1737 my $vmtype = $ptr->{$ENV{'PBPROJ'}};
1738 my $vmcmd = $ptr2->{$ENV{'PBPROJ'}};
1739 if (not defined $ENV{'PBVMOPT'}) {
1740 $ENV{'PBVMOPT'} = "";
1741 }
1742 # Save the current status for later restoration
1743 $ENV{'PBOLDVMOPT'} = $ENV{'PBVMOPT'};
1744 # Set a default timeout of 2 minutes
1745 if (not defined $ENV{'PBVMTMOUT'}) {
1746 $ENV{'PBVMTMOUT'} = "120";
1747 }
1748 if (defined $vmopt->{$v}) {
1749 $ENV{'PBVMOPT'} .= " $vmopt->{$v}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$v}/);
1750 } elsif (defined $vmopt->{$ENV{'PBPROJ'}}) {
1751 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
1752 }
1753
1754 # Are we allowed to use snapshot feature
1755 if ($usesnap == 1) {
1756 if ((defined $vmsnap->{$v}) && ($vmsnap->{$v} =~ /true/i)) {
1757 $ENV{'PBVMOPT'} .= " -snapshot";
1758 } elsif ((defined $vmsnap->{$ENV{'PBPROJ'}}) && ($vmsnap->{$ENV{'PBPROJ'}} =~ /true/i)) {
1759 $ENV{'PBVMOPT'} .= " -snapshot";
1760 } elsif ($pbsnap eq 1) {
1761 $ENV{'PBVMOPT'} .= " -snapshot";
1762 }
1763 }
1764 if ($snapme != 0) {
1765 if (($vmtype eq "kvm") || ($vmtype eq "qemu")) {
1766 # Configure the monitoring to automize the creation of the 'pb' snapshot
1767 $ENV{'PBVMOPT'} .= " -serial mon:telnet::$vmmonport->{$ENV{'PBPROJ'}},server,nowait";
1768 # In that case no snapshot call needed
1769 $ENV{'PBVMOPT'} =~ s/ -snapshot//;
1770 }
1771 }
1772 if (defined $vmtmout->{$v}) {
1773 $ENV{'PBVMTMOUT'} = $vmtmout->{$v};
1774 } elsif (defined $vmtmout->{$ENV{'PBPROJ'}}) {
1775 $ENV{'PBVMTMOUT'} = $vmtmout->{$ENV{'PBPROJ'}};
1776 }
1777 my $nport = $vmport->{$ENV{'PBPROJ'}};
1778 $nport = "$pbport" if (defined $pbport);
1779
1780 my $cmd;
1781 my $vmm; # has to be used for pb_check_ps
1782 if (($vmtype eq "qemu") || ($vmtype eq "kvm")) {
1783 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
1784 if (($create != 0) || (defined $iso)) {
1785 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
1786 }
1787 # Always redirect the network and always try to use a 'pb' snapshot
1788 $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 -loadvm pb $vmm"
1789 } elsif ($vmtype eq "xen") {
1790 } elsif ($vmtype eq "vmware") {
1791 } else {
1792 die "VM of type $vmtype not supported. Report to the dev team";
1793 }
1794 # Restore the ENV VAR Value
1795 $ENV{'PBVMOPT'} = $ENV{'PBOLDVMOPT'};
1796
1797 my ($tmpcmd,$void) = split(/ +/,$cmd);
1798 my $vmexist = pb_check_ps($tmpcmd,$vmm);
1799 my $vmpid = 0;
1800 if (! $vmexist) {
1801 if ($create != 0) {
1802 die("Found an existing Virtual machine $vmm. Won't overwrite") if (-r $vmm);
1803 if (($vmtype eq "qemu") || ($vmtype eq "xen") || ($vmtype eq "kvm")) {
1804 pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
1805 } elsif ($vmtype eq "vmware") {
1806 } else {
1807 }
1808 }
1809 if (! -f "$vmm") {
1810 pb_log(0,"Unable to find VM $vmm\n");
1811 } else {
1812 pb_system("$cmd &","Launching the VM $vmm");
1813 pb_system("sleep $ENV{'PBVMTMOUT'}","Waiting $ENV{'PBVMTMOUT'} s for VM $v to come up");
1814 $vmpid = pb_check_ps($tmpcmd,$vmm);
1815 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
1816 }
1817 } else {
1818 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
1819 }
1820 pb_log(2,"DEBUG: pb_launchv returns ($vmexist,$vmpid)\n");
1821 return($vmexist,$vmpid);
1822 # VE here
1823 } else {
1824 # Get distro context
1825 my ($name,$ver,$darch) = split(/-/,$v);
1826 chomp($darch);
1827 my ($ddir, $dver, $dfam, $dtype, $dos, $pbsuf) = pb_distro_init($name,$ver,$darch);
1828
1829 # Get VE context
1830 my ($ptr,$vepath) = pb_conf_get("vetype","vepath");
1831 my $vetype = $ptr->{$ENV{'PBPROJ'}};
1832
1833 # We can probably only get those params now we have the distro context
1834 my ($rbsb4pi,$rbspi,$vesnap,$oscodename,$osmindep,$verebuild,$rbsmirrorsrv) = pb_conf_get_if("rbsb4pi","rbspi","vesnap","oscodename","osmindep","verebuild","rbsmirrorsrv");
1835
1836 # We need to avoid umask propagation to the VE
1837 umask 0022;
1838
1839 if (($vetype eq "chroot") || ($vetype eq "schroot")) {
1840 # Architecture consistency
1841 if ($arch ne $darch) {
1842 die "Unable to launch a VE of architecture $darch on a $arch platform" if (($darch eq "x86_64") && ($arch =~ /i?86/));
1843 }
1844
1845 my ($verpmtype,$vedebtype) = pb_conf_get("verpmtype","vedebtype");
1846 if (($create != 0) || ((defined $verebuild) && ($verebuild->{$ENV{'PBPROJ'}} =~ /true/i)) || ($pbforce == 1)) {
1847 my ($rbsopt1) = pb_conf_get_if("rbsopt");
1848
1849 # We have to rebuild the chroot
1850 if ($dtype eq "rpm") {
1851
1852 # Which tool is used
1853 my $verpmstyle = $verpmtype->{$ENV{'PBPROJ'}};
1854
1855 # Get potential rbs option
1856 my $rbsopt = "";
1857 if (defined $rbsopt1) {
1858 if (defined $rbsopt1->{$verpmstyle}) {
1859 $rbsopt = $rbsopt1->{$verpmstyle};
1860 } elsif (defined $rbsopt1->{$ENV{'PBPROJ'}}) {
1861 $rbsopt = $rbsopt1->{$ENV{'PBPROJ'}};
1862 } else {
1863 $rbsopt = "";
1864 }
1865 }
1866
1867 my $postinstall = pb_get_postinstall($ddir,$dver,$darch,$rbspi,$verpmstyle);
1868 if ($verpmstyle eq "rinse") {
1869 # Need to reshape the mirrors generated with local before-post-install script
1870 my $b4post = "--before-post-install ";
1871 my $postparam = pb_distro_get_param($ddir,$dver,$darch,$rbsb4pi);
1872 if ($postparam eq "") {
1873 $b4post = "";
1874 } else {
1875 $b4post .= $postparam;
1876 }
1877
1878 # Need to reshape the package list for pb
1879 my $addpkgs;
1880 $postparam = "";
1881 $postparam .= pb_distro_get_param($ddir,$dver,$darch,$osmindep);
1882 if ($postparam eq "") {
1883 $addpkgs = "";
1884 } else {
1885 my $pkgfile = "$ENV{'PBTMP'}/addpkgs.lis";
1886 open(PKG,"> $pkgfile") || die "Unable to create $pkgfile";
1887 foreach my $p (split(/,/,$postparam)) {
1888 print PKG "$p\n";
1889 }
1890 close(PKG);
1891 $addpkgs = "--add-pkg-list $pkgfile";
1892 }
1893
1894 my $rinseverb = "";
1895 $rinseverb = "--verbose" if ($pbdebug gt 0);
1896 my ($rbsconf) = pb_conf_get("rbsconf");
1897
1898 pb_system("sudo /usr/sbin/rinse --directory \"$vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch\" --arch \"$darch\" --distribution \"$ddir-$dver\" --config \"$rbsconf->{$ENV{'PBPROJ'}}\" $b4post $postinstall $rbsopt $addpkgs $rinseverb","Creating the rinse VE for $ddir-$dver ($darch)", "verbose");
1899 } elsif ($verpmstyle eq "rpmbootstrap") {
1900 my $rbsverb = "";
1901 foreach my $i (1..$pbdebug) {
1902 $rbsverb .= " -v";
1903 }
1904 my $addpkgs = "";
1905 my $postparam = "";
1906 $postparam .= pb_distro_get_param($ddir,$dver,$darch,$osmindep);
1907 if ($postparam eq "") {
1908 $addpkgs = "";
1909 } else {
1910 $addpkgs = "-a $postparam";
1911 }
1912 pb_system("sudo /usr/bin/rpmbootstrap $rbsopt $postinstall $addpkgs $ddir-$dver-$darch $rbsverb","Creating the rpmbootstrap VE for $ddir-$dver ($darch)", "verbose");
1913 } elsif ($verpmstyle eq "mock") {
1914 my ($rbsconf) = pb_conf_get("rbsconf");
1915 pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$rbsconf->{$ENV{'PBPROJ'}}\" -r $v $rbsopt","Creating the mock VE for $ddir-$dver ($darch)");
1916 # Once setup we need to install some packages, the pb account, ...
1917 pb_system("sudo /usr/sbin/mock --install --configdir=\"$rbsconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
1918 } else {
1919 die "Unknown verpmtype type $verpmstyle. Report to dev team";
1920 }
1921 } elsif ($dtype eq "deb") {
1922 my $vedebstyle = $vedebtype->{$ENV{'PBPROJ'}};
1923
1924 my $codename = pb_distro_get_param($ddir,$dver,$darch,$oscodename);
1925 my $postparam = "";
1926 my $addpkgs;
1927 $postparam .= pb_distro_get_param($ddir,$dver,$darch,$osmindep);
1928 if ($postparam eq "") {
1929 $addpkgs = "";
1930 } else {
1931 $addpkgs = "--include $postparam";
1932 }
1933 my $debmir = "";
1934 $debmir .= pb_distro_get_param($ddir,$dver,$darch,$rbsmirrorsrv);
1935
1936 # Get potential rbs option
1937 my $rbsopt = "";
1938 if (defined $rbsopt1) {
1939 if (defined $rbsopt1->{$vedebstyle}) {
1940 $rbsopt = $rbsopt1->{$vedebstyle};
1941 } elsif (defined $rbsopt1->{$ENV{'PBPROJ'}}) {
1942 $rbsopt = $rbsopt1->{$ENV{'PBPROJ'}};
1943 } else {
1944 $rbsopt = "";
1945 }
1946 }
1947
1948 # debootstrap works with amd64 not x86_64
1949 my $debarch = $darch;
1950 $debarch = "amd64" if ($darch eq "x86_64");
1951 if ($vedebstyle eq "debootstrap") {
1952 my $dbsverb = "";
1953 $dbsverb = "--verbose" if ($pbdebug gt 0);
1954
1955 # Some perl modules are in Universe on Ubuntu
1956 $rbsopt .= " --components=main,universe" if ($ddir eq "ubuntu");
1957
1958 pb_system("sudo /usr/sbin/debootstrap $dbsverb $rbsopt --arch=$debarch $addpkgs $codename \"$vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch\" $debmir","Creating the debootstrap VE for $ddir-$dver ($darch)", "verbose");
1959 # debootstrap doesn't create an /etc/hosts file
1960 if (! -f "$vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch/etc/hosts" ) {
1961 pb_system("sudo cp /etc/hosts $vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch/etc/hosts");
1962 }
1963 } else {
1964 die "Unknown vedebtype type $vedebstyle. Report to dev team";
1965 }
1966 } elsif ($dtype eq "ebuild") {
1967 die "Please teach the dev team how to build gentoo chroot";
1968 } else {
1969 die "Unknown distribution type $dtype. Report to dev team";
1970 }
1971 }
1972 # Fix modes to allow access to the VE for pb user
1973 pb_system("sudo chmod 755 $vepath->{$ENV{'PBPROJ'}}/$ddir $vepath->{$ENV{'PBPROJ'}}/$ddir/$dver $vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch","Fixing permissions");
1974
1975 # Test if an existing snapshot exists and use it if appropriate
1976 # And also use it of no local extracted VE is present
1977 if ((-f "$vepath->{$ENV{'PBPROJ'}}/$ddir-$dver-$darch.tar.gz") &&
1978 (((defined $vesnap->{$v}) && ($vesnap->{$v} =~ /true/i)) ||
1979 ((defined $vesnap->{$ENV{'PBPROJ'}}) && ($vesnap->{$ENV{'PBPROJ'}} =~ /true/i)) ||
1980 ($pbsnap eq 1) ||
1981 (! -d "$vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch"))) {
1982 pb_system("sudo rm -rf $vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch ; sudo mkdir -p $vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch ; sudo tar xz -C $vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch -f $vepath->{$ENV{'PBPROJ'}}/$ddir-$dver-$darch.tar.gz","Extracting snapshot of $ddir-$dver-$darch.tar.gz under $vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch");
1983 }
1984 # Nothing more to do for VE. No real launch
1985 } else {
1986 die "VE of type $vetype not supported. Report to the dev team";
1987 }
1988 }
1989}
1990
1991# Return string for date synchro
1992sub pb_date2v {
1993
1994my $vtype = shift;
1995my $v = shift;
1996
1997my ($ntp) = pb_conf_get_if($vtype."ntp");
1998my $vntp = $ntp->{$ENV{'PBPROJ'}} if (defined $ntp);
1999my $ntpline;
2000
2001if (defined $vntp) {
2002 my ($ntpcmd) = pb_conf_get($vtype."ntpcmd");
2003 my $vntpcmd;
2004 if (defined $ntpcmd->{$v}) {
2005 $vntpcmd = $ntpcmd->{$v};
2006 } elsif (defined $ntpcmd->{$ENV{'PBPROJ'}}) {
2007 $vntpcmd = $ntpcmd->{$ENV{'PBPROJ'}};
2008 } else {
2009 $vntpcmd = "/bin/true";
2010 }
2011 $ntpline = "sudo $vntpcmd $vntp";
2012} else {
2013 $ntpline = undef;
2014}
2015# Force new date to be in the future compared to the date
2016# of the host by adding 1 minute
2017my @date=pb_get_date();
2018$date[1]++;
2019my $upddate = strftime("%m%d%H%M%Y", @date);
2020my $dateline = "sudo date $upddate";
2021return($ntpline,$dateline);
2022}
2023
2024sub pb_build2v {
2025
2026my $vtype = shift;
2027my $action = shift || "build";
2028
2029my ($v,$all) = pb_get2v($vtype);
2030
2031# Send tar files when we do a global generation
2032pb_build2ssh() if (($all == 1) && ($action eq "build"));
2033
2034my ($vmexist,$vmpid) = (undef,undef);
2035
2036foreach my $v (@$v) {
2037 # Prepare the script to be executed on the VM/VE
2038 # in $ENV{'PBDESTDIR'}/pbscript
2039 open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
2040 print SCRIPT "#!/bin/bash\n";
2041
2042 # Transmit the verbosity level to the virtual env/mach.
2043 my $verbose = "";
2044 my $i = 0; # minimal debug level
2045 while ($i lt $pbdebug) {
2046 $verbose .= "-v ";
2047 $i++;
2048 }
2049 # Activate script verbosity if at least 2 for pbdebug
2050 print SCRIPT "set -x\n" if ($i gt 1);
2051 # Quiet if asked to be so on the original system
2052 $verbose = "-q" if ($pbdebug eq -1);
2053
2054 print SCRIPT "echo ... Execution needed\n";
2055 print SCRIPT "# This is in directory delivery\n";
2056 print SCRIPT "# Setup the variables required for building\n";
2057 print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
2058
2059 if ($action eq "build") {
2060 print SCRIPT "# Preparation for pb\n";
2061 print SCRIPT "mv .pbrc \$HOME\n";
2062 print SCRIPT "cd ..\n";
2063 }
2064
2065 # VE needs a good /proc
2066 if ($vtype eq "ve") {
2067 print SCRIPT "sudo mount -t proc /proc /proc\n";
2068 }
2069
2070 my ($ntpline,$dateline) = pb_date2v($vtype,$v);
2071 print SCRIPT "# Time sync\n";
2072 print SCRIPT "echo 'setting up date with '";
2073 if (defined $ntpline) {
2074 print SCRIPT "echo $ntpline\n";
2075 print SCRIPT "$ntpline\n";
2076 } else {
2077 print SCRIPT "echo $dateline\n";
2078 print SCRIPT "$dateline\n";
2079 }
2080 # Use potential local proxy declaration in case we need it to download repo, pkgs, ...
2081 if (defined $ENV{'http_proxy'}) {
2082 print SCRIPT "export http_proxy=\"$ENV{'http_proxy'}\"\n";
2083 }
2084
2085 if (defined $ENV{'ftp_proxy'}) {
2086 print SCRIPT "export ftp_proxy=\"$ENV{'ftp_proxy'}\"\n";
2087 }
2088
2089 # Get list of packages to build/test and get some ENV vars as well
2090 my $ptr = pb_get_pkg();
2091 @pkgs = @$ptr;
2092 my $p = join(' ',@pkgs) if (@pkgs);
2093 print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
2094 print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
2095 print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
2096
2097 # We may need to do some other tasks before building. Read a script here to finish setup
2098 if (-x "$ENV{'PBDESTDIR'}/pb$vtype".".pre") {
2099 print SCRIPT "# Special pre-instructions to be launched\n";
2100 print SCRIPT pb_get_content("$ENV{'PBDESTDIR'}/pb$vtype".".pre");
2101 }
2102
2103 if (-x "$ENV{'PBDESTDIR'}/pb$vtype"."$action.pre") {
2104 print SCRIPT "# Special pre-$action instructions to be launched\n";
2105 print SCRIPT pb_get_content("$ENV{'PBDESTDIR'}/pb$vtype"."$action.pre");
2106 }
2107
2108 print SCRIPT "# $action\n";
2109 print SCRIPT "echo $action"."ing packages on $vtype...\n";
2110
2111 if (($action eq "test") && (! -x "$ENV{'PBDESTDIR'}/pbtest")) {
2112 die "No test script ($ENV{'PBDESTDIR'}/pbtest) found when in test mode. Aborting ...";
2113 }
2114 print SCRIPT "pb $verbose -p $ENV{'PBPROJ'} $action"."2pkg $p\n";
2115
2116 if ($vtype eq "ve") {
2117 print SCRIPT "sudo umount /proc\n";
2118 }
2119
2120 # We may need to do some other tasks after building. Read a script here to exit properly
2121 if (-x "$ENV{'PBDESTDIR'}/pb$vtype"."$action.post") {
2122 print SCRIPT "# Special post-$action instructions to be launched\n";
2123 print SCRIPT pb_get_content("$ENV{'PBDESTDIR'}/pb$vtype"."$action.post");
2124 }
2125
2126 if (-x "$ENV{'PBDESTDIR'}/pb$vtype".".post") {
2127 print SCRIPT "# Special post-instructions to be launched\n";
2128 print SCRIPT pb_get_content("$ENV{'PBDESTDIR'}/pb$vtype".".post");
2129 }
2130
2131 close(SCRIPT);
2132 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
2133
2134 # Launch the VM/VE
2135 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
2136
2137 if ($vtype eq "vm") {
2138 # Skip that VM if it something went wrong
2139 next if (($vmpid == 0) && ($vmexist == 0));
2140 } else {
2141 # VE
2142 $vmexist = 0;
2143 $vmpid = 0;
2144 }
2145 # Gather all required files to send them to the VM/VE
2146 # and launch the build through pbscript
2147 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
2148 pb_send2target(uc($vtype).$action,"$v",$vmexist,$vmpid);
2149}
2150}
2151
2152
2153sub pb_clean {
2154
2155 my $sleep=10;
2156 die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
2157 die "Unable to get env var PBBUILDDIR" if (not defined $ENV{'PBBUILDDIR'});
2158 pb_log(0,"We will now wait $sleep s before removing both directories\n$ENV{'PBDESTDIR'} and $ENV{'PBBUILDDIR'}.\nPlease break me if this is wrong\n");
2159 sleep $sleep;
2160 pb_rm_rf($ENV{'PBDESTDIR'});
2161 pb_rm_rf($ENV{'PBBUILDDIR'});
2162}
2163
2164sub pb_newver {
2165
2166 die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
2167
2168 # Need this call for PBDIR
2169 my ($scheme2,$uri) = pb_cms_init($pbinit);
2170
2171 my ($pbconf,$pburl) = pb_conf_get("pbconfurl","pburl");
2172 $uri = $pbconf->{$ENV{'PBPROJ'}};
2173 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
2174
2175 # Checking CMS repositories status
2176 ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
2177
2178 if ($scheme !~ /^svn/) {
2179 die "Only SVN is supported at the moment";
2180 }
2181
2182 my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
2183 die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
2184
2185 $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
2186 die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
2187
2188 # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
2189 # we want to get for the root of the new URL
2190
2191 my $tmp = $ENV{'PBROOTDIR'};
2192 $tmp =~ s|^$ENV{'PBCONFDIR'}||;
2193
2194 my $newurl = "$uri/".dirname($tmp)."/$newver";
2195 # Should probably use projver in the old file
2196 my $oldver= basename($tmp);
2197
2198 # Duplicate and extract project-builder part
2199 pb_log(2,"Copying $uri/$tmp to $newurl\n");
2200 pb_cms_copy($scheme,"$uri/$tmp",$newurl);
2201 pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
2202 pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
2203
2204 # Duplicate and extract project
2205 my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
2206
2207 pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
2208 pb_cms_copy($scheme2,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
2209 pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
2210 pb_cms_up($scheme2,"$ENV{'PBDIR'}/..");
2211
2212 # Update the .pb file
2213 open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
2214 open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
2215 while(<FILE>) {
2216 s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
2217 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/);
2218 pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
2219 s/^testver/#testver/;
2220 print OUT $_;
2221 pb_log(0,"Please check delivery ($_) in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^delivery/);
2222 }
2223 close(FILE);
2224 close(OUT);
2225 rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
2226
2227 # Checking pbcl files
2228 foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
2229 # Compute new pbcl file
2230 my $f2 = $f;
2231 $f2 =~ s|$ENV{'PBROOTDIR'}|$ENV{'PBROOTDIR'}/../$newver/|;
2232 open(PBCL,$f) || die "Unable to open $f";
2233 my $foundnew = 0;
2234 while (<PBCL>) {
2235 $foundnew = 1 if (/^$newver \(/);
2236 }
2237 close(PBCL);
2238 open(OUT,"> $f2") || die "Unable to write to $f2: $!";
2239 open(PBCL,$f) || die "Unable to open $f";
2240 while (<PBCL>) {
2241 print OUT "$_" if (not /^$oldver \(/);
2242 if ((/^$oldver \(/) && ($foundnew == 0)) {
2243 print OUT "$newver ($pbdate)\n";
2244 print OUT "- TBD\n";
2245 print OUT "\n";
2246 pb_log(0,"WARNING: version $newver not found in $f so added to $f2...\n") if ($foundnew == 0);
2247 }
2248 }
2249 close(OUT);
2250 close(PBCL);
2251 }
2252
2253 pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
2254 pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver",undef);
2255}
2256
2257#
2258# Return the list of VMs/VEs we are working on
2259# $all is a flag to know if we return all of them
2260# or only some (if all we publish also tar files in addition to pkgs
2261#
2262sub pb_get2v {
2263
2264my $vtype = shift;
2265my @v;
2266my $all = 0;
2267my $vlist;
2268my $pbv = 'PBV';
2269
2270if ($vtype eq "vm") {
2271 $vlist = "vmlist";
2272} elsif ($vtype eq "ve") {
2273 $vlist = "velist";
2274}
2275# Get VM/VE list
2276if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
2277 my ($ptr) = pb_conf_get($vlist);
2278 $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
2279 $all = 1;
2280}
2281pb_log(2,"$vtype: $ENV{$pbv}\n");
2282@v = split(/,/,$ENV{$pbv});
2283return(\@v,$all);
2284}
2285
2286# Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
2287# Needs to use root account to connect to the VM/VE
2288# pb will take your local public SSH key to access
2289# the pb account in the VM later on if needed
2290sub pb_setup2v {
2291
2292my $vtype = shift;
2293
2294my ($vm,$all) = pb_get2v($vtype);
2295
2296# Script generated
2297my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
2298
2299foreach my $v (@$vm) {
2300 # Deal with date sync.
2301 my ($ntpline,$dateline) = pb_date2v($vtype,$v);
2302
2303 # Get distro context
2304 my ($name,$ver,$darch) = split(/-/,$v);
2305 chomp($darch);
2306 my ($ddir, $dver, $dfam, $dtype, $dos, $pbsuf, $pbupd) = pb_distro_init($name,$ver,$darch);
2307
2308 # Name of the account to deal with for VM/VE
2309 # Do not use the one passed potentially with -a
2310 my ($pbac) = pb_conf_get($vtype."login");
2311 my ($key,$zero0,$zero1,$zero2);
2312 my ($vmexist,$vmpid);
2313
2314 # Prepare the script to be executed on the VM/VE
2315 # in $ENV{'PBDESTDIR'}/setupv
2316 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
2317
2318 print SCRIPT << 'EOF';
2319#!/usr/bin/perl -w
2320
2321use strict;
2322use File::Copy;
2323
2324# We should not need in this script more functions than what is provided
2325# by Base and Distribution to avoid problems at exec time.
2326# They are appended at the end.
2327
2328our $pbdebug;
2329our $pbLOG;
2330our $pbsynmsg = "pbscript";
2331our $pbdisplaytype = "text";
2332our $pblocale = "";
2333pb_log_init($pbdebug, $pbLOG);
2334pb_temp_init();
2335
2336EOF
2337
2338 # Launch the VM/VE - Usage of snapshot disabled
2339 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0,0,0);
2340
2341 if ($vtype eq "vm") {
2342 # Prepare the key to be used and transfered remotely
2343 my $keyfile = pb_ssh_get(1);
2344
2345 my ($vmhost,$vmport,$vmntp) = pb_conf_get("vmhost","vmport","vmntp");
2346 my $nport = $vmport->{$ENV{'PBPROJ'}};
2347 $nport = "$pbport" if (defined $pbport);
2348
2349 # Skip that VM if something went wrong
2350 next if (($vmpid == 0) && ($vmexist == 0));
2351
2352 # Store the pub key part in a variable
2353 open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
2354 ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
2355 close(FILE);
2356
2357 $key = "\Q$zero1";
2358
2359 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 ; if [ -x /usr/bin/chcon ]; then /usr/bin/chcon -Rt home_ssh_t .ssh 2> /dev/null; fi\"","Copying local keys to $vtype. This may require the root password");
2360 # once this is done, we can do what we want on the VM remotely
2361 } elsif ($vtype eq "ve") {
2362 print SCRIPT << "EOF";
2363# For VE we need a good null dev
2364pb_system("rm -f /dev/null; mknod /dev/null c 1 3; chmod 777 /dev/null");
2365EOF
2366 print SCRIPT << "EOF";
2367# For VE we first need to mount some FS
2368pb_system("mount -t proc /proc /proc");
2369
2370EOF
2371 }
2372
2373if ($vtype eq "vm") {
2374 print SCRIPT << 'EOF';
2375# Removes duplicate in .ssh/authorized_keys of our key if needed
2376#
2377my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
2378open(PBFILE,$file1) || die "Unable to open $file1";
2379open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
2380my $count = 0;
2381while (<PBFILE>) {
2382
2383EOF
2384 print SCRIPT << "EOF";
2385 if (/ $key /) {
2386 \$count++;
2387 }
2388print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
2389}
2390close(PBFILE);
2391close(PBOUT);
2392rename("\$file1.new",\$file1);
2393chmod 0600,\$file1;
2394
2395# Sync date
2396EOF
2397 if (defined $ntpline) {
2398 print SCRIPT "pb_system(\"$ntpline\");\n";
2399 } else {
2400 print SCRIPT "pb_system(\"$dateline\");\n";
2401 }
2402 }
2403 print SCRIPT << 'EOF';
2404
2405# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
2406#
2407my $file="/etc/passwd";
2408open(PBFILE,$file) || die "Unable to open $file";
2409my $found = 0;
2410while (<PBFILE>) {
2411EOF
2412 print SCRIPT << "EOF";
2413 \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
2414EOF
2415
2416my $home = "/home";
2417# Solaris doesn't like that we use /home
2418$home = "/export/home" if ($dtype eq "pkg");
2419
2420 print SCRIPT << "EOF";
2421}
2422close(PBFILE);
2423
2424if ( \$found == 0 ) {
2425 if ( ! -d "$home" ) {
2426 pb_mkdir_p("$home");
2427 }
2428EOF
2429 print SCRIPT << "EOF";
2430pb_system("/usr/sbin/groupadd $pbac->{$ENV{'PBPROJ'}}","Adding group $pbac->{$ENV{'PBPROJ'}}");
2431pb_system("/usr/sbin/useradd -g $pbac->{$ENV{'PBPROJ'}} -m -d $home/$pbac->{$ENV{'PBPROJ'}} $pbac->{$ENV{'PBPROJ'}}","Adding user $pbac->{$ENV{'PBPROJ'}} (group $pbac->{$ENV{'PBPROJ'}} - home $home/$pbac->{$ENV{'PBPROJ'}})");
2432}
2433EOF
2434
2435 # Copy the content of our local conf file to the VM/VE
2436 my $content = pb_get_content(pb_distro_conffile());
2437 print SCRIPT << "EOF";
2438 #
2439 # Create a temporary local conf file for distribution support
2440 # This is created here before its use later. Its place is hardcoded, so no choice for the path
2441 #
2442 my \$tempconf = pb_distro_conffile();
2443 pb_mkdir_p(dirname(\$tempconf));
2444 open(CONF,"> \$tempconf") || die "Unable to create \$tempconf";
2445 print CONF q{$content};
2446 close(CONF);
2447EOF
2448
2449 if ($vtype eq "vm") {
2450 print SCRIPT << "EOF";
2451# allow ssh entry to build
2452#
2453mkdir "$home/$pbac->{$ENV{'PBPROJ'}}/.ssh",0700;
2454# Allow those accessing root to access the build account
2455copy("\$ENV{'HOME'}/.ssh/authorized_keys","$home/$pbac->{$ENV{'PBPROJ'}}/.ssh/authorized_keys");
2456chmod 0600,".ssh/authorized_keys";
2457pb_system("chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} $home/$pbac->{$ENV{'PBPROJ'}}","Finish setting up the account env for $pbac->{$ENV{'PBPROJ'}}");
2458
2459EOF
2460}
2461 print SCRIPT << 'EOF';
2462# No passwd for build account only keys
2463$file="/etc/shadow";
2464if (-f $file) {
2465 open(PBFILE,$file) || die "Unable to open $file";
2466 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
2467 while (<PBFILE>) {
2468EOF
2469 print SCRIPT << "EOF";
2470 s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
2471 s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
2472 s/^$pbac->{$ENV{'PBPROJ'}}:\\*LK\\*:/$pbac->{$ENV{'PBPROJ'}}:NP:/; #Solaris e.g.
2473EOF
2474 print SCRIPT << 'EOF';
2475 print PBOUT $_;
2476 }
2477 close(PBFILE);
2478 close(PBOUT);
2479 rename("$file.new",$file);
2480 chmod 0640,$file;
2481 }
2482
2483# Keep the VM in text mode
2484$file="/etc/inittab";
2485if (-f $file) {
2486 open(PBFILE,$file) || die "Unable to open $file";
2487 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
2488 while (<PBFILE>) {
2489 s/^(..):5:initdefault:$/$1:3:initdefault:/;
2490 print PBOUT $_;
2491 }
2492 close(PBFILE);
2493 close(PBOUT);
2494 rename("$file.new",$file);
2495 chmod 0640,$file;
2496}
2497
2498# pb has to be added to portage group on gentoo
2499
2500# We need to have that pb_distro_init function
2501# Get it from Project-Builder::Distribution
2502# And we now need the conf file required for this to work created above
2503
2504my ($ddir, $dver, $dfam, $dtype, $dos, $pbsuf, $pbupd, $darch) = pb_distro_init();
2505print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf, $darch))."\n";
2506
2507# Adapt sudoers
2508# sudo is not default on Solaris and needs to be installed first
2509# from http://www.sunfreeware.com/programlistsparc10.html#sudo
2510if ($dtype eq "pkg") {
2511 $file="/usr/local/etc/sudoers";
2512} else {
2513 $file="/etc/sudoers";
2514}
2515open(PBFILE,$file) || die "Unable to open $file";
2516open(PBOUT,"> $file.new") || die "Unable to open $file.new";
2517while (<PBFILE>) {
2518EOF
2519 print SCRIPT << "EOF";
2520 next if (/^$pbac->{$ENV{'PBPROJ'}} /);
2521EOF
2522 print SCRIPT << 'EOF';
2523 s/Defaults[ \t]+requiretty//;
2524 print PBOUT $_;
2525}
2526close(PBFILE);
2527EOF
2528 print SCRIPT << "EOF";
2529# Some distro force requiretty at compile time, so disable here
2530print PBOUT "Defaults:$pbac->{$ENV{'PBPROJ'}} !requiretty\n";
2531print PBOUT "Defaults:root !requiretty\n";
2532# This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
2533print PBOUT "Defaults:$pbac->{$ENV{'PBPROJ'}} env_keep += \\\"http_proxy ftp_proxy\\\"\n";
2534print PBOUT "$pbac->{$ENV{'PBPROJ'}} ALL=(ALL) NOPASSWD:ALL\n";
2535EOF
2536 print SCRIPT << 'EOF';
2537close(PBOUT);
2538rename("$file.new",$file);
2539chmod 0440,$file;
2540
2541EOF
2542
2543 # We may need a proxy configuration. Get it from the local env
2544
2545 if (defined $ENV{'http_proxy'}) {
2546 print SCRIPT "\$ENV\{'http_proxy'\}=\"$ENV{'http_proxy'}\";\n";
2547 }
2548
2549 if (defined $ENV{'ftp_proxy'}) {
2550 print SCRIPT "\$ENV\{'ftp_proxy'\}=\"$ENV{'ftp_proxy'}\";\n";
2551 }
2552
2553 print SCRIPT << 'EOF';
2554
2555 my ($ospkgdep,$osperldep,$osperlver) = pb_conf_get_if("ospkgdep","osperldep","osperlver");
2556
2557 # First install all required packages
2558 pb_system("yum clean all","Cleaning yum env") if (($ddir eq "fedora") || ($ddir eq "asianux") || ($ddir eq "rhel"));
2559 my $pkgdep = pb_distro_get_param($ddir,$dver,$darch,$ospkgdep,$dfam,$dtype,$dos);
2560 pb_distro_installdeps(undef,$dtype,$pbupd,pb_distro_only_deps_needed($dtype,join(' ',split(/,/,$pkgdep))));
2561
2562 # Then install manually the missing perl modules
2563 my $perldep = pb_distro_get_param($ddir,$dver,$darch,$osperldep,$dfam,$dtype,$dos);
2564 foreach my $m (split(/,/,$perldep)) {
2565 # Skip empty deps
2566 next if ($m =~ /^\s*$/);
2567 my $dir = $m;
2568 $dir =~ s/-.*//;
2569 pb_system("echo \"rm -rf $m* ; wget http://search.cpan.org/CPAN/modules/by-module/$dir/$m-$osperlver->{$m}.tar.gz ; gzip -cd $m-$osperlver->{$m}.tar.gz | tar xf - ; cd $m* ; if [ -f Build.PL ]; then perl Build.PL; ./Build ; ./Build install ; else perl Makefile.PL; make ; make install ; fi; cd .. ; rm -rf $m*\" | bash" ,"Installing perl module $m-$osperlver->{$m}");
2570 }
2571
2572# Suse wants sudoers as 640
2573if ((($ddir eq "sles") && (($dver =~ /10/) || ($dver =~ /9/))) || (($ddir eq "opensuse") && ($dver =~ /10.[012]/))) {
2574 chmod 0640,$file;
2575}
2576
2577pb_system("rm -rf ProjectBuilder-* ; wget --passive-ftp ftp://ftp.mondorescue.org/src/ProjectBuilder-latest.tar.gz ; gzip -cd ProjectBuilder-latest.tar.gz | tar xf - ; cd ProjectBuilder-* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf ProjectBuilder-* ; rm -rf project-builder-* ; wget --passive-ftp ftp://ftp.mondorescue.org/src/project-builder-latest.tar.gz ; gzip -cd project-builder-latest.tar.gz | tar xf - ; cd project-builder-* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf project-builder-* ;","Building Project-Builder");
2578pb_system("pb 2>&1 | head -5",undef,"verbose");
2579EOF
2580 if ($vtype eq "ve") {
2581 print SCRIPT << 'EOF';
2582# For VE we need to umount some FS at the end
2583
2584pb_system("umount /proc");
2585
2586# Create a basic network file if not already there
2587
2588my $nf="/etc/sysconfig/network";
2589if ((! -f $nf) && ($dtype eq "rpm")) {
2590 open(NF,"> $nf") || die "Unable to create $nf";
2591 print NF "NETWORKING=yes\n";
2592 print NF "HOSTNAME=localhost\n";
2593 close(NF);
2594}
2595chmod 0755,$nf;
2596EOF
2597 }
2598
2599 # Adds pb_distro_init and all functions needed from ProjectBuilder::Distribution and Base
2600 foreach my $d (@INC) {
2601 my @f = ("$d/ProjectBuilder/Base.pm","$d/ProjectBuilder/Distribution.pm","$d/ProjectBuilder/Conf.pm");
2602 foreach my $f (@f) {
2603 if (-f "$f") {
2604 open(PBD,"$f") || die "Unable to open $f";
2605 while (<PBD>) {
2606 next if (/^package/);
2607 next if (/^use Exporter/);
2608 next if (/^use ProjectBuilder::/);
2609 next if (/^our /);
2610 print SCRIPT $_;
2611 }
2612 close(PBD);
2613 }
2614 }
2615 }
2616 close(SCRIPT);
2617 chmod 0755,"$pbscript";
2618
2619 # That build script needs to be run as root and force stop of VM at end
2620 $pbaccount = "root";
2621
2622 # Force shutdown of VM exept if it was already launched
2623 my $pbforce = 0;
2624 if ((! $vmexist) && ($vtype eq "vm")) {
2625 $pbforce = 1;
2626 }
2627
2628 pb_script2v($pbscript,$vtype,$pbforce,$v);
2629}
2630return;
2631}
2632
2633# Function to create a snapshot named 'pb' for VMs and a compressed tar for VEs
2634sub pb_snap2v {
2635
2636my $vtype = shift;
2637
2638my ($vm,$all) = pb_get2v($vtype);
2639
2640# Script generated
2641my $pbscript = "$ENV{'PBDESTDIR'}/snapv";
2642
2643my ($pbac) = pb_conf_get($vtype."login");
2644
2645foreach my $v (@$vm) {
2646 # Get distro context
2647 my ($name,$ver,$darch) = split(/-/,$v);
2648 chomp($darch);
2649 my ($ddir, $dver, $dfam, $dtype, $dos, $pbsuf) = pb_distro_init($name,$ver,$darch);
2650 my ($vepath) = pb_conf_get("vepath");
2651
2652 # Test if an existing snapshot exists and remove it if there is a VE
2653 if ((-f "$vepath->{$ENV{'PBPROJ'}}/$ddir-$dver-$darch.tar.gz") &&
2654 (! -d "$vepath->{$ENV{'PBPROJ'}}/$ddir/$dver/$darch")) {
2655 pb_system("sudo rm -f $vepath->{$ENV{'PBPROJ'}}/$ddir-$dver-$darch.tar.gz","Removing previous snapshot $ddir-$dver-$darch.tar.gz");
2656 }
2657
2658 # Name of the account to deal with for VM/VE
2659 # Do not use the one passed potentially with -a
2660 my ($vmexist,$vmpid);
2661
2662 # Prepare the script to be executed on the VM/VE
2663 # in $ENV{'PBDESTDIR'}/setupv
2664 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
2665
2666 print SCRIPT << 'EOF';
2667 #!/bin/bash
2668 sleep 2
2669EOF
2670 close(SCRIPT);
2671 chmod 0755,"$pbscript";
2672
2673 # Force shutdown of VM/VE
2674 # Force snapshot of VM/VE
2675 pb_script2v($pbscript,$vtype,1,$v,1);
2676}
2677return;
2678}
2679
2680sub pb_announce {
2681
2682 # Get all required parameters
2683 my ($pbpackager,$pbrepo,$pbml,$pbsmtp) = pb_conf_get("pbpackager","pbrepo","pbml","pbsmtp");
2684 my ($pkgv, $pkgt, $testver) = pb_conf_get_if("pkgver","pkgtag","testver");
2685 my $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
2686 my @pkgs = @$pkg;
2687 my %pkgs;
2688 my $first = 0;
2689
2690 # Command to find packages on repo
2691 my $findstr = "find . ";
2692 # Generated announce files
2693 my @files;
2694
2695 foreach my $pbpkg (@pkgs) {
2696 if ($first != 0) {
2697 $findstr .= "-o ";
2698 }
2699 $first++;
2700 if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
2701 $pbver = $pkgv->{$pbpkg};
2702 } else {
2703 $pbver = $ENV{'PBPROJVER'};
2704 }
2705 if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
2706 $pbtag = $pkgt->{$pbpkg};
2707 } else {
2708 $pbtag = $ENV{'PBPROJTAG'};
2709 }
2710
2711 # TODO: use virtual/real names here now
2712 $findstr .= "-name \'$pbpkg-$pbver-$pbtag\.*.rpm\' -o -name \'$pbpkg"."_$pbver*\.deb\' -o -name \'$pbpkg-$pbver*\.ebuild\' ";
2713
2714 my $chglog;
2715
2716 # Get project info on log file and generate tmp files used later on
2717 pb_cms_init($pbinit);
2718 $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
2719 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
2720 $chglog = undef if (! -f $chglog);
2721
2722 open(OUT,"> $ENV{'PBTMP'}/$pbpkg.ann") || die "Unable to create $ENV{'PBTMP'}/$pbpkg.ann: $!";
2723 my %pb;
2724 $pb{'dtype'} = "announce";
2725 $pb{'realpkg'} = $pbpkg;
2726 $pb{'ver'} = $pbver;
2727 $pb{'tag'} = $pbtag;
2728 $pb{'suf'} = "N/A"; # Should not be empty even if unused
2729 $pb{'date'} = $pbdate;
2730 $pb{'chglog'} = $chglog;
2731 $pb{'packager'} = $pbpackager;
2732 $pb{'proj'} = $ENV{'PBPROJ'};
2733 $pb{'repo'} = $pbrepo;
2734 pb_changelog(\%pb,\*OUT,"yes");
2735 close(OUT);
2736 push(@files,"$ENV{'PBTMP'}/$pbpkg.ann");
2737 }
2738 $findstr .= " | grep -Ev \'src.rpm\'";
2739
2740 # Prepare the command to run and execute it
2741 open(PBS,"> $ENV{'PBTMP'}/pbscript") || die "Unable to create $ENV{'PBTMP'}/pbscript";
2742 print PBS "$findstr\n";
2743 close(PBS);
2744 chmod 0755,"$ENV{'PBTMP'}/pbscript";
2745 pb_send2target("Announce");
2746
2747 # Get subject line
2748 my $sl = "Project $ENV{'PBPROJ'} version $ENV{'PBPROJVER'} is now available";
2749 pb_log(0,"Please enter the title of your announce\n");
2750 pb_log(0,"(By default: $sl)\n");
2751 my $sl2 = <STDIN>;
2752 $sl = $sl2 if ($sl2 !~ /^$/);
2753
2754 # Prepare a template of announce
2755 open(ANN,"> $ENV{'PBTMP'}/announce.html") || die "Unable to create $ENV{'PBTMP'}/announce.html: $!";
2756 print ANN << "EOF";
2757$sl</p>
2758
2759<p>The project team is happy to announce the availability of a newest version of $ENV{'PBPROJ'} $ENV{'PBPROJVER'}. Enjoy it as usual!</p>
2760<p>
2761Now available at <a href="$pbrepo->{$ENV{'PBPROJ'}}">$pbrepo->{$ENV{'PBPROJ'}}</a>
2762</p>
2763<p>
2764EOF
2765 open(LOG,"$ENV{'PBTMP'}/system.log") || die "Unable to read $ENV{'PBTMP'}/system.log: $!";
2766 my $col = 2;
2767 my $i = 1;
2768 print ANN << 'EOF';
2769<TABLE WIDTH="700" CELLPADDING="0" CELLSPACING="0" BORDER="0">
2770<TR>
2771EOF
2772 while (<LOG>) {
2773 print ANN "<TD><A HREF=\"$pbrepo->{$ENV{'PBPROJ'}}/$_\">$_</A></TD>";
2774 $i++;
2775 if ($i > $col) {
2776 print ANN "</TR>\n<TR>";
2777 $i = 1;
2778 }
2779 }
2780 close(LOG);
2781 print ANN << "EOF";
2782</TR>
2783</TABLE>
2784</p>
2785
2786<p>As usual source packages are also available in the same directory.</p>
2787
2788<p>
2789Changes are :
2790</p>
2791<p>
2792EOF
2793 # Get each package changelog content
2794 foreach my $f (sort(@files)) {
2795 open(IN,"$f") || die "Unable to read $f:$!";
2796 while (<IN>) {
2797 print ANN $_;
2798 }
2799 close(IN);
2800 print ANN "</p><p>\n";
2801 }
2802 print ANN "</p>\n";
2803 close(ANN);
2804
2805 # Allow for modification
2806 my $editor = "vi";
2807 $editor = $ENV{'EDITOR'} if (defined $ENV{'EDITOR'});
2808 pb_system("$editor $ENV{'PBTMP'}/announce.html","Allowing modification of the announce","noredir");
2809
2810 # Store it in DB for external usage (Web pages generation)
2811 my $db = "$ENV{'PBCONFDIR'}/announces3.sql";
2812
2813 my $precmd = "";
2814 if (! -f $db) {
2815 $precmd = "CREATE TABLE announces (id INTEGER PRIMARY KEY AUTOINCREMENT, date DATE, announce VARCHAR[65535])";
2816 }
2817
2818 my $dbh = DBI->connect("dbi:SQLite:dbname=$db","","",
2819 { RaiseError => 1, AutoCommit => 1 })
2820 || die "Unable to connect to $db";
2821
2822 if ($precmd ne "") {
2823 my $sth = $dbh->prepare(qq{$precmd})
2824 || die "Unable to create table into $db";
2825 $sth->execute();
2826 }
2827
2828 # To read whole file
2829 local $/;
2830 open(ANN,"$ENV{'PBTMP'}/announce.html") || die "Unable to read $ENV{'PBTMP'}/announce.html: $!";
2831 my $announce = <ANN>;
2832 close(ANN);
2833
2834 pb_log(2,"INSERT INTO announces VALUES (NULL, $pbdate, $announce)");
2835 my $sth = $dbh->prepare(qq{INSERT INTO announces VALUES (NULL,?,?)})
2836 || die "Unable to insert into $db";
2837 $sth->execute($pbdate, $announce);
2838 $sth->finish();
2839 $dbh->disconnect;
2840
2841 # Then deliver it on the Web
2842 # $TOOLHOME/livwww www
2843
2844 # Mail it to project's ML
2845 open(ML,"| w3m -dump -T text/html > $ENV{'PBTMP'}/announce.txt") || die "Unable to create $ENV{'PBTMP'}/announce.txt: $!";
2846 print ML << 'EOF';
2847<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/x html1/DTD/xhtml1-strict.dtd">
2848
2849<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" xml:lang="en" lang="en">
2850 <head>
2851 </head>
2852 <body>
2853 <p>
2854EOF
2855 open(ANN,"$ENV{'PBTMP'}/announce.html") || die "Unable to read $ENV{'PBTMP'}/announce.html: $!";
2856 while(<ANN>) {
2857 print ML $_;
2858 }
2859 print ML << 'EOF';
2860</body>
2861</html>
2862EOF
2863 close(ML);
2864
2865 # To read whole file
2866 local $/;
2867 open(ANN,"$ENV{'PBTMP'}/announce.txt") || die "Unable to read $ENV{'PBTMP'}/announce.txt: $!";
2868 my $msg = <ANN>;
2869 close(ANN);
2870
2871 # Preparation of headers
2872
2873 my %mail = (
2874 To => $pbml->{$ENV{'PBPROJ'}},
2875 From => $pbpackager->{$ENV{'PBPROJ'}},
2876 Smtp => $pbsmtp->{$ENV{'PBPROJ'}},
2877 Body => $msg,
2878 Subject => "[ANNOUNCE] $sl",
2879 );
2880
2881 # Send mail
2882 sendmail(%mail) or die "Unable to send mail ($Mail::Sendmail::error): $Mail::Sendmail::log";
2883}
2884
2885#
2886# Creates a set of HTML file containing the news for the project
2887# based on what has been generated by the pb_announce function
2888#
2889sub pb_web_news2html {
2890
2891 my $dest = shift || $ENV{'PBTMP'};
2892
2893 # Get all required parameters
2894 my ($pkgv, $pkgt) = pb_conf_get_if("pkgver","pkgtag");
2895
2896 # DB of announces for external usage (Web pages generation)
2897 my $db = "$ENV{'PBCONFDIR'}/announces3.sql";
2898
2899 my $dbh = DBI->connect("dbi:SQLite:dbname=$db","","",
2900 { RaiseError => 1, AutoCommit => 1 })
2901 || die "Unable to connect to $db";
2902 # For date handling
2903 $ENV{LANGUAGE}="C";
2904 my $firstjan = strftime("%Y-%m-%d", 0, 0, 0, 1, 0, localtime->year(), 0, 0, -1);
2905 my $oldfirst = strftime("%Y-%m-%d", 0, 0, 0, 1, 0, localtime->year()-1, 0, 0, -1);
2906 pb_log(2,"firstjan: $firstjan, oldfirst: $oldfirst, pbdate:$pbdate\n");
2907 my $all = $dbh->selectall_arrayref("SELECT id,date,announce FROM announces ORDER BY date DESC");
2908 my %news;
2909 $news{"cy"} = ""; # current year's news
2910 $news{"ly"} = ""; # last year news
2911 $news{"py"} = ""; # previous years news
2912 $news{"fp"} = ""; # first page news
2913 my $cpt = 4; # how many news for first page
2914 # Extract info from DB
2915 foreach my $row (@$all) {
2916 my ($id, $date, $announce) = @$row;
2917 $news{"cy"} = $news{"cy"}."<p><B>$date</B> $announce\n" if ((($date cmp $pbdate) le 0) && (($firstjan cmp $date) le 0));
2918 $news{"ly"} = $news{"ly"}."<p><B>$date</B> $announce\n" if ((($date cmp $firstjan) le 0) && (($oldfirst cmp $date) le 0));
2919 $news{"py"} = $news{"py"}."<p><B>$date</B> $announce\n" if (($date cmp $oldfirst) le 0);
2920 $news{"fp"} = $news{"fp"}."<p><B>$date</B> $announce\n" if ($cpt > 0);
2921 $cpt--;
2922 }
2923 pb_log(1,"news{fp}: ".$news{"fp"}."\n");
2924 $dbh->disconnect;
2925
2926 # Generate the HTML content
2927 foreach my $pref (keys %news) {
2928 open(NEWS,"> $dest/pb_web_$pref"."news.html") || die "Unable to create $dest/pb_web_$pref"."news.html: $!";
2929 print NEWS "$news{$pref}";
2930 close(NEWS);
2931 }
2932}
2933
2934
2935# Return the SSH key file to use
2936# Potentially create it if needed
2937
2938sub pb_ssh_get {
2939
2940my $create = shift || 0; # Do not create keys by default
2941
2942# Check the SSH environment
2943my $keyfile = undef;
2944
2945# We have specific keys by default
2946$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
2947if (!(-e $keyfile) && ($create eq 1)) {
2948 pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
2949}
2950
2951$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
2952$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
2953$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
2954die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
2955return($keyfile);
2956}
2957
2958
2959# Returns the pid of a running VM command using a specific VM file
2960sub pb_check_ps {
2961 my $vmcmd = shift;
2962 my $vmm = shift;
2963 my $vmexist = 0; # FALSE by default
2964
2965 open(PS, "ps auxhww|") || die "Unable to call ps";
2966 while (<PS>) {
2967 next if (! /$vmcmd/);
2968 next if (! /$vmm/);
2969 my ($void1, $void2);
2970 ($void1, $vmexist, $void2) = split(/ +/);
2971 last;
2972 }
2973 return($vmexist);
2974}
2975
2976
2977sub pb_extract_build_files {
2978
2979my $src=shift;
2980my $dir=shift;
2981my $ddir=shift;
2982my $mandatory=shift || "spec";
2983my @files;
2984
2985my $flag = "mayfail" if ($mandatory eq "patch");
2986my $res;
2987
2988if ($src =~ /tar\.gz$/) {
2989 $res = pb_system("tar xfpz $src $dir","Extracting $mandatory files from $src",$flag);
2990} elsif ($src =~ /tar\.bz2$/) {
2991 $res = pb_system("tar xfpj $src $dir","Extracting $mandatory files from $src",$flag);
2992} else {
2993 die "Unknown compression algorithm for $src";
2994}
2995# If not mandatory return now
2996return() if (($res != 0) and ($mandatory eq "patch"));
2997opendir(DIR,"$dir") || die "Unable to open directory $dir";
2998foreach my $f (readdir(DIR)) {
2999 next if ($f =~ /^\./);
3000 # Skip potential patch dir
3001 next if ($f =~ /^pbpatch/);
3002 move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
3003 pb_log(2,"mv $dir/$f $ddir\n");
3004 push @files,"$ddir/$f";
3005}
3006closedir(DIR);
3007# Not enough but still a first cleanup
3008pb_rm_rf("$dir");
3009return(@files);
3010}
3011
3012sub pb_list_bfiles {
3013
3014my $dir = shift;
3015my $pbpkg = shift;
3016my $bfiles = shift;
3017my $pkgfiles = shift;
3018my $supfiles = shift;
3019
3020opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
3021foreach my $f (readdir(BDIR)) {
3022 next if ($f =~ /^\./);
3023 if (-d $f) {
3024 # Recurse for directories (Debian 3.0 format e.g.)
3025 pb_list_bfiles($f,$pbpkg,$bfiles,$pkgfiles,$supfiles);
3026 next;
3027 }
3028 $bfiles->{$f} = "$dir/$f";
3029 $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
3030 if (defined $supfiles->{$pbpkg}) {
3031 $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
3032 }
3033}
3034closedir(BDIR);
3035}
3036
3037
3038#
3039# Return the list of packages we are working on in a non CMS action
3040#
3041sub pb_get_pkg {
3042
3043my @pkgs = ();
3044
3045my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
3046@pkgs = keys %$var;
3047
3048pb_log(0,"Packages: ".join(',',@pkgs)."\n");
3049return(\@pkgs);
3050}
3051
3052#
3053# Return the postinstall line if needed
3054#
3055
3056sub pb_get_postinstall {
3057
3058my $ddir = shift;
3059my $dver = shift;
3060my $darch = shift;
3061my $rbspi = shift;
3062my $vestyle = shift;
3063my $post = "";
3064
3065# Do we have a local post-install script
3066if ($vestyle eq "rinse") {
3067 $post = "--post-install ";
3068} elsif ($vestyle eq "rpmbootstrap") {
3069 $post = "-s ";
3070}
3071
3072my $postparam = pb_distro_get_param($ddir,$dver,$darch,$rbspi);
3073if ($postparam eq "") {
3074 $post = "";
3075} else {
3076 $post .= $postparam;
3077}
3078return($post);
3079}
3080
30811;
Note: See TracBrowser for help on using the repository browser.