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

Last change on this file since 1548 was 1548, checked in by Bruno Cornec, 12 years ago
  • pb: Improve error message when building but config isn't present. Pass through pb_stop_on_error when setting up a virtual environment. (Eric Andersson)
  • Property svn:executable set to *
File size: 143.1 KB
RevLine 
[5]1#!/usr/bin/perl -w
2#
3# Project Builder main application
4#
5# $Id$
6#
[1248]7# Copyright B. Cornec 2007-2011
[5]8# Provided under the GPL v2
9
[22]10# Syntax: see at end
[9]11
[18]12use strict 'vars';
[1107]13
14# The modules mentioned here are required by pb when used both
[1176]15# locally or inside a VE/VM/RM
[1107]16# Additional required modules only used locally are called with a require
17# in their respective section
[331]18use Getopt::Long qw(:config auto_abbrev no_ignore_case);
[9]19use Data::Dumper;
20use English;
[16]21use File::Basename;
[26]22use File::Copy;
[395]23use File::stat;
24use File::Temp qw(tempdir);
[872]25use File::Find;
[547]26use Time::localtime qw(localtime);
[13]27use POSIX qw(strftime);
[17]28use lib qw (lib);
[329]29use ProjectBuilder::Version;
[318]30use ProjectBuilder::Base;
[512]31use ProjectBuilder::Display;
[405]32use ProjectBuilder::Conf;
33use ProjectBuilder::Distribution;
[1469]34use ProjectBuilder::VCS;
[405]35use ProjectBuilder::CMS;
[416]36use ProjectBuilder::Env;
[405]37use ProjectBuilder::Filter;
[473]38use ProjectBuilder::Changelog;
[1348]39use ProjectBuilder::VE;
[473]40
[397]41# Global variables
[1537]42$Global::pb_stop_on_error = 1;
[5]43my %opts; # CLI Options
[9]44my $action; # action to realize
[320]45my $test = "FALSE"; # Not used
[748]46my $pbforce = 0; # Force VE/VM rebuild
[968]47my $pbsnap = 0; # Do not use snapshot mode for VM/VE by default
[1425]48my $pbkeep = 0; # keep temporary directory at the end
[320]49my $option = ""; # Not used
50my @pkgs; # list of packages
[95]51my $pbtag; # Global Tag variable
52my $pbver; # Global Version variable
[141]53my $pbscript; # Name of the script
[77]54my %pbver; # per package
55my %pbtag; # per package
[53]56my $pbrev; # Global REVISION variable
[1176]57my $pbaccount; # Login to use to connect to the VM/RM
[1401]58my $pbtarget = undef; # Target os-ver-arch you want to build for
[1176]59my $pbport; # Port to use to connect to the VM/RM
[199]60my $newver; # New version to create
[792]61my $iso = undef; # ISO image for the VM to create
[5]62
[320]63my @date = pb_get_date();
64my $pbdate = strftime("%Y-%m-%d", @date);
[5]65
[331]66=pod
67
68=head1 NAME
69
70pb, aka project-builder.org - builds packages for your projects
71
72=head1 DESCRIPTION
73
74pb helps you build various packages directly from your project sources.
75Those sources could be handled by a CMS (Configuration Management System)
[748]76such as Subversion, CVS, Git, Mercurial... or being a simple reference to a compressed tar file.
[331]77It's based on a set of configuration files, a set of provided macros to help
78you keeping build files as generic as possible. For example, a single .spec
79file should be required to generate for all rpm based distributions, even
80if you could also have multiple .spec files if required.
81
82=head1 SYNOPSIS
83
[1401]84pb [-vhSq][-r pbroot][-p project][[-s script -a account -P port][-t [os-ver-arch]][-m os-ver-arch[,...]]][-g][-i iso] <action> [<pkg1> ...]
[331]85
[1401]86pb [--verbose][--help][--man][--quiet][--snapshot][--revision pbroot][--project project][[--script script --account account --port port][--target [os-ver-arch]][--machine os-ver-arch[,...]]][--nographic][--iso iso][--rebuild] <action> [<pkg1> ...]
[331]87
88=head1 OPTIONS
89
90=over 4
91
92=item B<-v|--verbose>
93
94Print a brief help message and exits.
95
96=item B<-q|--quiet>
97
98Do not print any output.
99
100=item B<-h|--help>
101
102Print a brief help message and exits.
103
[748]104=item B<-S|--snapshot>
105
106Use the snapshot mode of VMs or VEs
107
[331]108=item B<--man>
109
110Prints the manual page and exits.
111
[1120]112=item B<-t|--target os-ver-arch>
[331]113
[1120]114Name of the target system you want to build for.
115All if none precised.
116
117=item B<-m|--machine os-ver-arch[,os-ver-arch,...]>
118
[1176]119Name of the Virtual Machines (VM), Virtual Environments (VE) or Remote Machines (RM)
120you want to build on (coma separated).
[331]121All if none precised (or use the env variable PBV).
122
123=item B<-s|--script script>
124
[1176]125Name of the script you want to execute on the related VMs/VEs/RMs.
[331]126
[1158]127=item B<-g|--nographic>
[1124]128
129Do not launch VMs in graphical mode.
130
[331]131=item B<-i|--iso iso_image>
132
133Name of the ISO image of the distribution you want to install on the related VMs.
134
135=item B<-a|--account account>
136
[1176]137Name of the account to use to connect on the related VMs/RMs.
[331]138
139=item B<-P|--port port_number>
140
[1176]141Port number to use to connect on the related VMs/RMs.";
[331]142
143=item B<-p|--project project_name>
144
145Name of the project you're working on (or use the env variable PBPROJ)
146
147=item B<-r|--revision revision>
148
149Path Name of the project revision under the CMS (or use the env variable PBROOT)
150
151=item B<-V|--version new_version>
152
153New version of the project to create based on the current one.
154
[1425]155=item B<-k|--keep>
156
157Keep the temporary dir where files have been created in or der to help debug
158
[1386]159=item B<--rebuild>
160
161Only valid with the checkssh action, it alllows to automatically relaunch the build of the failed packages
162
[1537]163=item B<--no-stop-on-error>
164
165Continue through errors with best effort.
166
[331]167=back
168
169=head1 ARGUMENTS
170
171<action> can be:
172
173=over 4
174
[1097]175=item B<sbx2build>
176
177Create tar files for the project under your CMS.
178Current state of the exported content is taken.
179CMS supported are SVN, SVK, CVS, Git and Mercurial
180parameters are packages to build
181if not using default list
182
[331]183=item B<cms2build>
184
185Create tar files for the project under your CMS.
[1097]186Current state of the CMS is taken.
187CMS supported are SVN, SVK, CVS, Git and Mercurial
[331]188parameters are packages to build
189if not using default list
190
191=item B<build2pkg>
192
193Create packages for your running distribution
194
195=item B<cms2pkg>
196
197cms2build + build2pkg
198
[1097]199=item B<sbx2pkg>
200
201sbx2build + build2pkg
202
[331]203=item B<build2ssh>
204
205Send the tar files to a SSH host
206
[1097]207=item B<sbx2ssh>
208
209sbx2build + build2ssh
210
[331]211=item B<cms2ssh>
212
213cms2build + build2ssh
214
215=item B<pkg2ssh>
216
217Send the packages built to a SSH host
218
219=item B<build2vm>
220
221Create packages in VMs, launching them if needed
222and send those packages to a SSH host once built
[1176]223VM type supported are QEMU and KVM
[331]224
225=item B<build2ve>
226
227Create packages in VEs, creating it if needed
228and send those packages to a SSH host once built
229
[1176]230=item B<build2rm>
231
232Create packages in RMs, which should pre-exist,
233and send those packages to a SSH host once built
234RM means Remote Machine, and could be a physical or Virtual one.
235This is one buildfarm integration for pb.
236
[1097]237=item B<sbx2vm>
238
239sbx2build + build2vm
240
241=item B<sbx2ve>
242
243sbx2build + build2ve
244
[1176]245=item B<sbx2rm>
246
247sbx2build + build2rm
248
[331]249=item B<cms2vm>
250
251cms2build + build2vm
252
253=item B<cms2ve>
254
255cms2build + build2ve
256
[1176]257=item B<cms2rm>
258
259cms2build + build2rm
260
[331]261=item B<launchvm>
262
263Launch one virtual machine
264
265=item B<launchve>
266
267Launch one virtual environment
268
269=item B<script2vm>
270
271Launch one virtual machine if needed
272and executes a script on it
273
274=item B<script2ve>
275
276Execute a script in a virtual environment
277
[1176]278=item B<script2rm>
279
280Execute a script on a remote machine
281
[331]282=item B<newvm>
283
284Create a new virtual machine
285
286=item B<newve>
287
288Create a new virtual environment
289
[346]290=item B<setupvm>
291
292Setup a virtual machine for pb usage
293
294=item B<setupve>
295
296Setup a virtual environment for pb usage
297
[1176]298=item B<setuprm>
299
300Setup a remote machine for pb usage
301
[1140]302=item B<sbx2setupvm>
303
304Setup a virtual machine for pb usage using the sandbox version of pb instead of the latest stable
305Reserved to dev team.
306
307=item B<sbx2setupve>
308
309Setup a virtual environment for pb usage using the sandbox version of pb instead of the latest stable
310Reserved to dev team.
311
[1176]312=item B<sbx2setuprm>
313
314Setup a remote machine for pb usage using the sandbox version of pb instead of the latest stable
315Reserved to dev team.
316
[748]317=item B<snapvm>
318
319Snapshot a virtual machine for pb usage
320
321=item B<snapve>
322
323Snapshot a virtual environment for pb usage
324
[1111]325=item B<updatevm>
326
327Update the distribution in the virtual machine
328
329=item B<updateve>
330
331Update the distribution in the virtual environment
332
[1176]333=item B<updaterm>
334
335Update the distribution in the remote machine
336
[783]337=item B<test2pkg>
338
339Test a package locally
340
[772]341=item B<test2vm>
342
343Test a package in a virtual machine
344
345=item B<test2ve>
346
347Test a package in a virtual environment
348
[1176]349=item B<test2rm>
350
351Test a package in a remote machine
352
[1386]353=item B<checkssh>
354
355Check the delivery of the packages on the repository
356
[331]357=item B<newver>
358
359Create a new version of the project derived
360from the current one
361
362=item B<newproj>
363
364Create a new project and a template set of
365configuration files under pbconf
366
[471]367=item B<announce>
368
369Announce the availability of the project through various means
370
[1117]371=item B<sbx2webssh>
[557]372
[1117]373Create tar files for the website under your CMS.
374Current state of the exported content is taken.
375Deliver the content to the target server using ssh from the exported dir.
[557]376
[1117]377=item B<cms2webssh>
378
379Create tar files for the website from your CMS.
380Deliver the content to the target server using ssh from the DVCS.
381
382=item B<sbx2webpkg>
383
384Create tar files for the website under your CMS.
385Current state of the exported content is taken.
386
387=item B<cms2webpkg>
388
389Create tar files for the website under your CMS.
390
[1495]391=item B<getconf>
392
393Print the full configuration parameters as found in the various configuration files. help to debug conf issues.
394
[739]395=item B<clean>
396
397Purge the build and delivery directories related to the current project
398
[1392]399=item B<cleanssh>
400
401Purge the ssh server of its packages (only for testver and test packages)
402
403=back
404
[331]405<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).
406
407=head1 WEB SITES
408
409The 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/>.
410
411=head1 USER MAILING LIST
412
413None exists for the moment.
414
415=head1 CONFIGURATION FILES
416
417Each pb user may have a configuration in F<$HOME/.pbrc>. The values in this file may overwrite any other configuration file value.
418
419Here is an example of such a configuration file:
420
421 #
422 # Define for each project the URL of its pbconf repository
423 # No default option allowed here as they need to be all different
424 #
425 # URL of the pbconf content
426 # This is the format of a classical URL with the extension of additional schema such as
427 # svn+ssh, cvs+ssh, ...
428 #
429 pbconfurl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe/pbconf
430
431 # This is normaly defined in the project's configuration file
432 # Url of the project
433 #
434 pburl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe
435
436 # All these URLs needs to be defined here as the are the entry point
437 # for how to build packages for the project
438 #
439 pbconfurl pb = svn+ssh://svn.project-builder.org/mondo/svn/pb/pbconf
440 pbconfurl mondorescue = svn+ssh://svn.project-builder.org/mondo/svn/project-builder/mondorescue/pbconf
441 pbconfurl collectl = svn+ssh://bruno@svn.mondorescue.org/mondo/svn/project-builder/collectl/pbconf
442 pbconfurl netperf = svn+ssh://svn.mondorescue.org/mondo/svn/project-builder/netperf/pbconf
443
444 # Under that dir will take place everything related to pb
445 # If you want to use VMs/chroot/..., then use $ENV{'HOME'} to make it portable
446 # to your VMs/chroot/...
447 # if not defined then /var/cache
448 pbdefdir default = $ENV{'HOME'}/project-builder
449 pbdefdir pb = $ENV{'HOME'}
450 pbdefdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
451 pbdefdir mondorescue = $ENV{'HOME'}/mondo/svn
452
453 # pbconfdir points to the directory where the CMS content of the pbconfurl is checked out
454 # If not defined, pbconfdir is under pbdefdir/pbproj/pbconf
455 pbconfdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs/pbconf
456 pbconfdir mondorescue = $ENV{'HOME'}/mondo/svn/pbconf
457
458 # pbdir points to the directory where the CMS content of the pburl is checked out
459 # If not defined, pbdir is under pbdefdir/pbproj
460 # Only defined if we have access to the dev of the project
461 pbdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
462 pbdir mondorescue = $ENV{'HOME'}/mondo/svn
463
464 # -daemonize doesn't work with qemu 0.8.2
465 vmopt default = -m 384
466
[1537]467=head1 COMMAND DETAILS
468
469=head2 newproj
470
471The newproj command creates a new project-builder project. To run this command you first need to define two variables in your ~/.pbrc file:
472
473 pbconfurl I<project> = file:///home/anderse/.git/project-builder-config/I<project>
474 pbdefdir default = $ENV{HOME}/cache-project-builder
475
476The first line defines the version controlled configuration information and the second defines the root directory for project-builder to use.
477
478You can then run the command:
479
480 % pb -p I<$project> -r I<$version> newproj
481
482to create the new project. Running the newproj command will then generate the file $pbdefdir/$project/pbconf/$version/$project.pb. You will need to edit that file in order to run any of the later commands.
483
484=head2 cms2build
485
486The cms2build command takes your files from the content management system and makes the two tar files that are necessary for building files. Before running this command, you need to run the newproj command, and edit the $project.pb configuration file. In particular, you need to set the pburl, pbrepo, pbwf, pbpackager, projver, projtag, testver, deliver, and defpkgdir lines as described in the configuration file. Then you can run a command like:
487
488 % pb -p $project -r $version cms2build
489
490To create the $pbdefdir/$project/delivery/$project-$version.{,pbconf}.tar.gz files, the $version-$projtag.pb and pbrc files in the same directory.
491
492=head2 build2pkg
493
[1542]494The build2pkg command takes the tar files created in the cms2build step and attempts to build the binary packages for your current operating system. In order for this step to work, you may need to edit the files in one of the $pbdefdir/$project/pbconf/$version/$project/{deb,rpm,pkg} directories. Those files will be used to try to build your package. Note that if you change those files, you need to re-run the cms2build step. Then you can run a command like:
[1537]495
[1542]496 % pb -p $project -r $version build2pkg
[1537]497
[1542]498To create the files in $project/build that comprise your binary package(s).
499
500=head2 newve
501
502The newve command creates a new virtual environment, i.e. a chrooted OS for building packages. Using a virtual environment is an efficient way to build packages on a related set of operating systems. The OS's have to be related because the kernel will be shared. Steps:
503
504=over 4
505
506=item Update ~/.pbrc
507
508Update your ~/.pbrc file to specify the vepath, velist, velogin, and vetype variables, e.g.:
509
510 vepath default = $ENV{HOME}/cache-project-builder/chroot
511 velist default = debian-6.0-i386
512 velogin default = pb
513 vetype default = chroot
514
515You may also choose to specify a mirror for the OS packages, and optionally http/ftp proxies. You can specify the proxies either through environment variables ($http_proxy/$ftp_proxy) or in the configuration file. The configuration file will be used if no corresponding environment variable has been set. For example, for debian and with a local squid proxy:
516
517 rbsmirrorsrv debian = http://mirrors1.kernel.org/debian/
518 http_proxy default = http://localhost:3128/
519 ftp_proxy default = http://localhost:3128/
520
521=item Run the cms2build command
522
523If you have deleted your $package/delivery directory, re-run the cms2build command as in the earlier step. This step is necessary to generate the I<package>/delivery/pbrc file.
524
525=item Create the new virtual environment
526
527Initialize the new operating system. This step will install the core OS packages for the virtual environment, e.g.:
528
529 % pb -v -p $project -m debian-6.0-i386 newve
530
531=back
532
533=head2 setupve
534
[1545]535The setupve command prepares a virtual environment for use by project builder. In particular it installs project-builder from the packages into the virtual environment. Two sub-steps are necessary:
[1542]536
[1545]537=over 4
538
539=item Update $project.pb
540
541You need to have a sshhost entry for setupve to work, so add one, even an invalid one, e.g.:
542
543 sshhost $project = foo.example.org
544
545=item Setup the virtual environment
546
[1542]547 % pb -v -p $project -m debian-6.0-i386 setupve
548
549If you prefer to install the current SVN version of project builder, you can substitute the setupve option by the sbx2setupv one.
550
[1545]551=back
552
553=head2 build2ve
554
555The build2ve command is similar to the build2pkg command in that it will take the sources created by cms2build and turn them into binary packages. The command has two differences. First, it creates the packages in a virtual environment, i.e. the one made by an earlier setupve setup. Second it copies the resulting packages to a repository and builds the repository meta-data needed.
556
557Two sub-steps are needed:
558
559=over 4
560
561=item Update $project.pb
562
563You need to have a valid sshdir and sshhost entry for build2ve to work, so add them. Note that you need to be able to ssh from the host you run the command on to the repository host, preferably without needing to type in a password, so using ssh-agent or having a special passwordless project-builder ssh key will make this step easier.
564
565 sshhost $project = localhost
566 sshdir $project = $home/cache-project-builder/repos
567
568=item Build the packages and copy them to the repository
569
570 % pb -v -p $project -m debian-6.0-i386 build2ve
571
572=back
573
574*Debugging:* If the build fails (and you did not specify the --no-stop-on-error) option, then the virtual environment and scripts should still be present and configured to build the package. You can run a command like 'sudo setarch i386 chroot $path bash' in order to get into the environment. In your log you should see a command like that. From there you can go into the /home/pb directory as the pb user and run the same style of pb commands as you did when doing build2pkg. This will help you figure out what has gone wrong in the build in the virtual environment.
575
[331]576=head1 AUTHORS
577
578The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
579
580=head1 COPYRIGHT
581
582Project-Builder.org is distributed under the GPL v2.0 license
583described in the file C<COPYING> included with the distribution.
584
585=cut
586
587# ---------------------------------------------------------------------------
588
[75]589my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
[974]590my $appname = "pb";
[331]591
[397]592# Initialize the syntax string
593
[974]594pb_syntax_init("$appname (aka project-builder.org) Version $projectbuilderver-$projectbuilderrev\n");
[397]595
[331]596GetOptions("help|?|h" => \$opts{'h'},
597 "man" => \$opts{'man'},
598 "verbose|v+" => \$opts{'v'},
[748]599 "snapshot|S" => \$opts{'S'},
[331]600 "quiet|q" => \$opts{'q'},
601 "log-files|l=s" => \$opts{'l'},
602 "force|f" => \$opts{'f'},
603 "account|a=s" => \$opts{'a'},
604 "revision|r=s" => \$opts{'r'},
605 "script|s=s" => \$opts{'s'},
606 "machines|mock|m=s" => \$opts{'m'},
[1401]607 "target|t:s" => \$opts{'t'},
[1158]608 "nographic|g" => \$opts{'g'},
[331]609 "port|P=i" => \$opts{'P'},
610 "project|p=s" => \$opts{'p'},
[1386]611 "rebuild" => \$opts{'rebuild'},
[331]612 "iso|i=s" => \$opts{'i'},
[815]613 "version|V=s" => \$opts{'V'},
[1425]614 "keep|k" => \$opts{'k'},
[1537]615 "stop-on-error!" => \$Global::pb_stop_on_error,
[331]616) || pb_syntax(-1,0);
617
[21]618if (defined $opts{'h'}) {
[331]619 pb_syntax(0,1);
[21]620}
[331]621if (defined $opts{'man'}) {
622 pb_syntax(0,2);
623}
[21]624if (defined $opts{'v'}) {
[495]625 $pbdebug = $opts{'v'};
[21]626}
[320]627if (defined $opts{'f'}) {
[748]628 $pbforce=1;
[320]629}
[21]630if (defined $opts{'q'}) {
[495]631 $pbdebug=-1;
[21]632}
[748]633if (defined $opts{'S'}) {
634 $pbsnap=1;
635}
[1425]636if (defined $opts{'k'}) {
637 $pbkeep=1;
638}
[22]639if (defined $opts{'l'}) {
[495]640 open(pbLOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
641 $pbLOG = \*pbLOG;
642 $pbdebug = 0 if ($pbdebug == -1);
[22]643 }
[495]644pb_log_init($pbdebug, $pbLOG);
645pb_display_init("text","");
[315]646
[67]647# Handle root of the project if defined
648if (defined $opts{'r'}) {
[340]649 $ENV{'PBROOTDIR'} = $opts{'r'};
[67]650}
[91]651# Handle virtual machines if any
652if (defined $opts{'m'}) {
[320]653 $ENV{'PBV'} = $opts{'m'};
[91]654}
[141]655if (defined $opts{'s'}) {
656 $pbscript = $opts{'s'};
657}
[152]658if (defined $opts{'a'}) {
659 $pbaccount = $opts{'a'};
[347]660 die "option -a requires a -s script option" if (not defined $pbscript);
[152]661}
[162]662if (defined $opts{'P'}) {
663 $pbport = $opts{'P'};
664}
[199]665if (defined $opts{'V'}) {
666 $newver = $opts{'V'};
667}
[262]668if (defined $opts{'i'}) {
669 $iso = $opts{'i'};
670}
[1120]671if (defined $opts{'t'}) {
672 $pbtarget = $opts{'t'};
673}
[108]674
675# Get Action
676$action = shift @ARGV;
[331]677die pb_syntax(-1,1) if (not defined $action);
[108]678
[314]679my ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir);
[273]680my $pbinit = undef;
681$pbinit = 1 if ($action =~ /^newproj$/);
[108]682
[59]683# Handles project name if any
[108]684# And get global params
[1425]685($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) = pb_env_init($opts{'p'},$pbinit,$action,$pbkeep);
[59]686
[982]687#
688# Check for command requirements
689#
[1126]690my ($req,$opt,$pbpara) = pb_conf_get_if("oscmd","oscmdopt","pbparallel");
[1128]691pb_check_requirements($req,$opt,$appname);
[982]692
[1125]693#
694# Check if we can launch some actions in // with Parallel::ForkManager
695#
[1126]696my $pbparallel = $pbpara->{$appname} if (defined $pbpara);
697if (not defined $pbparallel) {
698 eval
699 {
700 require Sys::CPU;
701 Sys::CPU->import();
702 };
703 if ($@) {
704 # Sys::CPU not found, defaulting to 1
[1153]705 pb_log(1,"ADVISE: Install Sys::CPU to benefit from automatic parallelism optimization.\nOr use pbparallel in your pb.conf file\nOnly 1 process at a time for the moment\n");
[1126]706 $pbparallel = 1;
707 } else {
708 # Using the number of cores
709 $pbparallel = Sys::CPU::cpu_count();
[1153]710 pb_log(1,"Using parallel mode with $pbparallel processes\n");
[1126]711 }
712}
713
[1125]714eval
715{
716 require Parallel::ForkManager;
717 Parallel::ForkManager->import();
718};
719# Parallel::ForkManager not found so no // actions
720if ($@) {
721 $pbparallel = undef;
[1153]722 pb_log(1,"ADVISE: Install Parallel::ForkManager to benefit from automatic parallelism optimization.\nOnly 1 process at a time for the moment\n");
[1125]723}
724
[315]725pb_log(0,"Project: $ENV{'PBPROJ'}\n");
726pb_log(0,"Action: $action\n");
[9]727
728# Act depending on action
729if ($action =~ /^cms2build$/) {
[1097]730 pb_cms2build("CMS");
731} elsif ($action =~ /^sbx2build$/) {
732 pb_cms2build("SandBox");
[77]733} elsif ($action =~ /^build2pkg$/) {
734 pb_build2pkg();
735} elsif ($action =~ /^cms2pkg$/) {
[1097]736 pb_cms2build("CMS");
[77]737 pb_build2pkg();
[1097]738} elsif ($action =~ /^sbx2pkg$/) {
739 pb_cms2build("SandBox");
740 pb_build2pkg();
[88]741} elsif ($action =~ /^build2ssh$/) {
742 pb_build2ssh();
[220]743} elsif ($action =~ /^cms2ssh$/) {
[1097]744 pb_cms2build("CMS");
[220]745 pb_build2ssh();
[1102]746} elsif ($action =~ /^sbx2ssh$/) {
[1097]747 pb_cms2build("SandBox");
748 pb_build2ssh();
[88]749} elsif ($action =~ /^pkg2ssh$/) {
750 pb_pkg2ssh();
[1176]751} elsif ($action =~ /^build2rm$/) {
752 pb_build2v("rm","build");
[320]753} elsif ($action =~ /^build2ve$/) {
[772]754 pb_build2v("ve","build");
[91]755} elsif ($action =~ /^build2vm$/) {
[772]756 pb_build2v("vm","build");
[1176]757} elsif ($action =~ /^cms2rm$/) {
758 pb_cms2build("CMS");
759 pb_build2v("rm","build");
[320]760} elsif ($action =~ /^cms2ve$/) {
[1097]761 pb_cms2build("CMS");
[772]762 pb_build2v("ve","build");
[1176]763} elsif ($action =~ /^sbx2rm$/) {
764 pb_cms2build("SandBox");
765 pb_build2v("rm","build");
[1097]766} elsif ($action =~ /^sbx2ve$/) {
767 pb_cms2build("SandBox");
768 pb_build2v("ve","build");
[91]769} elsif ($action =~ /^cms2vm$/) {
[1097]770 pb_cms2build("CMS");
[772]771 pb_build2v("vm","build");
[1097]772} elsif ($action =~ /^sbx2vm$/) {
773 pb_cms2build("SandBox");
774 pb_build2v("vm","build");
[141]775} elsif ($action =~ /^launchvm$/) {
[320]776 pb_launchv("vm",$ENV{'PBV'},0);
777} elsif ($action =~ /^launchve$/) {
778 pb_launchv("ve",$ENV{'PBV'},0);
[142]779} elsif ($action =~ /^script2vm$/) {
[320]780 pb_script2v($pbscript,"vm");
781} elsif ($action =~ /^script2ve$/) {
782 pb_script2v($pbscript,"ve");
[1176]783} elsif ($action =~ /^script2rm$/) {
784 pb_script2v($pbscript,"rm");
[199]785} elsif ($action =~ /^newver$/) {
786 pb_newver();
[320]787} elsif ($action =~ /^newve$/) {
788 pb_launchv("ve",$ENV{'PBV'},1);
[262]789} elsif ($action =~ /^newvm$/) {
[320]790 pb_launchv("vm",$ENV{'PBV'},1);
[909]791 pb_log(0, "Please ensure that sshd is running in your VM by default\n");
792 pb_log(0, "and that it allows remote root login (PermitRootLogin yes in /etc/ssh/sshd_config)\n");
[1105]793 pb_log(0, "Also ensure that network is up, firewalling correctly configured\n");
794 pb_log(0, "and perl, sudo, ntpdate and scp/ssh installed\n");
[1072]795 pb_log(0, "You should then be able to login with ssh -p VMPORT root\@localhost (if VM started with pb)\n");
[1176]796} elsif ($action =~ /^setuprm$/) {
797 pb_setup2v("rm");
[346]798} elsif ($action =~ /^setupve$/) {
[772]799 pb_setup2v("ve");
[346]800} elsif ($action =~ /^setupvm$/) {
[772]801 pb_setup2v("vm");
[1176]802} elsif ($action =~ /^sbx2setuprm$/) {
803 die "This feature is limited to the pb project" if ($ENV{'PBPROJ'} ne $appname);
804 pb_cms2build("SandBox");
805 pb_setup2v("rm","SandBox");
[1140]806} elsif ($action =~ /^sbx2setupve$/) {
807 die "This feature is limited to the pb project" if ($ENV{'PBPROJ'} ne $appname);
808 pb_cms2build("SandBox");
809 pb_setup2v("ve","SandBox");
810} elsif ($action =~ /^sbx2setupvm$/) {
811 die "This feature is limited to the pb project" if ($ENV{'PBPROJ'} ne $appname);
812 pb_cms2build("SandBox");
813 pb_setup2v("vm","SandBox");
[1176]814} elsif ($action =~ /^updaterm$/) {
815 pb_update2v("rm");
[1111]816} elsif ($action =~ /^updateve$/) {
817 pb_update2v("ve");
818} elsif ($action =~ /^updatevm$/) {
819 pb_update2v("vm");
[748]820} elsif ($action =~ /^snapve$/) {
[772]821 pb_snap2v("ve");
[748]822} elsif ($action =~ /^snapvm$/) {
[772]823 pb_snap2v("vm");
[783]824} elsif ($action =~ /^test2pkg$/) {
825 pb_test2pkg();
[1176]826} elsif ($action =~ /^test2rm$/) {
827 pb_build2v("rm","test");
[772]828} elsif ($action =~ /^test2ve$/) {
829 pb_build2v("ve","test");
830} elsif ($action =~ /^test2vm$/) {
831 pb_build2v("vm","test");
[273]832} elsif ($action =~ /^newproj$/) {
833 # Nothing to do - already done in pb_env_init
[1495]834} elsif ($action =~ /^getconf$/) {
835 my $pbos = pb_distro_get_context();
836 pb_conf_print();
[106]837} elsif ($action =~ /^clean$/) {
[739]838 pb_clean();
[471]839} elsif ($action =~ /^announce$/) {
[498]840 # For announce only. Require avoids the systematic load of these modules
841 require DBI;
[557]842 require DBD::SQLite;
[498]843
[1386]844 pb_announce("Announce");
[1392]845} elsif ($action =~ /^cleanssh$/) {
846 pb_announce("Clean");
[1386]847} elsif ($action =~ /^checkssh$/) {
848 pb_announce("Check");
[1117]849} elsif ($action =~ /^sbx2webpkg$/) {
[547]850 require DBI;
[557]851 require DBD::SQLite;
[547]852
[1117]853 pb_cms2build("SandBox","Web");
854} elsif ($action =~ /^sbx2webssh$/) {
855 require DBI;
856 require DBD::SQLite;
857
858 pb_cms2build("SandBox","Web");
[556]859 pb_send2target("Web");
[1117]860} elsif ($action =~ /^cms2webpkg$/) {
861 require DBI;
862 require DBD::SQLite;
863
864 pb_cms2build("CMS","Web");
865} elsif ($action =~ /^cms2webssh$/) {
866 require DBI;
867 require DBD::SQLite;
868
869 pb_cms2build("CMS","Web");
870 pb_send2target("Web");
[77]871} else {
[315]872 pb_log(0,"\'$action\' is not available\n");
[331]873 pb_syntax(-2,1);
[77]874}
875
876sub pb_cms2build {
877
[556]878 my $param = shift || undef;
[1117]879 my $web = shift || undef;
[556]880
881 my $pkg;
882 my @pkgs;
[557]883 my $webdir;
[556]884
[557]885 my %pkgs;
[1186]886 my $pb; # Structure to store conf info
[557]887
[1117]888 die "pb_cms2build requires a parameter: SandBox or CMS" if (not defined $param);
[1097]889
[556]890 # If Website, then pkg is only the website
[1117]891 if (defined $web) {
[557]892 ($webdir) = pb_conf_get("webdir");
893 pb_log(2,"webdir: ".Dumper($webdir)."\n");
894 $pkgs[0] = $webdir->{$ENV{'PBPROJ'}};
[556]895 $extpkgdir = $webdir;
[557]896 pb_log(0,"Package: $pkgs[0]\n");
[556]897 } else {
898 $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
899 @pkgs = @$pkg;
900 }
901
[1097]902 my ($scheme, $uri) = pb_cms_init($pbinit,$param);
[331]903
[898]904 # We need 2 lines here
905 my ($pkgv, $pkgt, $testver) = pb_conf_get_if("pkgver","pkgtag","testver");
[174]906
[429]907 # declare packager and repo for filtering
908 my ($tmp1, $tmp2) = pb_conf_get("pbpackager","pbrepo");
909 $ENV{'PBPACKAGER'} = $tmp1->{$ENV{'PBPROJ'}};
910 $ENV{'PBREPO'} = $tmp2->{$ENV{'PBPROJ'}};
[1203]911 my ($delivery) = pb_conf_get_if("delivery");
912 $delivery->{$ENV{'PBPROJ'}} = "" if (not defined $delivery->{$ENV{'PBPROJ'}});
[174]913
[1432]914 # If we deal with a test dir, we want to keep the date in tar file and dir name
915 my $pbextdir = "";
916 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
917 $pbextdir = strftime("%Y%m%d%H%M%S", @date);
918 }
919
[27]920 foreach my $pbpkg (@pkgs) {
[115]921 $ENV{'PBPKG'} = $pbpkg;
[728]922
[98]923 if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
924 $pbver = $pkgv->{$pbpkg};
[9]925 } else {
[353]926 $pbver = $ENV{'PBPROJVER'};
[9]927 }
[1432]928 # If it's a test version, then tag == 0
[897]929 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
[1432]930 $pbtag = "0";
[728]931 $ENV{'PBPROJTAG'} = $pbtag;
932 } elsif ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
[98]933 $pbtag = $pkgt->{$pbpkg};
[9]934 } else {
[353]935 $pbtag = $ENV{'PBPROJTAG'};
[9]936 }
[95]937
[16]938 $pbrev = $ENV{'PBREVISION'};
[319]939 pb_log(0,"\n");
940 pb_log(0,"Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n");
[9]941 die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
[539]942
[1432]943 my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver$pbextdir";
[1173]944 # Create the structure if needed
945 pb_mkdir_p($dest);
[16]946 # Clean up dest if necessary. The export will recreate it
[74]947 pb_rm_rf($dest) if (-d $dest);
[9]948
949 # Export CMS tree for the concerned package to dest
950 # And generate some additional files
951 $OUTPUT_AUTOFLUSH=1;
[29]952
[9]953 # computes in which dir we have to work
[113]954 my $dir = $defpkgdir->{$pbpkg};
955 $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
[1117]956 $dir = $webdir->{$ENV{'PBPROJ'}} if (defined $web);
957 die "Variable \$dir not defined. Please report to dev team with log of a verbose run and this info ".Dumper($webdir) if (not defined $dir);
[1260]958 pb_log(2,"def:".Dumper($defpkgdir)."ext: ".Dumper($extpkgdir)."dir: $dir\n");
[9]959
[537]960 # Exporting content from CMS
[1097]961 my $sourcedir = undef;
962 my $sourceuri = $uri;
963 if ($param eq "SandBox") {
964 # Point to the local instance
965 $sourcedir = "$ENV{'PBDIR'}/$dir";
966 } else {
967 # Get it from a subdir of the URI with same version as localy but different root
[1174]968 # Only if using a real CMS
969 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
970 if (($scheme !~ /^file/) && ($scheme !~ /^(ht|f)tp/)) {
971 $sourceuri = "$ENV{'PBDIR'}/$dir";
[1260]972 $sourceuri =~ s|^$ENV{'PBPROJDIR'}/|$uri/|;
[1174]973 }
[1097]974 }
[1469]975 my $preserve = pb_vcs_export($sourceuri,$sourcedir,$dest);
[315]976
[435]977 # Generated fake content for test versions to speed up stuff
978 my $chglog;
[285]979
[448]980 # Get project info on authors and log file
[1185]981 # TODO: Make it CMS aware
[448]982 $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
983 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
984 $chglog = undef if (! -f $chglog);
[285]985
[1185]986 # TODO: Make it CMS aware
[448]987 my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
988 $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
989 $authors = "/dev/null" if (! -f $authors);
[435]990
[448]991 # Extract cms log history and store it
992 if ((defined $chglog) && (! -f "$dest/NEWS")) {
993 pb_log(2,"Generating NEWS file from $chglog\n");
994 copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
[285]995 }
[448]996 pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors,$testver);
[29]997
[21]998 my %build;
[865]999 # We want to at least build for the underlying distro
[1120]1000 # except if a target was given, in which case we only build for it
[1401]1001 # if -t was passed without target then build for the native distro.
[1177]1002 my $pbos = pb_distro_get_context($pbtarget);
[1282]1003 my $tmpl = pb_get_distros($pbos,$pbtarget);
[1120]1004
[1186]1005 # Setup $pb structure to allow filtering later on, on files using that structure
1006 $pb->{'tag'} = $pbtag;
1007 $pb->{'rev'} = $pbrev;
1008 $pb->{'ver'} = $pbver;
1009 $pb->{'pkg'} = $pbpkg;
[1192]1010 $pb->{'suf'} = $pbos->{'suffix'};
[1186]1011 $pb->{'realpkg'} = $pbpkg;
1012 $pb->{'date'} = $pbdate;
1013 $pb->{'defpkgdir'} = $defpkgdir;
1014 $pb->{'extpkgdir'} = $extpkgdir;
1015 $pb->{'chglog'} = $chglog;
[1432]1016 $pb->{'extdir'} = $pbextdir;
[1186]1017 $pb->{'packager'} = $ENV{'PBPACKAGER'};
1018 $pb->{'proj'} = $ENV{'PBPROJ'};
[1200]1019 $pb->{'repo'} = "$ENV{'PBREPO'}/$delivery->{$ENV{'PBPROJ'}}";
[1186]1020 $pb->{'patches'} = ();
1021 $pb->{'sources'} = ();
[556]1022
[1185]1023 my $tmpd = "$ENV{'PBTMP'}/cms.$$";
1024 pb_mkdir_p($tmpd) if (defined $pbparallel);
1025
1026 # Get only all.pbf filter at this stage for pbinit
1027 my $ptr = pb_get_filters($pbpkg);
1028
[556]1029 # Do not do that for website
[1117]1030 if (not defined $web) {
[665]1031 my %virt;
[1176]1032 # De-duplicate similar VM/VE/RM
[556]1033 foreach my $d (split(/,/,$tmpl)) {
[766]1034 # skip ill-formatted vms (name-ver-arch)
1035 next if ($d !~ /-/);
[665]1036 $virt{$d} = $d;
1037 }
1038
[1125]1039 # Try to use // processing here
[1350]1040 my $pm = new Parallel::ForkManager($pbparallel) if (defined $pbparallel);
[1125]1041
[1189]1042 pb_log(0,"Preparing delivery ...\n");
[1177]1043 foreach my $v (keys %virt) {
[1125]1044 $pm->start and next if (defined $pbparallel);
[1177]1045
1046 # Distro context
1047 my $pbos = pb_distro_get_context($v);
[1207]1048
[1186]1049 $pb->{'pbos'} = $pbos;
[1189]1050 $pb->{'suf'} = $pbos->{'suffix'};
[1186]1051 pb_log(3,"DEBUG: pb: ".Dumper($pb)."\n");
[1185]1052
1053 # Get all filters to apply
[1192]1054 $ptr = pb_get_filters($pbpkg,$pbos);
[1185]1055
[556]1056 pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
1057
1058 # We need to compute the real name of the package
[1177]1059 my $pbrealpkg = pb_cms_get_real_pkg($pbpkg,$pbos->{'type'});
[1186]1060 $pb->{'realpkg'} = $pbrealpkg;
[1177]1061 pb_log(1,"Virtual package $pbpkg has a real package name of $pbrealpkg on $pbos->{'name'}-$pbos->{'version'}\n") if ($pbrealpkg ne $pbpkg);
[556]1062
1063 # Filter build files from the less precise up to the most with overloading
1064 # Filter all files found, keeping the name, and generating in dest
1065
1066 # Find all build files first relatively to PBROOTDIR
1067 # Find also all specific files referenced in the .pb conf file
1068 my %bfiles = ();
1069 my %pkgfiles = ();
[1185]1070 # Used in Filter.pm by pb_filter_file
1071
[1363]1072 $build{$v} = "no";
[1185]1073 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'os'}") {
1074 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'os'}",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
[1363]1075 $build{$v} = "yes";
1076 }
1077 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'type'}") {
[1177]1078 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'type'}",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
[1363]1079 $build{$v} = "yes";
1080 }
1081 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'family'}") {
[1177]1082 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'family'}",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
[1363]1083 $build{$v} = "yes";
1084 }
1085 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'name'}") {
[1177]1086 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'name'}",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
[1363]1087 $build{$v} = "yes";
1088 }
1089 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'name'}-$pbos->{'version'}") {
[1177]1090 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'name'}-$pbos->{'version'}",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
[1363]1091 $build{$v} = "yes";
1092 }
1093 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}") {
[1177]1094 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
[1363]1095 $build{$v} = "yes";
[500]1096 }
[1186]1097 pb_log(2,"DEBUG($v) bfiles: ".Dumper(\%bfiles)."\n");
[556]1098
[1185]1099 if ($build{$v} ne "no") {
1100 # Apply now all the filters on all the files concerned
1101 # destination dir depends on the type of file
[556]1102 # For patch support
[1185]1103 # TODO: Make it CMS aware
[1186]1104 $pb->{'patches'} = pb_list_sfiles("$ENV{'PBROOTDIR'}/$pbpkg/pbpatch", $pb->{'patches'}, $pbos, "$ENV{'PBROOTDIR'}/$pbpkg/pbextpatch");
1105 pb_log(2,"DEBUG($v) patches: ".Dumper($pb->{'patches'})."\n");
[1185]1106 # TODO: Make it CMS aware
[1186]1107 $pb->{'sources'} = pb_list_sfiles("$ENV{'PBROOTDIR'}/$pbpkg/pbsrc", $pb->{'sources'}, $pbos, "$ENV{'PBROOTDIR'}/$pbpkg/pbextsrc");
1108 pb_log(2,"DEBUG($v) sources: ".Dumper($pb->{'sources'})."\n");
[1185]1109
[1186]1110 if (defined $pb->{'patches'}->{$v}) {
[1185]1111 # Filter potential patches (local + remote)
1112 pb_mkdir_p("$dest/pbconf/$v/pbpatch");
[1367]1113 # If Debian based distribution, then prepare what will be done at build time
1114 my ($patchcmd,$patchopt);
1115 if ($pbos->{'type'} eq "deb") {
1116 ($patchcmd,$patchopt) = pb_distro_get_param($pbos,pb_conf_get_if("ospatchcmd","ospatchopt"));
1117 open(SCRIPT,"> $dest/pbconf/$v/pbpatch/pbapplypatch") || die "Unable to create $dest/pbconf/$v/pbpatch/pbapplypatch";
1118 print SCRIPT "#!/bin/bash\n";
1119 print SCRIPT "set -x\n" if ($pbdebug gt 1);
1120 }
[1186]1121 foreach my $pf (split(/,/,$pb->{'patches'}->{$v})) {
[1185]1122 my $pp = basename($pf);
[1469]1123 pb_vcs_export($pf,undef,"$dest/pbconf/$v/pbpatch");
[1186]1124 pb_filter_file_inplace($ptr,"$dest/pbconf/$v/pbpatch/$pp",$pb);
[1185]1125 pb_system("gzip -9f $dest/pbconf/$v/pbpatch/$pp","","quiet");
[1367]1126 if ($pbos->{'type'} eq "deb") {
1127 # If Debian based distribution, then prepare what will be done at build time
1128 # by applying the patches that will be available under the debian/patches dir
1129 print SCRIPT "$patchcmd $patchopt \< debian/patches/$pp\n";
1130 }
[1185]1131 }
[1367]1132 if ($pbos->{'type'} eq "deb") {
1133 close(SCRIPT);
1134 chmod 0755,"$dest/pbconf/$v/pbpatch/pbapplypatch";
1135 }
1136 #pb_system("cat $dest/pbconf/$v/pbpatch/pbapplypatch","APPLY","verbose");
[1185]1137 }
[1186]1138 if (defined $pb->{'sources'}->{$v}) {
[1185]1139 pb_mkdir_p("$dest/pbconf/$v/pbsrc");
[1186]1140 foreach my $pf (split(/,/,$pb->{'sources'}->{$v})) {
[1185]1141 my $pp = basename($pf);
[1469]1142 pb_vcs_export($pf,undef,"$dest/pbconf/$v/pbsrc");
[1186]1143 pb_filter_file_inplace($ptr,"$dest/pbconf/$v/pbsrc/$pp",$pb);
[1185]1144 }
1145 }
[1186]1146 # Filter build files at the end, as they depend on patches and sources
[1363]1147 foreach my $f (keys %bfiles) {
1148 pb_filter_file("$ENV{'PBROOTDIR'}/$bfiles{$f}",$ptr,"$dest/pbconf/$v/$f",$pb);
[1186]1149 }
[1363]1150 foreach my $f (keys %pkgfiles) {
1151 pb_filter_file("$ENV{'PBROOTDIR'}/$pkgfiles{$f}",$ptr,"$dest/pbconf/$v/$f",$pb);
1152 }
[556]1153 }
[1130]1154
[1185]1155 if (defined $pbparallel) {
1156 # Communicate results back to parent
1157 my $str = "";
1158 $str .= "build $v = $build{$v}\n" if (defined $build{$v});
[1186]1159 $str .= "patches $v = $pb->{'patches'}->{$v}\n" if (defined $pb->{'patches'}->{$v});
1160 $str .= "sources $v = $pb->{'sources'}->{$v}\n" if (defined $pb->{'sources'}->{$v});
[1185]1161 pb_set_content("$tmpd/$$","$str");
1162 $pm->finish;
1163 }
[15]1164 }
[1185]1165 # In the parent, we need to get the result from the children
[1125]1166 $pm->wait_all_children if (defined $pbparallel);
[1185]1167 my $made = "";
1168 my %h = ();
1169 my %tmp;
[1186]1170 my %tmp2;
[1185]1171 my $pt;
1172 my $k;
1173
1174 foreach $k (<$tmpd/*>) {
1175 $made .= pb_get_content($k);
[556]1176 }
[1185]1177 pb_rm_rf($tmpd);
1178 pb_log(3,"MADE:\n$made");
[500]1179
[1185]1180 # Rebuild local hashes
1181 foreach $k (split(/\n/,$made)) {
1182 if ($k =~ /^\s*([A-z0-9-_]+)\s+([[A-z0-9-_.]+)\s*=\s*(.+)$/) {
1183 $h{$1}->{$2}=$3;
1184 }
1185 }
[1186]1186 pb_log(2,"HASH: ".Dumper(%h));
[236]1187
[1185]1188 # Patches
1189 pb_log(0,"Delivered and compressed patches ");
1190 $pt = $h{'patches'};
[1186]1191 foreach $k (keys %$pt) {
1192 foreach my $v1 (split(/,/,$pt->{$k})) {
1193 $tmp{$v1} = "";
1194 }
[1185]1195 }
[1186]1196 if (keys %tmp) {
1197 foreach $k (keys %tmp) {
1198 pb_log(0,"$k ");
1199 }
1200 } else {
1201 pb_log(0,"N/A");
[1185]1202 }
1203 pb_log(0,"\n");
[236]1204
[1185]1205 # Sources
1206 pb_log(0,"Delivered additional sources ");
1207 $pt = $h{'sources'};
[1186]1208 foreach $k (keys %$pt) {
1209 foreach my $v1 (split(/,/,$pt->{$k})) {
1210 $tmp2{$v1} = "";
1211 }
[236]1212 }
[1186]1213 if (keys %tmp2) {
1214 foreach $k (keys %tmp2) {
1215 pb_log(0,"$k ");
1216 }
1217 } else {
1218 pb_log(0,"N/A");
[1185]1219 }
1220 pb_log(0,"\n");
[236]1221
[1185]1222 # Build files
1223 my @found;
1224 my @notfound;
1225 $pt = $h{'build'};
1226 foreach my $b (keys %$pt) {
1227 push @found,$b if ($pt->{$b} =~ /yes/);
1228 push @notfound,$b if ($pt->{$b} =~ /no/);
1229 }
1230 pb_log(0,"Build files have been generated for ... ".join(',',sort(@found))."\n") if (@found);
1231 pb_log(0,"No Build files found for ".join(',',sort(@notfound))."\n") if (@notfound);
1232
[556]1233 } else {
1234 # Instead call News generation
1235 pb_web_news2html($dest);
[559]1236 # And create an empty pbconf
1237 pb_mkdir_p("$dest/pbconf");
[560]1238 # And prepare the pbscript to execute remotely
[1138]1239 open(SCRIPT,"> $ENV{'PBTMP'}/pbscript") || die "Unable to create $ENV{'PBTMP'}/pbscript";
[560]1240 print SCRIPT "#!/bin/bash\n";
1241 print SCRIPT "#set -x\n";
1242 print SCRIPT "echo ... Extracting Website content\n";
[1461]1243 print SCRIPT "find . -type f | grep -Ev '^./$pbpkg-$pbver$pbextdir.tar.gz|^./pbscript' | xargs rm -f non-existent\n";
[560]1244 print SCRIPT "find * -type d -depth | xargs rmdir 2> /dev/null \n";
[1461]1245 print SCRIPT "tar xfz $pbpkg-$pbver$pbextdir.tar.gz\n";
1246 print SCRIPT "mv $pbpkg-$pbver$pbextdir/* .\n";
1247 print SCRIPT "rm -f $pbpkg-$pbver$pbextdir.tar.gz\n";
1248 print SCRIPT "rmdir $pbpkg-$pbver$pbextdir\n";
[1484]1249 print SCRIPT "find . -type f -print0 | xargs -0 chmod 644\n";
1250 print SCRIPT "find . -type d -print0 | xargs -0 chmod 755\n";
[560]1251 close(SCRIPT);
[1165]1252 chmod 0755,"$ENV{'PBTMP'}/pbscript";
[499]1253 }
1254
[1259]1255 # Apply filters to the non-build files
1256 my $liste ="";
1257 if (defined $filteredfiles->{$pbpkg}) {
1258 foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
1259 pb_filter_file_inplace($ptr,"$dest/$f",$pb);
1260 $liste = "$f $liste";
1261 }
1262 }
1263 pb_log(2,"Files ".$liste."have been filtered\n");
1264
1265 # TODO: Make it CMS aware
1266 # Execute the pbinit script if any
1267 if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
1268 pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$pb);
1269 chmod 0755,"$ENV{'PBTMP'}/pbinit";
1270 pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit under $dest","verbose");
1271 }
1272
1273 # Do we have additional script to run to prepare the environement for the project ?
1274 # Then include it in the pbconf delivery
1275 foreach my $pbvf (<$ENV{'PBROOTDIR'}/pbv*.pre>,<$ENV{'PBROOTDIR'}/pbv*.post>, <$ENV{'PBROOTDIR'}/pbtest*>) {
1276 if (-x "$pbvf") {
1277 my $target = "$ENV{'PBDESTDIR'}/".basename($pbvf);
1278 pb_filter_file("$pbvf",$ptr,$target,$pb);
1279 chmod 0755,"$target";
1280 }
1281 }
1282
[265]1283 # Prepare the dest directory for archive
[69]1284 chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
[537]1285 if (defined $preserve) {
1286 # In that case we want to preserve the original tar file for checksum purposes
1287 # The one created is btw equivalent in that case to this one
1288 # Maybe check basename of both to be sure they are the same ?
1289 pb_log(0,"Preserving original tar file ");
[1432]1290 move("$preserve","$pbpkg-$pbver$pbextdir.tar.gz");
[537]1291 } else {
1292 # Possibility to look at PBSRC to guess more the filename
[1432]1293 pb_system("tar cfz $pbpkg-$pbver$pbextdir.tar.gz --exclude=$pbpkg-$pbver$pbextdir/pbconf $pbpkg-$pbver$pbextdir","Creating $pbpkg tar files compressed");
[537]1294 }
[1432]1295 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver$pbextdir.tar.gz\n");
1296 pb_system("tar cfz $pbpkg-$pbver$pbextdir.pbconf.tar.gz $pbpkg-$pbver$pbextdir/pbconf","Creating pbconf tar files compressed");
1297 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver$pbextdir.pbconf.tar.gz\n");
[83]1298
[357]1299 # Keep track of version-tag per pkg
1300 $pkgs{$pbpkg} = "$pbver-$pbtag";
[83]1301
[288]1302 # Final cleanup
1303 pb_rm_rf($dest) if (-d $dest);
[9]1304 }
[357]1305
1306 # Keep track of per package version
1307 pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
1308 open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
[539]1309 foreach my $pbpkg (keys %pkgs) {
[357]1310 print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
1311 }
1312 close(PKG);
1313
1314 # Keep track of what is generated by default
1315 # We need to store the dir and info on version-tag
1316 # Base our content on the existing .pb file
1317 copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
1318 open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
1319 print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
[702]1320 print LAST "projver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
1321 print LAST "projtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
[357]1322 print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
[1432]1323 print LAST "pbextdir $ENV{'PBPROJ'} = $pbextdir\n";
[357]1324 close(LAST);
[77]1325}
[22]1326
[772]1327sub pb_test2pkg {
1328 # Get the running distro to test on
[1177]1329 my $pbos = pb_distro_get_context();
[772]1330
1331 # Get list of packages to test
1332 # Get content saved in cms2build
1333 my $ptr = pb_get_pkg();
1334 @pkgs = @$ptr;
1335
1336 # Additional potential repo
[1177]1337 pb_distro_setuprepo($pbos);
[772]1338 foreach my $pbpkg (@pkgs) {
1339 # We need to install the package to test, and deps brought with it
[1177]1340 pb_distro_installdeps(undef,$pbos,$pbpkg);
[772]1341 pb_system("$ENV{'PBDESTDIR'}/pbtest","Launching test for $pbpkg","verbose");
1342 }
1343}
1344
[77]1345sub pb_build2pkg {
1346
[22]1347 # Get the running distro to build on
[1177]1348 my $pbos = pb_distro_get_context();
[22]1349
[1137]1350 # If needed we may add repository to the build env
[1177]1351 pb_distro_setuprepo($pbos);
[1137]1352
[353]1353 # Get list of packages to build
1354 my $ptr = pb_get_pkg();
1355 @pkgs = @$ptr;
1356
[898]1357 # Get content saved in cms2build
[353]1358 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
[83]1359 $pkg = { } if (not defined $pkg);
[1432]1360 my $pbextdir = pb_get_extdir();
[83]1361
[1212]1362 pb_mkdir_p("$ENV{'PBBUILDDIR'}") if (! -d "$ENV{'PBBUILDDIR'}");
[1208]1363 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
[126]1364 my $made = ""; # pkgs made during build
[1176]1365 my $pm;
[1545]1366 my $all_ok = 1;
[1137]1367
[1545]1368 if (defined $pbparallel) {
1369 $pm = new Parallel::ForkManager($pbparallel);
1370 $pm->run_on_finish(sub { my ($pid, $code, $id, $signal, $dump) = @_;
1371 $all_ok = 0 unless (($code == 0) && ($signal == 0) && ($dump == 0)); });
1372 }
1373
[1137]1374 # We need to communicate info back from the children if parallel so prepare a dir for that
1375 my $tmpd = "$ENV{'PBTMP'}/build.$$";
1376 pb_mkdir_p($tmpd) if (defined $pbparallel);
1377
[27]1378 foreach my $pbpkg (@pkgs) {
[1137]1379 $pm->start and next if (defined $pbparallel);
1380
[88]1381 my $vertag = $pkg->{$pbpkg};
[1459]1382 pb_log(2,"Vertag: $vertag\n");
[77]1383 # get the version of the current package - maybe different
1384 ($pbver,$pbtag) = split(/-/,$vertag);
1385
[1432]1386 my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver$pbextdir.tar.gz";
1387 my $src2="$ENV{'PBDESTDIR'}/$pbpkg-$pbver$pbextdir.pbconf.tar.gz";
[315]1388 pb_log(2,"Source file: $src\n");
[493]1389 pb_log(2,"Pbconf file: $src2\n");
[25]1390
[315]1391 pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
[1177]1392 if ($pbos->{'type'} eq "rpm") {
[25]1393 foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
[28]1394 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
[1212]1395 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$d");
[28]1396 }
[25]1397 }
1398
[315]1399 # Remove in case a previous link/file was there
[301]1400 unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
[188]1401 symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
[25]1402 # We need to first extract the spec file
[1432]1403 my @specfile = pb_extract_build_files($src2,"$pbpkg-$pbver$pbextdir/pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/","$ENV{'PBBUILDDIR'}/SPECS","spec");
[25]1404
[493]1405 # We need to handle potential patches to upstream sources
[1432]1406 pb_extract_build_files($src2,"$pbpkg-$pbver$pbextdir/pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbpatch/","$ENV{'PBBUILDDIR'}/SOURCES","patch");
[493]1407
[1219]1408 # We need to handle potential additional sources to upstream sources
[1432]1409 pb_extract_build_files($src2,"$pbpkg-$pbver$pbextdir/pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbsrc/","$ENV{'PBBUILDDIR'}/SOURCES","src");
[1219]1410
[315]1411 pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
[25]1412 # set LANGUAGE to check for correct log messages
1413 $ENV{'LANGUAGE'}="C";
[459]1414 # Older Redhat use _target_platform in %configure incorrectly
1415 my $specialdef = "";
[1177]1416 if (($pbos->{'name'} eq "redhat") || (($pbos->{'name'} eq "rhel") && ($pbos->{'version'} eq "2.1"))) {
[459]1417 $specialdef = "--define \'_target_platform \"\"\'";
1418 }
[702]1419
[28]1420 foreach my $f (@specfile) {
1421 if ($f =~ /\.spec$/) {
[1137]1422 # This could cause an issue in // mode
[1177]1423 pb_distro_installdeps($f,$pbos);
[1085]1424 pb_system("rpmbuild $specialdef --define \"packager $ENV{'PBPACKAGER'}\" --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}","verbose");
[28]1425 last;
1426 }
1427 }
[540]1428 # Get the name of the generated packages
[1137]1429 open(LOG,"$ENV{'PBTMP'}/system.$$.log") || die "Unable to open $ENV{'PBTMP'}/system.$$.log";
[540]1430 while (<LOG>) {
[572]1431 chomp($_);
[540]1432 next if ($_ !~ /^Wrote:/);
1433 s|.*/([S]*RPMS.*)|$1|;
[572]1434 $made .=" $_";
[540]1435 }
[541]1436 close(LOG);
[540]1437
[1177]1438 } elsif ($pbos->{'type'} eq "deb") {
[274]1439 pb_system("tar xfz $src","Extracting sources");
[493]1440 pb_system("tar xfz $src2","Extracting pbconf");
[149]1441
[1432]1442 chdir "$pbpkg-$pbver$pbextdir" || die "Unable to chdir to $pbpkg-$pbver$pbextdir";
[310]1443 pb_rm_rf("debian");
[1546]1444 my $confdir = "pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}";
[1548]1445 die "Configuration directory $confdir is not a directory\nIs os description listed in your {ve,vm,rm}list values?" if (not -d $confdir);
[1546]1446 symlink "$confdir","debian" || die "Unable to symlink 'debian' to $confdir";
[199]1447 chmod 0755,"debian/rules";
[544]1448
[1359]1449 # We need to handle potential patches to upstream sources
[1363]1450 pb_mkdir_p("debian/patches");
[1432]1451 my @f = pb_extract_build_files($src2,"$pbpkg-$pbver$pbextdir/pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbpatch/","debian/patches","patch");
[1363]1452
[1367]1453 # By default we use format 1.0 - Cf man dpkg-source
1454 my $debsrcfmt = "1.0";
1455 my $debsrcfile = "debian/source/format";
1456 if (-f $debsrcfile) {
1457 $debsrcfmt = pb_get_content($debsrcfile);
1458 }
[1546]1459
[1367]1460 if ($debsrcfmt =~ /^3.*quilt/) {
1461 # If we use quilt to manage patches, we then setup the env correctly
1462 # as per http://pkg-perl.alioth.debian.org/howto/quilt.html
1463 # Generate Debian patch series for quilt
1464 open(SERIE,"> debian/patches/series") || die "Unable to write in debian/patches/series";
1465 $ENV{'QUILT_PATCHES'}="debian/patches";
1466 } else {
1467 # If we use dpatch to manage patches, we then setup the 00list file as well
1468 open(SERIE,"> debian/patches/00list") || die "Unable to write in debian/patches/00list";
1469 }
[1363]1470 foreach my $f (sort @f) {
[1367]1471 # Skip the script made to apply the patches to the Debian tree
1472 next if ($f =~ /pbapplypatch/);
1473 # We also need to uncompress them
1474 pb_system("gzip -d $f","","quiet");
1475 $f =~ s/\.gz$//;
[1359]1476 print SERIE "$f\n";
1477 }
1478 close(SERIE);
[1367]1479 if (@f) {
[1432]1480 # We have patches...
[1537]1481 my $patch_file = "debian/patches/pbapplypatch";
1482 if (($debsrcfmt =~ /^1.*/) && (-x $patch_file)) {
[1432]1483 # In that case we need to apply the patches ourselves locally
[1537]1484 pb_system("cat $patch_file","APPLY","verbose");
1485 pb_system("$patch_file","Applying patches to $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'} tree");
[1432]1486 }
1487 # ...so modify the name of files to be Debian compliant
1488 move("../$src","../$pbpkg-$pbver$pbextdir.orig.tar.gz");
[1367]1489 }
[1359]1490
1491 # We need to handle potential additional sources to upstream sources
[1432]1492 #pb_extract_build_files($src2,"$pbpkg-$pbver$pbextdir/pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbsrc/","$ENV{'PBBUILDDIR'}/debian","src");
[1359]1493
[1177]1494 pb_distro_installdeps("debian/control",$pbos);
[544]1495 pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package","verbose");
1496 # Get the name of the generated packages
[1137]1497 open(LOG,"$ENV{'PBTMP'}/system.$$.log") || die "Unable to open $ENV{'PBTMP'}/system.$$.log";
[1545]1498 my $tmp = "";
[544]1499 while (<LOG>) {
1500 chomp();
[1545]1501 next unless (/^dpkg-deb.*:\s+building\s+package\s+.*\s+in\s+\`\.\.\/(\S+)\'\./o);
1502 $tmp = $1;
1503 die "Missing file $tmp" if (not -f $tmp);
1504 $made = "$made $tmp";
[448]1505 }
[544]1506 close(LOG);
[1545]1507 open(CTRL,"debian/control") or die "Unable to open debian/control: $!";
1508 #$made="$made $tmp.dsc $tmp.tar.gz $tmp"."_*.deb $tmp"."_*.changes";
1509 while (<CTRL>) {
1510 next unless (/^Source: (\S+)/o);
1511 foreach my $glob (("$1\_*.changes", "$1\_*.dsc", "$1\_*.tar.gz")) {
1512 my @file = glob($glob);
1513 die "Missing file for $glob" unless @file > 0;
1514 die "Too many files for $glob" if @file > 1;
1515 die "Missing file $file[0]" if (not -f $file[0]);
1516 $made .= " $file[0]";
1517 }
1518 }
1519 close(CTRL);
1520 pb_display_file("$ENV{'PBTMP'}/system.$$.log");
1521
[1234]1522 chdir ".." || die "Unable to chdir to parent dir";
[1424]1523 pb_rm_rf("$pbpkg-$pbver");
[1177]1524 } elsif ($pbos->{'type'} eq "ebuild") {
[149]1525 my @ebuildfile;
1526 # For gentoo we need to take pb as subsystem name
[295]1527 # We put every apps here under sys-apps. hope it's correct
[435]1528 # We use pb's home dir in order to have a single OVERLAY line
[1185]1529 my $tmpe = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
1530 pb_mkdir_p($tmpe) if (! -d "$tmpe");
[295]1531 pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
[149]1532
[295]1533 # We need to first extract the ebuild file
[1432]1534 @ebuildfile = pb_extract_build_files($src2,"$pbpkg-$pbver$pbextdir/pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/","$tmpe","ebuild");
[149]1535
1536 # Prepare the build env for gentoo
1537 my $found = 0;
[295]1538 my $pbbd = $ENV{'HOME'};
[150]1539 $pbbd =~ s|/|\\/|g;
[295]1540 if (-r "/etc/make.conf") {
1541 open(MAKE,"/etc/make.conf");
1542 while (<MAKE>) {
1543 $found = 1 if (/$pbbd\/portage/);
1544 }
1545 close(MAKE);
[149]1546 }
1547 if ($found == 0) {
[295]1548 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
[149]1549 }
[295]1550 #$found = 0;
1551 #if (-r "/etc/portage/package.keywords") {
1552 #open(KEYW,"/etc/portage/package.keywords");
1553 #while (<KEYW>) {
1554 #$found = 1 if (/portage\/pb/);
1555 #}
1556 #close(KEYW);
1557 #}
1558 #if ($found == 0) {
1559 #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
1560 #}
[149]1561
1562 # Build
1563 foreach my $f (@ebuildfile) {
1564 if ($f =~ /\.ebuild$/) {
[1177]1565 pb_distro_installdeps($f,$pbos);
[1185]1566 move($f,"$tmpe/$pbpkg-$pbver.ebuild");
1567 pb_system("cd $tmpe ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package","verbose");
[295]1568 # Now move it where pb expects it
1569 pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
[1432]1570 if ($pbtag eq 0) {
1571 # This is assumed to be a test version
1572 my $nver = substr($pbver,0,-14);
1573 my $ntag = substr($pbver,-14);
1574 my $ebtg = "portage/pb/sys-apps/$pbpkg/$pbpkg-$nver"."_p$ntag.ebuild";
1575 move("$tmpe/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/$ebtg");
1576 $made="$made $ebtg";
[1174]1577 } else {
[1432]1578 my $ebtg = "portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver-r$pbtag.ebuild";
1579 move("$tmpe/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/$ebtg");
1580 $made="$made $ebtg";
[1174]1581 }
[149]1582 }
1583 }
1584
[1177]1585 } elsif ($pbos->{'type'} eq "tgz") {
[437]1586 # Slackware family
[435]1587 $made="$made $pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
1588
1589 pb_system("tar xfz $src","Extracting sources");
[493]1590 pb_system("tar xfz $src2","Extracting pbconf");
[1432]1591 chdir "$pbpkg-$pbver$pbextdir" || die "Unable to chdir to $pbpkg-$pbver$pbextdir";
[1177]1592 symlink "pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}","install" || die "Unable to symlink to pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}";
[435]1593 if (-x "install/pbslack") {
[1177]1594 pb_distro_installdeps("./install/pbslack",$pbos);
[872]1595 pb_system("./install/pbslack","Building software");
[529]1596 pb_system("sudo /sbin/makepkg -p -l y -c y $pbpkg","Packaging $pbpkg","verbose");
[435]1597 }
[1234]1598 chdir ".." || die "Unable to chdir to parent dir";
[1432]1599 pb_rm_rf("$pbpkg-$pbver$pbextdir");
[1177]1600 } elsif ($pbos->{'type'} eq "pkg") {
[872]1601 # Solaris
[916]1602 $made="$made $pbpkg-$pbver-$pbtag.pkg.gz";
[873]1603 my $pkgdestdir="$ENV{'PBBUILDDIR'}/install";
[872]1604
1605 # Will host resulting packages
[1177]1606 pb_mkdir_p("$pbos->{'type'}");
[878]1607 pb_mkdir_p("$pkgdestdir/delivery");
[873]1608 pb_system("tar xfz $src","Extracting sources under $ENV{'PBBUILDDIR'}");
1609 pb_system("tar xfz $src2","Extracting pbconf under $ENV{'PBBUILDDIR'}");
[1242]1610 # We need to handle potential patches to upstream sources
[1432]1611 pb_extract_build_files($src2,"$pbpkg-$pbver$pbextdir/pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbpatch/","$ENV{'PBBUILDDIR'}","patch");
[1242]1612
1613 # We need to handle potential additional sources to upstream sources
[1432]1614 pb_extract_build_files($src2,"$pbpkg-$pbver$pbextdir/pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbsrc/","$ENV{'PBBUILDDIR'}","src");
[1242]1615
[1432]1616 chdir "$pbpkg-$pbver$pbextdir" || die "Unable to chdir to $pbpkg-$pbver$pbextdir";
[1177]1617 if (-f "pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbbuild") {
1618 chmod 0755,"pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbbuild";
[872]1619 # pkginfo file is mandatory
[1177]1620 die "Unable to find pkginfo file in pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}" if (! -f "pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pkginfo");
[872]1621 # Build
[1177]1622 pb_system("pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbbuild $pkgdestdir/delivery","Building software and installing under $pkgdestdir/delivery");
[872]1623 # Copy complementary files
[1177]1624 if (-f "pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/prototype") {
1625 copy("pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/prototype", $pkgdestdir)
[872]1626 } else {
1627 # No prototype provided, calculating it
[878]1628 open(PROTO,"> $pkgdestdir/prototype") || die "Unable to create prototype file";
[872]1629 print PROTO "i pkginfo\n";
[1177]1630 print PROTO "i depend\n" if (-f "pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/depend");
[879]1631 $ENV{'PBSOLDESTDIR'} = "$pkgdestdir/delivery";
1632 find(\&create_solaris_prototype, "$pkgdestdir/delivery");
[872]1633 }
[1177]1634 copy("pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/depend", $pkgdestdir) if (-f "pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/depend");
1635 copy("pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pkginfo", $pkgdestdir);
1636 pb_system("cd $pkgdestdir/delivery ; pkgmk -o -f ../prototype -r $pkgdestdir/delivery -d $ENV{'PBBUILDDIR'}/$pbos->{'type'}","Packaging $pbpkg","verbose");
1637 pb_system("cd $ENV{'PBBUILDDIR'}/$pbos->{'type'} ; echo \"\" | pkgtrans -o -n -s $ENV{'PBBUILDDIR'}/$pbos->{'type'} $ENV{'PBBUILDDIR'}/$pbpkg-$pbver-$pbtag.pkg all","Transforming $pbpkg","verbose");
[916]1638 pb_system("cd $ENV{'PBBUILDDIR'} ; gzip -9f $pbpkg-$pbver-$pbtag.pkg","Compressing $pbpkg-$pbver-$pbtag.pkg","verbose");
[913]1639 } else {
[1177]1640 pb_log(0,"No pbconf/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}/pbbuild file found for $pbpkg-$pbver in \n");
[872]1641 }
[874]1642 chdir ".." || die "Unable to chdir to parent dir";
[1432]1643 pb_rm_rf("$pbpkg-$pbver$pbextdir","$ENV{'PBBUILDDIR'}/$pbos->{'type'}","$pkgdestdir");
[1177]1644 } elsif ($pbos->{'type'} eq "hpux") {
[1174]1645 # HP-UX
1646 pb_system("tar xfz $src","Extracting sources");
1647 pb_system("tar xfz $src2","Extracting pbconf");
1648
[1432]1649 chdir "$pbpkg-$pbver$pbextdir" || die "Unable to chdir to $pbpkg-$pbver$pbextdir";
[1174]1650 pb_system("buildpackage ","Building package","verbose");
1651 # Get the name of the generated packages
1652 open(LOG,"$ENV{'PBTMP'}/system.$$.log") || die "Unable to open $ENV{'PBTMP'}/system.$$.log";
1653 while (<LOG>) {
1654 chomp();
1655 my $tmp = $_;
1656 next if ($tmp !~ /^SD BUILD.*:/);
1657 $tmp =~ s|.*../(.*)_(.*).sd.*|$1|;
[1279]1658 $made = "$made $tmp"."_*.sd";
[1174]1659 }
1660 close(LOG);
1661 $made="$made $pbpkg-$pbver-$pbtag.sd";
1662
[1234]1663 chdir ".." || die "Unable to chdir to parent dir";
[1432]1664 pb_rm_rf("$pbpkg-$pbver$pbextdir");
[87]1665 } else {
[1177]1666 die "Unknown OS type format $pbos->{'type'}";
[87]1667 }
[1137]1668 if (defined $pbparallel) {
1669 # Communicate results back to parent
1670 pb_set_content("$tmpd/$$",$made);
1671 $pm->finish;
1672 }
[87]1673 }
[1137]1674 if (defined $pbparallel) {
1675 # In the parent, we need to get the result from the children
1676 $pm->wait_all_children;
1677 foreach my $f (<$tmpd/*>) {
1678 $made .= " ".pb_get_content($f);
1679 }
[1545]1680 die "Aborting, one or more of the children failed.\n" if ((not $all_ok) && ($Global::pb_stop_on_error));
[1137]1681 pb_rm_rf($tmpd);
1682 }
1683
[1278]1684 # Sign packages
1685 pb_sign_pkgs($pbos,$made);
1686
[1109]1687 # Find the appropriate check cmd/opts
[1177]1688 my ($chkcmd,$chkopt) = pb_distro_get_param($pbos,pb_conf_get_if("oschkcmd","oschkopt"));
[1109]1689
[541]1690 # Packages check if needed
[1177]1691 if ($pbos->{'type'} eq "rpm") {
1692 if ((defined $chkcmd) && (-x $chkcmd)) {
1693 my $cmd = "$chkcmd";
1694 $cmd .= " $chkopt" if (defined $chkopt);
1695 $cmd .= " $made";
[1539]1696 my $ret = pb_system("$cmd","Checking validity of rpms with $chkcmd","verbose",1);
1697 pb_log(0,"ERROR: when checking packages validity\n") if ($ret ne 0);
[541]1698 }
[1098]1699 my $rpms ="";
1700 my $srpms ="";
1701 foreach my $f (split(/ /,$made)) {
1702 $rpms .= "$ENV{'PBBUILDDIR'}/$f " if ($f =~ /^RPMS\//);
1703 $srpms .= "$ENV{'PBBUILDDIR'}/$f " if ($f =~ /^SRPMS\//);
1704 }
1705 pb_log(0,"SRPM packages generated: $srpms\n");
1706 pb_log(0,"RPM packages generated: $rpms\n");
[1177]1707 } elsif ($pbos->{'type'} eq "deb") {
[572]1708 my $made2 = "";
[971]1709 foreach my $f (split(/ /,$made)) {
[1234]1710 $made2 .= "$f " if ($f =~ /\.deb$/);
[971]1711 }
[1109]1712 if (-x $chkcmd) {
[1539]1713 my $ret = pb_system("$chkcmd $chkopt $made2","Checking validity of debs with $chkcmd","verbose",1);
1714 pb_log(0,"ERROR: when checking packages validity\n") if ($ret ne 0);
[541]1715 }
[1234]1716 pb_log(0,"deb packages generated: $made2\n");
[541]1717 } else {
[1177]1718 pb_log(0,"No check done for $pbos->{'type'} yet\n");
[572]1719 pb_log(0,"Packages generated: $made\n");
[541]1720 }
1721
[1176]1722 # Keep track of what is generated so that we can get them back from VMs/RMs
[1545]1723 my $pbkeep = "$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}-$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}";
1724 open(KEEP,"> $pbkeep") || die "Unable to create $pbkeep: $!";
[118]1725 print KEEP "$made\n";
1726 close(KEEP);
[87]1727}
1728
[874]1729sub create_solaris_prototype {
[872]1730
[873]1731 my $uidgid = "bin bin";
[877]1732 my $pkgdestdir = $ENV{'PBSOLDESTDIR'};
[872]1733
[878]1734 return if ($_ =~ /^$pkgdestdir$/);
[875]1735 if (-d $_) {
1736 my $n = $File::Find::name;
1737 $n =~ s~$pkgdestdir/~~;
1738 print PROTO "d none $n 0755 $uidgid\n";
[877]1739 } elsif (-x $_) {
[875]1740 my $n = $File::Find::name;
1741 $n =~ s~$pkgdestdir/~~;
1742 print PROTO "f none $n 0755 $uidgid\n";
[872]1743 } elsif (-f $_) {
[875]1744 my $n = $File::Find::name;
1745 $n =~ s~$pkgdestdir/~~;
1746 print PROTO "f none $n 0644 $uidgid\n";
[872]1747 }
1748}
1749
[88]1750sub pb_build2ssh {
[320]1751 pb_send2target("Sources");
[1374]1752 pb_send2target("CPAN");
[90]1753}
[87]1754
[90]1755sub pb_pkg2ssh {
[320]1756 pb_send2target("Packages");
[90]1757}
1758
[108]1759# By default deliver to the the public site hosting the
[1176]1760# ftp structure (or whatever) or a VM/VE/RM
[320]1761sub pb_send2target {
[90]1762
1763 my $cmt = shift;
[320]1764 my $v = shift || undef;
[142]1765 my $vmexist = shift || 0; # 0 is FALSE
[200]1766 my $vmpid = shift || 0; # 0 is FALSE
[748]1767 my $snapme = shift || 0; # 0 is FALSE
[320]1768
[444]1769 pb_log(2,"DEBUG: pb_send2target($cmt,".Dumper($v).",$vmexist,$vmpid)\n");
[320]1770 my $host = "sshhost";
1771 my $login = "sshlogin";
1772 my $dir = "sshdir";
1773 my $port = "sshport";
1774 my $conf = "sshconf";
[883]1775 my $tmout = undef;
1776 my $path = undef;
[772]1777 if ($cmt =~ /^VM/) {
[320]1778 $login = "vmlogin";
[322]1779 $dir = "pbdefdir";
[320]1780 # Specific VM
[883]1781 $tmout = "vmtmout";
1782 $path = "vmpath";
[320]1783 $host = "vmhost";
1784 $port = "vmport";
[1176]1785 } elsif ($cmt =~ /^RM/) {
1786 $login = "rmlogin";
1787 $dir = "pbdefdir";
1788 # Specific RM
1789 $tmout = "rmtmout";
1790 $path = "rmpath";
1791 $host = "rmhost";
1792 $port = "rmport";
[772]1793 } elsif ($cmt =~ /^VE/) {
[320]1794 $login = "velogin";
[322]1795 $dir = "pbdefdir";
[320]1796 # Specific VE
1797 $path = "vepath";
[986]1798 $conf = "rbsconf";
[556]1799 } elsif ($cmt eq "Web") {
1800 $host = "websshhost";
1801 $login = "websshlogin";
1802 $dir = "websshdir";
1803 $port = "websshport";
[1374]1804 } elsif ($cmt eq "CPAN") {
1805 $host = "cpanpause";
1806 $login = "";
1807 $dir = "cpandir";
1808 $port = "";
[320]1809 }
[158]1810 my $cmd = "";
[471]1811 my $src = "";
[1374]1812 my $cpanpkg = 0;
[1177]1813 my $pbos;
[90]1814
[1432]1815 my $pbextdir = pb_get_extdir();
1816
[471]1817 if ($cmt ne "Announce") {
[898]1818 # Get list of packages to build
[471]1819 my $ptr = pb_get_pkg();
1820 @pkgs = @$ptr;
[87]1821
[471]1822 # Get the running distro to consider
[1177]1823 $pbos = pb_distro_get_context($v);
[87]1824
[471]1825 # Get content saved in cms2build
1826 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
1827 $pkg = { } if (not defined $pkg);
[87]1828
[1212]1829 pb_mkdir_p("$ENV{'PBBUILDDIR'}") if (! -d "$ENV{'PBBUILDDIR'}");
[1208]1830 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
[471]1831 foreach my $pbpkg (@pkgs) {
1832 my $vertag = $pkg->{$pbpkg};
1833 # get the version of the current package - maybe different
[1459]1834 pb_log(2,"Vertag: $vertag\n");
[471]1835 ($pbver,$pbtag) = split(/-/,$vertag);
[87]1836
[1179]1837 if (($cmt eq "Sources") || ($cmt =~ /(V[EM]|RM)build/)) {
[1432]1838 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver$pbextdir.tar.gz $ENV{'PBDESTDIR'}/$pbpkg-$pbver$pbextdir.pbconf.tar.gz";
[471]1839 if ($cmd eq "") {
[1432]1840 $cmd = "ln -sf $pbpkg-$pbver$pbextdir.tar.gz $pbpkg-latest.tar.gz";
[471]1841 } else {
[1432]1842 $cmd = "$cmd ; ln -sf $pbpkg-$pbver$pbextdir.tar.gz $pbpkg-latest.tar.gz";
[471]1843 }
[560]1844 } elsif ($cmt eq "Web") {
[1432]1845 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver$pbextdir.tar.gz"
[166]1846 }
[1374]1847
1848 # Do we have one perl package
1849 my @nametype = pb_conf_get_if("namingtype");
1850 my $type = $nametype[0]->{$pbpkg};
1851 if ((defined $type) && ($type eq "perl")) {
1852 $cpanpkg = 1;
1853 }
[118]1854 }
[471]1855 # Adds conf file for availability of conf elements
1856 pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
[118]1857 }
[1374]1858 my ($rbsconf,$testver,$delivery) = pb_conf_get_if($conf,"testver","delivery");
1859 if ($cmt =~ /CPAN/) {
1860 # Do not deliver on Pause if this is a test version
[1384]1861 return if (not defined $testver);
[1374]1862 return if ($testver =~ /true/);
1863 # Do not deliver on Pause if this is not a perl package
1864 return if ($cpanpkg == 0);
1865 }
[417]1866
[1176]1867 if ($cmt =~ /(V[EM]|RM)build/) {
[1138]1868 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc $ENV{'PBDESTDIR'}/pbscript.$$";
[1176]1869 } elsif ($cmt =~ /(V[EM]|RM)Script/) {
[1138]1870 $src="$src $ENV{'PBDESTDIR'}/pbscript.$$";
[1176]1871 } elsif ($cmt =~ /(V[EM]|RM)test/) {
[1138]1872 $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";
[1374]1873 } elsif (($cmt eq "Announce") || ($cmt eq "Web") || ($cmt eq "CPAN")) {
[471]1874 $src="$src $ENV{'PBTMP'}/pbscript";
[118]1875 } elsif ($cmt eq "Packages") {
1876 # Get package list from file made during build2pkg
[1189]1877 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}-$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}-$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}";
[126]1878 $src = <KEEP>;
[118]1879 chomp($src);
1880 close(KEEP);
[1279]1881 $src = "$src $ENV{'PBBUILDDIR'}/pbscript.$$";
[87]1882 }
[1374]1883 if (($cmt eq "Sources") || ($cmt eq "Packages") || ($cmt eq "CPAN")) {
[1279]1884 my ($pbpackager) = pb_conf_get("pbpackager");
1885 $ENV{'PBPACKAGER'} = $pbpackager->{$ENV{'PBPROJ'}};
1886 pb_log(0,"Exporting public key for $ENV{'PBPACKAGER'}\n");
1887 # Using pb_system is not working due to redirection below
1888 system("gpg --export -a \'$ENV{'PBPACKAGER'}\' > $ENV{'PBDESTDIR'}/$ENV{'PBPROJ'}.pubkey");
1889 chmod 0644,"$ENV{'PBDESTDIR'}/$ENV{'PBPROJ'}.pubkey";
1890 $src = "$src $ENV{'PBDESTDIR'}/$ENV{'PBPROJ'}.pubkey";
1891 }
[320]1892 # Remove potential leading spaces (cause problem with basename)
[132]1893 $src =~ s/^ *//;
[129]1894 my $basesrc = "";
[131]1895 foreach my $i (split(/ +/,$src)) {
1896 $basesrc .= " ".basename($i);
[130]1897 }
[118]1898
[320]1899 pb_log(0,"Sources handled ($cmt): $src\n");
[987]1900 pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$path,$conf))."\n");
[1541]1901 my ($sshhost,$sshdir) = pb_conf_get($host,$dir);
[883]1902 # Not mandatory...
[1102]1903 $delivery->{$ENV{'PBPROJ'}} = "" if (not defined $delivery->{$ENV{'PBPROJ'}});
[1541]1904 my ($sshlogin,$sshport) = pb_conf_get_if($login,$port);
1905 $sshport->{$ENV{PBPROJ}} = 22 unless (defined $sshport->{$ENV{PBPROJ}});
1906 $sshlogin->{$ENV{PBPROJ}} = getpwuid($UID) unless (defined $sshlogin->{$ENV{PBPROJ}});
[883]1907 my ($vtmout,$vepath);
1908 # ...Except those in virtual context
1909 if ($cmt =~ /^VE/) {
1910 ($vepath) = pb_conf_get($path);
1911 }
[1176]1912 if ($cmt =~ /^(V|R)M/) {
[1218]1913 $vtmout = pb_distro_get_param($pbos,pb_conf_get_if($tmout));
[883]1914 }
[1216]1915 my $remhost = $sshhost->{$ENV{'PBPROJ'}};
1916 my $remdir = $sshdir->{$ENV{'PBPROJ'}};
1917 if ($cmt =~ /^V[EM]|RM/) {
1918 # In that case our real host is in the xxhost with the OS as key, not project as above
1919 $remhost = pb_distro_get_param($pbos,$sshhost);
[1176]1920 }
[1217]1921 pb_log(2,"ssh: ".Dumper(($remhost,$sshlogin,$remdir,$sshport,$vepath,$rbsconf))."\n");
1922 pb_log(2,"ssh: ".Dumper($vtmout)."\n") if (defined $vtmout);
[320]1923
1924 my $mac;
[772]1925 if ($cmt !~ /^VE/) {
[1216]1926 $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$remhost";
[320]1927 # Overwrite account value if passed as parameter
[1216]1928 $mac = "$pbaccount\@$remhost" if (defined $pbaccount);
[355]1929 pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
[681]1930 } else {
1931 # VE
[1138]1932 # Overwrite account value if passed as parameter (typically for setup2v)
[681]1933 $mac = $sshlogin->{$ENV{'PBPROJ'}};
1934 $mac = $pbaccount if (defined $pbaccount);
[320]1935 }
1936
[108]1937 my $tdir;
[136]1938 my $bdir;
[1176]1939 if (($cmt eq "Sources") || ($cmt =~ /(V[EM]|RM)Script/)) {
[1216]1940 $tdir = "$remdir/$delivery->{$ENV{'PBPROJ'}}/src";
[1374]1941 } elsif ($cmt eq "CPAN") {
1942 $tdir = "$remdir";
[1176]1943 } elsif ($cmt =~ /(V[EM]|RM)(build|test)/) {
[1216]1944 $tdir = $remdir."/$ENV{'PBPROJ'}/delivery";
1945 $bdir = $remdir."/$ENV{'PBPROJ'}/build";
[136]1946 # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
1947 $bdir =~ s|\$ENV.+\}/||;
[471]1948 } elsif ($cmt eq "Announce") {
[1216]1949 $tdir = "$remdir/$delivery->{$ENV{'PBPROJ'}}";
[556]1950 } elsif ($cmt eq "Web") {
[1216]1951 $tdir = "$remdir/$delivery->{$ENV{'PBPROJ'}}";
[90]1952 } elsif ($cmt eq "Packages") {
[1192]1953 if (($pbos->{'type'} eq "rpm") || ($pbos->{'type'} eq "pkg") || ($pbos->{'type'} eq "hpux") || ($pbos->{'type'} eq "tgz")) {
1954 # put packages under an arch subdir
[1216]1955 $tdir = "$remdir/$delivery->{$ENV{'PBPROJ'}}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}";
[1192]1956 } elsif (($pbos->{'type'} eq "deb") || ($pbos->{'type'} eq "ebuild")) {
1957 # No need for an arch subdir
[1216]1958 $tdir = "$remdir/$delivery->{$ENV{'PBPROJ'}}/$pbos->{'name'}/$pbos->{'version'}";
[1192]1959 } else {
1960 die "Please teach the dev team where to deliver ($pbos->{'type'} type of packages\n";
1961 }
[429]1962
1963 my $repodir = $tdir;
[1216]1964 $repodir =~ s|^$remdir/||;
[429]1965
1966 my ($pbrepo) = pb_conf_get("pbrepo");
1967
1968 # Repository management
[1189]1969 open(PBS,"> $ENV{'PBBUILDDIR'}/pbscript.$$") || die "Unable to create $ENV{'PBBUILDDIR'}/pbscript.$$";
[1177]1970 if ($pbos->{'type'} eq "rpm") {
[1276]1971 my $pbsha = pb_distro_get_param($pbos,pb_conf_get("ossha"));
[429]1972 # Also make a pbscript to generate yum/urpmi bases
1973 print PBS << "EOF";
[433]1974#!/bin/bash
[429]1975# Prepare a script to ease yum setup
[1298]1976EOF
1977 print PBS "set -x\n" if ($pbdebug gt 1);
1978 print PBS << "EOF";
[429]1979cat > $ENV{'PBPROJ'}.repo << EOT
1980[$ENV{'PBPROJ'}]
[1177]1981name=$pbos->{'name'} $pbos->{'version'} $pbos->{'arch'} - $ENV{'PBPROJ'} Vanilla Packages
[433]1982baseurl=$pbrepo->{$ENV{'PBPROJ'}}/$repodir
[429]1983enabled=1
[1289]1984gpgcheck=1
[1335]1985gpgkey=$pbrepo->{$ENV{'PBPROJ'}}/$repodir/$ENV{'PBPROJ'}.pubkey
[429]1986EOT
1987chmod 644 $ENV{'PBPROJ'}.repo
1988
1989# Clean up old repo content
1990rm -rf headers/ repodata/
1991# Create yum repo
[1102]1992if [ -x /usr/bin/yum-arch ]; then
1993 yum-arch .
1994fi
[429]1995# Create repodata
[1276]1996createrepo -s $pbsha .
[1365]1997# Link to the key
[1409]1998(cd repodata ; ln -sf ../$ENV{'PBPROJ'}.pubkey repomd.xml.key)
[1365]1999# sign the repomd (at least useful for SLES - which requires a local key)
2000# gpg -a --detach-sign repodata/repomd.xml
2001# SLES also looks for media.1/info.txt
[429]2002EOF
[1177]2003 if ($pbos->{'family'} eq "md") {
[429]2004 # For Mandriva add urpmi management
2005 print PBS << "EOF";
2006# Prepare a script to ease urpmi setup
2007cat > $ENV{'PBPROJ'}.addmedia << EOT
[1003]2008urpmi.addmedia $ENV{'PBPROJ'} $pbrepo->{$ENV{'PBPROJ'}}/$repodir with media_info/hdlist.cz
[429]2009EOT
2010chmod 755 $ENV{'PBPROJ'}.addmedia
2011
2012# Clean up old repo content
[437]2013rm -f hdlist.cz synthesis.hdlist.cz
[429]2014# Create urpmi repo
[1002]2015genhdlist2 --clean .
2016if [ \$\? -ne 0 ]; then
2017 genhdlist .
2018fi
[429]2019EOF
2020 }
[1177]2021 if ($pbos->{'name'} eq "fedora") {
[484]2022 # Extract the spec file to please Fedora maintainers :-(
2023 print PBS << "EOF";
2024for p in $basesrc; do
2025 echo \$p | grep -q 'src.rpm'
2026 if [ \$\? -eq 0 ]; then
2027 rpm2cpio \$p | cpio -ivdum --quiet '*.spec'
2028 fi
2029done
2030EOF
2031 }
[1177]2032 if ($pbos->{'family'} eq "novell") {
[1089]2033 # Add ymp scripts for one-click install on SuSE
2034 print PBS << "EOF";
2035# Prepare a script to ease SuSE one-click install
[1090]2036# Cf: http://de.opensuse.org/1-Klick-Installation/ISV
2037#
[1089]2038cat > $ENV{'PBPROJ'}.ymp << EOT
[1096]2039<?xml version="1.0" encoding="utf-8"?>
2040<!-- vim: set sw=2 ts=2 ai et: -->
[1089]2041<metapackage xmlns:os="http://opensuse.org/Standards/One_Click_Install" xmlns="http://opensuse.org/Standards/One_Click_Install">
2042 <group><!-- The group of software, typically one for project-builder.org -->
2043 <name>$ENV{'PBPROJ'} Bundle</name> <!-- Name of the software group -->
2044 <summary>Software bundle for the $ENV{'PBPROJ'} project</summary> <!--This message is shown to the user and should describe the whole bundle -->
[1095]2045 <description>This is the summary of the $ENV{'PBPROJ'} Project
[1089]2046
[1095]2047 Details are available on a per package basis below
2048
[1089]2049 </description><!--This is also shown to the user -->
2050 <remainSubscribed>false</remainSubscribed> <!-- Don't know what it mean -->
2051 <repositories><!-- List of needed repositories -->
2052 <repository>
2053 <name>$ENV{'PBPROJ'} Repository</name> <!-- Name of the repository -->
2054 <summary>This repository contains the $ENV{'PBPROJ'} project packages.</summary> <!-- Summary of the repository -->
2055 <description>This repository contains the $ENV{'PBPROJ'} project packages.</description><!-- This description is shown to the user -->
2056 <url>$pbrepo->{$ENV{'PBPROJ'}}/$repodir</url><!--URL of repository, which is added -->
2057 </repository>
2058 </repositories>
2059 <software><!-- A List of packages, which should be added through the one-click-installation -->
2060EOT
2061for p in $basesrc; do
2062 sum=`rpm -q --qf '%{SUMMARY}' \$p`
[1096]2063 name=`rpm -q --qf '%{NAME}' \$p`
[1089]2064 desc=`rpm -q --qf '%{description}' \$p`
2065 cat >> $ENV{'PBPROJ'}.ymp << EOT
2066 <item>
[1096]2067 <name>\$name</name><!-- Name of the package, is shown to the user and used to identify the package at the repository -->
[1089]2068 <summary>\$sum</summary> <!-- Summary of the package -->
2069 <description>\$desc</description> <!-- Description, is shown to the user -->
2070 </item>
2071EOT
2072done
2073cat >> $ENV{'PBPROJ'}.ymp << EOT
2074 </software>
2075 </group>
2076</metapackage>
2077EOT
2078chmod 644 $ENV{'PBPROJ'}.ymp
2079EOF
2080 }
[1177]2081 } elsif ($pbos->{'type'} eq "deb") {
[429]2082 # Also make a pbscript to generate apt bases
[460]2083 # Cf: http://www.debian.org/doc/manuals/repository-howto/repository-howto.fr.html
[1246]2084 # This dirname removes ver
[1283]2085 my $debarch = $pbos->{'arch'};
[1287]2086 $debarch = "amd64" if ($pbos->{'arch'} eq "x86_64");
[465]2087 my $rpd = dirname("$pbrepo->{$ENV{'PBPROJ'}}/$repodir");
[1357]2088 # Remove extra . in path to fix #522
2089 $rpd =~ s|/./|/|g;
[460]2090 print PBS << "EOF";
[465]2091#!/bin/bash
2092# Prepare a script to ease apt setup
2093cat > $ENV{'PBPROJ'}.sources.list << EOT
[1177]2094deb $rpd $pbos->{'version'} contrib
2095deb-src $rpd $pbos->{'version'} contrib
[460]2096EOT
[465]2097chmod 644 $ENV{'PBPROJ'}.sources.list
[460]2098
[1112]2099# Up two levels to deal with the dist dir cross versions
[1192]2100cd ..
[1275]2101mkdir -p dists/$pbos->{'version'}/contrib/binary-$debarch dists/$pbos->{'version'}/contrib/source
[1112]2102
[460]2103# Prepare a script to create apt info file
[1192]2104# Reuse twice after
[1112]2105TMPD=`mktemp -d /tmp/pb.XXXXXXXXXX` || exit 1
2106mkdir -p \$TMPD
2107cat > \$TMPD/Release << EOT
2108Archive: unstable
2109Component: contrib
2110Origin: $ENV{'PBPROJ'}
2111Label: $ENV{'PBPROJ'} dev repository $pbrepo->{$ENV{'PBPROJ'}}
2112EOT
2113
[1275]2114echo "Creating Packages metadata ($pbos->{'arch'} aka $debarch)"
2115dpkg-scanpackages -a$debarch $pbos->{'version'} /dev/null | gzip -c9 > dists/$pbos->{'version'}/contrib/binary-$debarch/Packages.gz
2116dpkg-scanpackages -a$debarch $pbos->{'version'} /dev/null | bzip2 -c9 > dists/$pbos->{'version'}/contrib/binary-$debarch/Packages.bz2
[1192]2117echo "Creating Contents metadata"
2118apt-ftparchive contents $pbos->{'version'} | gzip -c9 > dists/$pbos->{'version'}/Contents.gz
[1275]2119echo "Creating Release metadata ($pbos->{'arch'} aka $debarch)"
2120cat \$TMPD/Release > dists/$pbos->{'version'}/contrib/binary-$debarch/Release
[1279]2121echo "Architecture: $debarch" >> dists/$pbos->{'version'}/contrib/binary-$debarch/Release
[1112]2122echo "Creating Source metadata"
[1192]2123dpkg-scansources $pbos->{'version'} /dev/null | gzip -c9 > dists/$pbos->{'version'}/contrib/source/Sources.gz
[1177]2124cat \$TMPD/Release > dists/$pbos->{'version'}/contrib/source/Release
2125echo "Architecture: Source" >> dists/$pbos->{'version'}/contrib/source/Release
[1112]2126echo "Creating Release metadata"
[1388]2127# Signing that file would be useful but uneasy as gpg keys are not there
2128# Cf: http://wiki.debian.org/SecureApt
2129# Same as for repomd
[1177]2130apt-ftparchive release dists/$pbos->{'version'} > dists/$pbos->{'version'}/Release
[1112]2131rm -rf \$TMPD
[460]2132EOF
[1177]2133 } elsif ($pbos->{'type'} eq "ebuild") {
[586]2134 # make a pbscript to generate links to latest version
2135 print PBS << "EOF";
2136#!/bin/bash
2137# Prepare a script to create correct links
2138for p in $src; do
2139 echo \$p | grep -q '.ebuild'
2140 if [ \$\? -eq 0 ]; then
2141 j=`basename \$p`
2142 pp=`echo \$j | cut -d'-' -f1`
2143 ln -sf \$j \$pp.ebuild
2144 fi
2145done
2146EOF
[429]2147 }
2148 close(PBS);
[1189]2149 chmod 0755,"$ENV{'PBBUILDDIR'}/pbscript.$$";
[90]2150 } else {
2151 return;
[22]2152 }
[239]2153
[1143]2154 # Useless for VE
[1179]2155 my $nport = pb_get_port($sshport,$pbos,$cmt) if ($cmt !~ /^VE/);
[320]2156
[136]2157 # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
[132]2158 $tdir =~ s|\$ENV.+\}/||;
2159
[1217]2160 my $tm = "";
[1176]2161 if ($cmt =~ /^(V|R)M/) {
[1218]2162 $tm = "sleep $vtmout" if (defined $vtmout);
[883]2163 }
[320]2164
[1374]2165 # ssh communication if not VE or CPAN
[349]2166 # should use a hash instead...
[320]2167 my ($shcmd,$cpcmd,$cptarget,$cp2target);
[1374]2168 if ($cmt =~ /^VE/) {
[1541]2169 my $tp = pb_path_expand($vepath->{$ENV{'PBPROJ'}});
2170 my $tpdir = pb_path_expand("$tp/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}");
[681]2171 my ($ptr) = pb_conf_get("vetype");
2172 my $vetype = $ptr->{$ENV{'PBPROJ'}};
[1545]2173 my $arch = pb_get_arch();
[681]2174 if ($vetype eq "chroot") {
[1179]2175 $shcmd = "sudo /usr/sbin/chroot $tpdir /bin/su - $mac -c ";
[681]2176 } elsif ($vetype eq "schroot") {
2177 $shcmd = "schroot $tp -u $mac -- ";
2178 }
[1545]2179 $sshcmd = "setarch i386 $sshcmd" if (($pbos->{'arch'} =~ /i?86/) && ($arch eq 'x86_64'));
[1179]2180 $cpcmd = "sudo /bin/cp -r ";
[681]2181 # We need to get the home dir of the target account to deliver in the right place
[1541]2182 open(PASS,"$tpdir/etc/passwd") || die "Unable to open $tpdir/etc/passwd: $!";
[681]2183 my $homedir = "";
2184 while (<PASS>) {
2185 my ($c1,$c2,$c3,$c4,$c5,$c6,$c7) = split(/:/);
2186 $homedir = $c6 if ($c1 =~ /^$mac$/);
2187 pb_log(3,"Homedir: $homedir - account: $c6\n");
2188 }
2189 close(PASS);
2190 $cptarget = "$tpdir/$homedir/$tdir";
[773]2191 if ($cmt eq "VEbuild") {
[681]2192 $cp2target = "$tpdir/$homedir/$bdir";
2193 }
2194 pb_log(2,"On VE using $cptarget as target dir to copy to\n");
[1374]2195 } elsif ($cmt =~ /^CPAN/) {
[1382]2196 my $ftpput = pb_check_req("ncftpput",1);
2197 my $ftpget = pb_check_req("wget",1);
[1374]2198 my ($cpanuser,$cpanpasswd) = pb_conf_get("cpanuser","cpanpasswd");
2199 my ($cpansubdir) = pb_conf_get_if("cpansubdir");
2200 $shcmd = "$ftpget --post-data \'HIDDENNAME=".$cpanuser;
2201 $shcmd .= "&user=".$cpanuser;
2202 $shcmd .= "&password=".$cpanpasswd;
2203 $shcmd .= "&SUBMIT_pause99_add_uri_upload=\"Upload the checked files\"";
2204 $shcmd .= "&pause99_add_uri_subdirtext=".$cpansubdir if (defined $cpansubdir);
2205 foreach my $s (split(/ /,$src)) {
2206 $shcmd .= "&pause99_add_uri_upload=".basename($s);
2207 }
2208 $shcmd .= "'";
2209 $cpcmd = "$ftpput $host $dir";
2210 $cptarget = "CPAN";
2211 } else {
2212 my $keyfile = pb_ssh_get(0);
[1545]2213 my $keyopt = defined $keyfile ? "-i $keyfile" : "";
[1382]2214 my $sshcmd = pb_check_req("ssh",1);
2215 my $scpcmd = pb_check_req("scp",1);
[1545]2216 $shcmd = "$sshcmd $keyopt -q -o NoHostAuthenticationForLocalhost=yes -p $nport $mac";
2217 $cpcmd = "$scpcmd $keyopt -p -o NoHostAuthenticationForLocalhost=yes -P $nport";
[1374]2218 $cptarget = "$mac:$tdir";
2219 if ($cmt =~ /^(V|R)Mbuild/) {
2220 $cp2target = "$mac:$bdir";
2221 }
[320]2222 }
[1374]2223
[471]2224 my $logres = "";
2225 # Do not touch when just announcing
[1374]2226 if (($cmt ne "Announce") && ($cmt ne "CPAN")) {
[908]2227 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");
[471]2228 } else {
2229 $logres = "> ";
2230 }
[320]2231 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
[444]2232
[681]2233 # For VE we need to change the owner manually
[772]2234 if ($cmt =~ /^VE/) {
[681]2235 pb_system("$shcmd \"sudo chown -R $mac $tdir\"","Adapt owner in $tdir to $mac");
2236 }
2237
[1140]2238 # Use the right script name depending on context
2239 my $pbscript;
[1189]2240 if (($cmt =~ /^(V[EM]|RM)/) || ($cmt =~ /Packages/)){
[1140]2241 $pbscript = "pbscript.$$";
2242 } else {
2243 $pbscript = "pbscript";
2244 }
2245
[1374]2246 # It's already ready for CPAN
[1383]2247 my $shcmdbase = $shcmd;
[1374]2248 if ($cmt !~ /^CPAN/) {
[1383]2249 $shcmd .= " \"echo \'cd $tdir ; if [ -x $pbscript ]; then ./$pbscript; fi ; rm -f ./$pbscript\' | bash\"";
[1374]2250 }
[1386]2251 my $cmdverb = "verbose";
[1388]2252 if (($cmt eq "Announce") || ($cmt eq "CPAN")) {
[1386]2253 $cmdverb = undef;
2254 }
2255 pb_system("$shcmd","Executing pbscript on $cptarget if needed",$cmdverb);
[1176]2256 if ($cmt =~ /^(V[EM]|RM)build/) {
2257 # Get back info on pkg produced, compute their name and get them from the VM/RM
[1189]2258 pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}-$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'} $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.$$ 2> /dev/null","Get package names in $cp2target");
[681]2259 # For VE we need to change the owner manually
[772]2260 if ($cmt eq "VEbuild") {
[1138]2261 pb_system("sudo chown $UID $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.$$","Adapt owner in $tdir to $UID");
[681]2262 }
[1138]2263 if (not -f "$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.$$") {
[1176]2264 pb_log(0,"Problem with VM/RM $v on $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.$$");
[1156]2265 } else {
2266 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.$$") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.$$";
2267 my $src = <KEEP>;
2268 chomp($src);
2269 close(KEEP);
2270 unlink("$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.$$");
[1138]2271
[1156]2272 $src =~ s/^ *//;
[1179]2273 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}");
[1156]2274 # Change pgben to make the next send2target happy
2275 my $made = "";
2276
[1176]2277 # For VM/RM we don't want shell expansion to hapen locally but remotely
[1156]2278 my $delim = '\'';
2279 if ($cmt =~ /^VEbuild/) {
2280 # For VE we need to support shell expansion locally
2281 $delim = "";
2282 }
[1138]2283
[1189]2284 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}-$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}-$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}";
[1156]2285 foreach my $p (split(/ +/,$src)) {
2286 my $j = basename($p);
[1179]2287 pb_system("$cpcmd $cp2target/$delim$p$delim $ENV{'PBBUILDDIR'}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'} 2> /dev/null","Recovery of package $j in $ENV{'PBBUILDDIR'}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}");
2288 $made="$made $pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/$j"; # if (($pbos->{'type'} ne "rpm") || ($j !~ /.src.rpm$/));
[1156]2289 }
2290 print KEEP "$made\n";
2291 close(KEEP);
[1383]2292 pb_system("$shcmdbase \"rm -rf $tdir $bdir\"","$cmt cleanup");
[1138]2293
[1156]2294 # Sign packages locally
[1278]2295 pb_sign_pkgs($pbos,$made);
[1156]2296
2297 # We want to send them to the ssh account so overwrite what has been done before
2298 undef $pbaccount;
2299 pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
[1179]2300 pb_send2target("Packages",$pbos->{'name'}."-".$pbos->{'version'}."-".$pbos->{'arch'},$vmexist,$vmpid);
2301 pb_rm_rf("$ENV{'PBBUILDDIR'}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}");
[623]2302 }
[108]2303 }
[1425]2304 unlink("$ENV{'PBDESTDIR'}/pbscript.$$") if ((($cmt =~ /^(V[ME]|RM)/) || ($cmt =~ /Packages/)) && ($pbkeep eq 0));
[1139]2305
[442]2306 pb_log(2,"Before halt, vmexist: $vmexist, vmpid: $vmpid\n");
[772]2307 if ((! $vmexist) && ($cmt =~ /^VM/)) {
[748]2308 # If in setupvm then takes a snapshot just before halting
2309 if ($snapme != 0) {
2310 my ($vmmonport,$vmtype) = pb_conf_get("vmmonport","vmtype");
2311 # For monitoring control
2312 if ((($vmtype->{$ENV{'PBPROJ'}}) eq "kvm") || (($vmtype->{$ENV{'PBPROJ'}}) eq "qemu")) {
[1153]2313 eval
2314 {
[804]2315 require Net::Telnet;
[1153]2316 Net::Telnet->import();
2317 };
2318 if ($@) {
2319 # Net::Telnet not found
2320 pb_log(1,"ADVISE: Install Net::Telnet to benefit from monitoring control and snapshot feature.\nWARNING: No snapshot created");
2321 } else {
2322 my $t = new Net::Telnet (Timeout => 120, Host => "localhost", Port => $vmmonport->{$ENV{'PBPROJ'}}) || die "Unable to dialog on the monitor";
2323 # move to monitor mode
2324 my @lines = $t->cmd("c");
2325 # Create a snapshot named pb
2326 @lines = $t->cmd("savevm pb");
2327 # Write the new status in the VM
2328 @lines = $t->cmd("commit all");
2329 # End
2330 @lines = $t->cmd("quit");
2331 }
[748]2332 }
2333 }
[914]2334 my $hoption = "-p";
[1197]2335 my $hpath = pb_distro_get_param($pbos,pb_conf_get("ospathcmd-halt"));
[1194]2336 # Solaris doesn't support -p of halt
[1177]2337 if ($pbos->{'type'} eq "pkg") {
[1091]2338 $hoption = "" ;
2339 }
[1383]2340 pb_system("$shcmdbase \"sudo $hpath $hoption \"; $tm ; echo \'if [ -d /proc/$vmpid ]; then kill -9 $vmpid; fi \' | bash ; sleep 10","VM $v halt (pid $vmpid)");
[442]2341 }
[772]2342 if (($cmt =~ /^VE/) && ($snapme != 0)) {
[1179]2343 my $tpdir = "$vepath->{$ENV{'PBPROJ'}}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}";
2344 pb_system("sudo tar cz -C $tpdir -f $vepath->{$ENV{'PBPROJ'}}/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz .","Creating a snapshot of $tpdir");
[752]2345 }
[9]2346}
[16]2347
[320]2348sub pb_script2v {
[142]2349 my $pbscript=shift;
[320]2350 my $vtype=shift;
[1138]2351 my $pbforce=shift || 0; # Force stop of VM. Default not.
[1176]2352 my $vm1=shift || undef; # Only that VM/VE/RM to treat. Default all.
[1138]2353 my $snapme=shift || 0; # Do we have to create a snapshot. Default not.
[442]2354 my $vm;
2355 my $all;
[141]2356
[767]2357 pb_log(2,"DEBUG: pb_script2v($pbscript,$vtype,$pbforce,".Dumper($vm1).",$snapme)\n");
[1176]2358 # Prepare the script to be executed on the VM/VE/RM
[1138]2359 # in $ENV{'PBDESTDIR'}/pbscript.$$
2360 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript.$$")) {
2361 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript.$$") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript.$$";
2362 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript.$$";
[142]2363 }
[141]2364
[442]2365 if (not defined $vm1) {
[772]2366 ($vm,$all) = pb_get2v($vtype);
[442]2367 } else {
2368 @$vm = ($vm1);
2369 }
[320]2370 my ($vmexist,$vmpid) = (undef,undef);
[142]2371
[141]2372 foreach my $v (@$vm) {
[968]2373 # Launch VM/VE
2374 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0,$snapme,$pbsnap);
[755]2375
[320]2376 if ($vtype eq "vm") {
[442]2377 pb_log(2,"DEBUG: After pb_launchv, vmexist: $vmexist, vmpid: $vmpid\n");
[141]2378
[1176]2379 # Skip that VM/RM if something went wrong
[442]2380 next if (($vmpid == 0) && ($vmexist == 0));
2381
2382 # If force stopping the VM then reset vmexist
[748]2383 if ($pbforce == 1) {
[442]2384 $vmpid = $vmexist;
2385 $vmexist = 0;
2386 }
[670]2387 } else {
2388 #VE
2389 $vmexist = 0;
2390 $vmpid = 0;
[320]2391 }
[274]2392
[1176]2393 # Gather all required files to send them to the VM/VE/RM
[320]2394 # and launch the build through pbscript
[442]2395 pb_log(2,"DEBUG: Before send2target, vmexist: $vmexist, vmpid: $vmpid\n");
[748]2396 pb_send2target(uc($vtype)."Script","$v",$vmexist,$vmpid,$snapme);
[169]2397
[142]2398 }
2399}
2400
[320]2401sub pb_launchv {
2402 my $vtype = shift;
2403 my $v = shift;
[1176]2404 my $create = shift || 0; # By default do not create a VM/VE/RM
2405 my $snapme = shift || 0; # By default do not snap a VM/VE/RM
[1349]2406 my $usesnap = shift || 1; # By default study the usage of the snapshot feature of VM/VE/RM
[310]2407
[773]2408 # If creation or snapshot creation mode, no snapshot usable
2409 if (($create == 1) || ($snapme == 1)) {
2410 $usesnap = 0;
2411 }
2412
2413 pb_log(2,"DEBUG: pb_launchv($vtype,$v,$create,$snapme,$usesnap)\n");
[1176]2414 die "No VM/VE/RM defined, unable to launch" if (not defined $v);
[320]2415 # Keep only the first VM in case many were given
[1537]2416 if ($v =~ /,/) {
2417 pb_log(0,"WARNING: pruning to just the first of several vms listed ($v)\n");
2418 $v =~ s/,.*//;
2419 }
[310]2420
[1179]2421 my $pbos = pb_distro_get_context($v);
[1348]2422
[320]2423 # Launch the VMs/VEs
2424 if ($vtype eq "vm") {
2425 die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
[310]2426
[1540]2427 my ($ptr,$ptr2,$vmpath,$vmport,$vms) = pb_conf_get("vmtype","vmcmd","vmpath","vmport","vmsize");
2428 my ($vmopt,$vmmm,$vmtmout,$vmsnap,$vmbuildtm,$vmmonport) = pb_conf_get_if("vmopt","vmmem","vmtmout","vmsnap","vmbuildtm","vmmonport");
[1249]2429 my $vmsize = pb_distro_get_param($pbos,$vms);
[320]2430
2431 my $vmtype = $ptr->{$ENV{'PBPROJ'}};
[1072]2432 my $vmcmd = $ptr2->{$ENV{'PBPROJ'}};
[1124]2433
2434 if (defined $opts{'g'}) {
2435 if (($vmtype eq "kvm") || ($vmtype eq "qemu")) {
[1158]2436 $ENV{'PBVMOPT'} = "--nographic";
[1124]2437 }
2438 }
[320]2439 if (not defined $ENV{'PBVMOPT'}) {
2440 $ENV{'PBVMOPT'} = "";
[310]2441 }
[639]2442 # Save the current status for later restoration
2443 $ENV{'PBOLDVMOPT'} = $ENV{'PBVMOPT'};
[483]2444 # Set a default timeout of 2 minutes
2445 if (not defined $ENV{'PBVMTMOUT'}) {
2446 $ENV{'PBVMTMOUT'} = "120";
2447 }
2448 if (defined $vmopt->{$v}) {
2449 $ENV{'PBVMOPT'} .= " $vmopt->{$v}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$v}/);
2450 } elsif (defined $vmopt->{$ENV{'PBPROJ'}}) {
[320]2451 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
2452 }
[773]2453
[1143]2454 # How much memory to allocate for VMs
[1540]2455 if (defined $vmmm) {
2456 my $vmmem = pb_distro_get_param($pbos,$vmmm);
2457 if (defined $vmmem) {
2458 $ENV{'PBVMOPT'} .= " -m $vmmem";
2459 }
[1143]2460 }
2461
[773]2462 # Are we allowed to use snapshot feature
2463 if ($usesnap == 1) {
[748]2464 if ((defined $vmsnap->{$v}) && ($vmsnap->{$v} =~ /true/i)) {
[1070]2465 $ENV{'PBVMOPT'} .= " -snapshot";
[748]2466 } elsif ((defined $vmsnap->{$ENV{'PBPROJ'}}) && ($vmsnap->{$ENV{'PBPROJ'}} =~ /true/i)) {
[1070]2467 $ENV{'PBVMOPT'} .= " -snapshot";
[748]2468 } elsif ($pbsnap eq 1) {
[1070]2469 $ENV{'PBVMOPT'} .= " -snapshot";
[748]2470 }
[767]2471 }
2472 if ($snapme != 0) {
[748]2473 if (($vmtype eq "kvm") || ($vmtype eq "qemu")) {
[1138]2474 # Configure the monitoring to automate the creation of the 'pb' snapshot
[1540]2475 $ENV{'PBVMOPT'} .= " -serial mon:telnet::$vmmonport->{$ENV{'PBPROJ'}},server,nowait" if ((defined $vmmonport) && (defined $vmmonport->{$ENV{'PBPROJ'}}));
[773]2476 # In that case no snapshot call needed
[1070]2477 $ENV{'PBVMOPT'} =~ s/ -snapshot//;
[748]2478 }
2479 }
[483]2480 if (defined $vmtmout->{$v}) {
2481 $ENV{'PBVMTMOUT'} = $vmtmout->{$v};
2482 } elsif (defined $vmtmout->{$ENV{'PBPROJ'}}) {
2483 $ENV{'PBVMTMOUT'} = $vmtmout->{$ENV{'PBPROJ'}};
2484 }
[1179]2485 my $nport = pb_get_port($vmport,$pbos,$vtype);
[320]2486
2487 my $cmd;
2488 my $vmm; # has to be used for pb_check_ps
[677]2489 if (($vmtype eq "qemu") || ($vmtype eq "kvm")) {
2490 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
[792]2491 if (($create != 0) || (defined $iso)) {
[677]2492 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
[320]2493 }
[748]2494 # Always redirect the network and always try to use a 'pb' snapshot
[1340]2495 #$cmd = "$vmcmd $ENV{'PBVMOPT'} -net user,hostfwd=tcp:$nport:10.0.2.15:22 -loadvm pb $vmm"
[1381]2496 $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
[320]2497 } elsif ($vmtype eq "xen") {
2498 } elsif ($vmtype eq "vmware") {
[310]2499 } else {
[320]2500 die "VM of type $vmtype not supported. Report to the dev team";
[310]2501 }
[639]2502 # Restore the ENV VAR Value
[641]2503 $ENV{'PBVMOPT'} = $ENV{'PBOLDVMOPT'};
[639]2504
[320]2505 my ($tmpcmd,$void) = split(/ +/,$cmd);
2506 my $vmexist = pb_check_ps($tmpcmd,$vmm);
2507 my $vmpid = 0;
2508 if (! $vmexist) {
2509 if ($create != 0) {
[653]2510 die("Found an existing Virtual machine $vmm. Won't overwrite") if (-r $vmm);
[677]2511 if (($vmtype eq "qemu") || ($vmtype eq "xen") || ($vmtype eq "kvm")) {
[1127]2512 my $command = pb_check_req("qemu-img",0);
[1249]2513 pb_system("$command create -f qcow2 $vmm $vmsize","Creating the QEMU VM");
[320]2514 } elsif ($vmtype eq "vmware") {
2515 } else {
2516 }
2517 }
2518 if (! -f "$vmm") {
2519 pb_log(0,"Unable to find VM $vmm\n");
2520 } else {
[1153]2521 # Is the SSH port free? if not kill the existing process using it after a build timeout period
2522 my $vmssh = pb_check_ps($tmpcmd,"tcp:$nport:10.0.2.15:22");
2523 if ($vmssh) {
2524 my $buildtm = $ENV{'PBVMTMOUT'};
2525 if (defined $vmbuildtm->{$v}) {
2526 $buildtm = $vmbuildtm->{$v};
2527 } elsif (defined $vmbuildtm->{$ENV{'PBPROJ'}}) {
2528 $buildtm = $vmbuildtm->{$ENV{'PBPROJ'}};
2529 }
2530
2531 sleep $buildtm;
2532 pb_log(0,"WARNING: Killing the process ($vmssh) using port $nport (previous failed VM ?)\n");
2533 kill 15,$vmssh;
[1154]2534 # Let it time to exit
2535 sleep 5;
[1153]2536 }
[320]2537 pb_system("$cmd &","Launching the VM $vmm");
[1540]2538 # Using system allows to kill it externaly if needed,sosupport that in the call
2539 pb_system("sleep $ENV{'PBVMTMOUT'}","Waiting $ENV{'PBVMTMOUT'} s for VM $v to come up",undef,1);
[320]2540 $vmpid = pb_check_ps($tmpcmd,$vmm);
[357]2541 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
[320]2542 }
[310]2543 } else {
[320]2544 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
[310]2545 }
[442]2546 pb_log(2,"DEBUG: pb_launchv returns ($vmexist,$vmpid)\n");
[320]2547 return($vmexist,$vmpid);
[1176]2548 } elsif ($vtype eq "ve") {
[1360]2549 # Force the creation of the VE and no snapshot usable
[1388]2550 pb_ve_launch($v,$create,$usesnap);
[1176]2551 } else {
2552 # RM here
2553 # Get distro context
[1177]2554 my $pbos = pb_distro_get_context($v);
[1176]2555
2556 # Get RM context
2557 my ($ptr,$rmpath) = pb_conf_get("rmtype","rmpath");
2558
2559 # Nothing more to do for RM. No real launch
2560 # For the moment we support the RM is already running
2561 # For ProLiant may be able to power them on if needed later on as an example.
[141]2562 }
2563}
[142]2564
[639]2565# Return string for date synchro
[772]2566sub pb_date2v {
[639]2567
2568my $vtype = shift;
[1216]2569my $pbos = shift;
[639]2570
[1545]2571# VE gets time from parent OS.
2572return "/bin/true" if ($vtype) =~ /^ve/o;
2573
[986]2574my ($ntp) = pb_conf_get_if($vtype."ntp");
2575my $vntp = $ntp->{$ENV{'PBPROJ'}} if (defined $ntp);
[1221]2576my $ntpline = undef;
[639]2577
2578if (defined $vntp) {
[1221]2579 # ntp command depends on pbos
2580 my $vntpcmd = pb_distro_get_param($pbos,pb_conf_get($vtype."ntpcmd"));
[652]2581 $ntpline = "sudo $vntpcmd $vntp";
[639]2582}
2583# Force new date to be in the future compared to the date
2584# of the host by adding 1 minute
2585my @date=pb_get_date();
2586$date[1]++;
2587my $upddate = strftime("%m%d%H%M%Y", @date);
[1179]2588my $dateline = "sudo /bin/date $upddate";
[1190]2589if (defined $ntpline) {
2590 return($ntpline);
2591} else {
2592 return($dateline);
[639]2593}
[1190]2594}
[639]2595
[320]2596sub pb_build2v {
[118]2597
[320]2598my $vtype = shift;
[772]2599my $action = shift || "build";
[142]2600
[772]2601my ($v,$all) = pb_get2v($vtype);
[320]2602
2603# Send tar files when we do a global generation
[772]2604pb_build2ssh() if (($all == 1) && ($action eq "build"));
[320]2605
[1143]2606# Adapt // mode to memory size
2607$pbparallel = pb_set_parallel($vtype);
2608
[320]2609my ($vmexist,$vmpid) = (undef,undef);
[1176]2610my $pm;
2611if (defined $pbparallel) {
2612 $pm = new Parallel::ForkManager($pbparallel);
[320]2613
[1176]2614 # Set which port the VM/RM will use to communicate
2615 $pm->run_on_start(\&pb_set_port);
2616}
[1143]2617
2618my $counter = 0;
[320]2619foreach my $v (@$v) {
[1143]2620 $counter++;
[1153]2621 # Modulo 2 * pbparallel (to avoid synchronization problems)
[1176]2622 $counter = 1 if ((defined $pbparallel) && ($counter > 2 * $pbparallel));
[1143]2623 $pm->start($counter) and next if (defined $pbparallel);
[1176]2624 # Prepare the script to be executed on the VM/VE/RM
[1138]2625 # in $ENV{'PBDESTDIR'}/pbscript.$$
2626 open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript.$$") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript.$$";
[652]2627 print SCRIPT "#!/bin/bash\n";
[721]2628
2629 # Transmit the verbosity level to the virtual env/mach.
2630 my $verbose = "";
2631 my $i = 0; # minimal debug level
2632 while ($i lt $pbdebug) {
2633 $verbose .= "-v ";
2634 $i++;
2635 }
[1545]2636 print SCRIPT "set -e\n" if $Global::pb_stop_on_error;
[721]2637 # Activate script verbosity if at least 2 for pbdebug
2638 print SCRIPT "set -x\n" if ($i gt 1);
2639 # Quiet if asked to be so on the original system
2640 $verbose = "-q" if ($pbdebug eq -1);
2641
[652]2642 print SCRIPT "echo ... Execution needed\n";
2643 print SCRIPT "# This is in directory delivery\n";
2644 print SCRIPT "# Setup the variables required for building\n";
2645 print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
[686]2646
[772]2647 if ($action eq "build") {
2648 print SCRIPT "# Preparation for pb\n";
2649 print SCRIPT "mv .pbrc \$HOME\n";
2650 print SCRIPT "cd ..\n";
2651 }
2652
[1545]2653 # VE needs a good /proc, tolerate one being potentially left around after a failure
[687]2654 if ($vtype eq "ve") {
[1545]2655 print SCRIPT "[ -d /proc/1 ] || sudo /bin/mount -t proc /proc /proc\n";
[686]2656 }
[652]2657
[1216]2658 # Get distro context
2659 my $pbos = pb_distro_get_context($v);
2660
2661 my $ntpline = pb_date2v($vtype,$pbos);
[652]2662 print SCRIPT "# Time sync\n";
[1545]2663 print SCRIPT "echo setting up date with $ntpline\n";
[1190]2664 print SCRIPT "$ntpline\n";
[721]2665 # Use potential local proxy declaration in case we need it to download repo, pkgs, ...
2666 if (defined $ENV{'http_proxy'}) {
2667 print SCRIPT "export http_proxy=\"$ENV{'http_proxy'}\"\n";
2668 }
[652]2669
[721]2670 if (defined $ENV{'ftp_proxy'}) {
2671 print SCRIPT "export ftp_proxy=\"$ENV{'ftp_proxy'}\"\n";
[652]2672 }
2673
[772]2674 # Get list of packages to build/test and get some ENV vars as well
2675 my $ptr = pb_get_pkg();
2676 @pkgs = @$ptr;
2677 my $p = join(' ',@pkgs) if (@pkgs);
2678 print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
2679 print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
2680 print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
[721]2681
2682 # We may need to do some other tasks before building. Read a script here to finish setup
[772]2683 if (-x "$ENV{'PBDESTDIR'}/pb$vtype".".pre") {
2684 print SCRIPT "# Special pre-instructions to be launched\n";
2685 print SCRIPT pb_get_content("$ENV{'PBDESTDIR'}/pb$vtype".".pre");
[721]2686 }
2687
[772]2688 if (-x "$ENV{'PBDESTDIR'}/pb$vtype"."$action.pre") {
2689 print SCRIPT "# Special pre-$action instructions to be launched\n";
2690 print SCRIPT pb_get_content("$ENV{'PBDESTDIR'}/pb$vtype"."$action.pre");
2691 }
2692
2693 print SCRIPT "# $action\n";
2694 print SCRIPT "echo $action"."ing packages on $vtype...\n";
2695
2696 if (($action eq "test") && (! -x "$ENV{'PBDESTDIR'}/pbtest")) {
2697 die "No test script ($ENV{'PBDESTDIR'}/pbtest) found when in test mode. Aborting ...";
2698 }
2699 print SCRIPT "pb $verbose -p $ENV{'PBPROJ'} $action"."2pkg $p\n";
2700
[687]2701 if ($vtype eq "ve") {
[1179]2702 print SCRIPT "sudo /bin/umount /proc\n";
[686]2703 }
[721]2704
2705 # We may need to do some other tasks after building. Read a script here to exit properly
[772]2706 if (-x "$ENV{'PBDESTDIR'}/pb$vtype"."$action.post") {
2707 print SCRIPT "# Special post-$action instructions to be launched\n";
2708 print SCRIPT pb_get_content("$ENV{'PBDESTDIR'}/pb$vtype"."$action.post");
[721]2709 }
2710
[772]2711 if (-x "$ENV{'PBDESTDIR'}/pb$vtype".".post") {
2712 print SCRIPT "# Special post-instructions to be launched\n";
2713 print SCRIPT pb_get_content("$ENV{'PBDESTDIR'}/pb$vtype".".post");
2714 }
2715
[1546]2716 print SCRIPT q{echo "********** Successful exit of script $$ *********************"}, "\n";
[652]2717 close(SCRIPT);
[1138]2718 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript.$$";
[652]2719
[1176]2720 # Launch the VM/VE/RM
[755]2721 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
2722
[1139]2723
[320]2724 if ($vtype eq "vm") {
[1143]2725 # Skip that VM if something went wrong
[1139]2726 if (($vmpid == 0) && ($vmexist == 0)) {
2727 $pm->finish if (defined $pbparallel);
2728 next;
2729 }
[658]2730 } else {
[1176]2731 # VE/RM
[658]2732 $vmexist = 0;
2733 $vmpid = 0;
[118]2734 }
[320]2735 # Gather all required files to send them to the VM/VE
[347]2736 # and launch the build through pbscript
[357]2737 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
[772]2738 pb_send2target(uc($vtype).$action,"$v",$vmexist,$vmpid);
[1139]2739 $pm->finish if (defined $pbparallel);
[105]2740}
[1176]2741$pm->wait_all_children if (defined $pbparallel);
[320]2742}
[105]2743
[262]2744
[739]2745sub pb_clean {
2746
2747 my $sleep=10;
2748 die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
2749 die "Unable to get env var PBBUILDDIR" if (not defined $ENV{'PBBUILDDIR'});
2750 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");
2751 sleep $sleep;
2752 pb_rm_rf($ENV{'PBDESTDIR'});
2753 pb_rm_rf($ENV{'PBBUILDDIR'});
2754}
2755
[199]2756sub pb_newver {
2757
[204]2758 die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
[340]2759
[366]2760 # Need this call for PBDIR
2761 my ($scheme2,$uri) = pb_cms_init($pbinit);
[361]2762
[898]2763 my ($pbconf,$pburl) = pb_conf_get("pbconfurl","pburl");
[366]2764 $uri = $pbconf->{$ENV{'PBPROJ'}};
2765 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
2766
[361]2767 # Checking CMS repositories status
[366]2768 ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
[340]2769
2770 if ($scheme !~ /^svn/) {
[199]2771 die "Only SVN is supported at the moment";
2772 }
[483]2773
[1469]2774 my $res = pb_vcs_isdiff($scheme,$ENV{'PBROOTDIR'});
[361]2775 die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
[358]2776
[1469]2777 $res = pb_vcs_isdiff($scheme2,$ENV{'PBDIR'});
[361]2778 die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
[358]2779
2780 # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
2781 # we want to get for the root of the new URL
2782
[1381]2783 my $oldver = $ENV{'PBROOTDIR'};
2784 $oldver =~ s|^$ENV{'PBCONFDIR'}||;
[358]2785
[1381]2786 pb_log(2, "PBCONFDIR: $ENV{'PBCONFDIR'}\nPBROOTDIR: $ENV{'PBROOTDIR'}\n");
2787
2788 my $newurl = "$uri/$newver";
[366]2789 # Should probably use projver in the old file
[1381]2790 my $oldvertxt= basename($oldver);
2791 my $newvertxt = basename($newver);
[361]2792
[366]2793 # Duplicate and extract project-builder part
[1381]2794 pb_log(2,"Copying $uri/$oldver to $newurl\n");
[1469]2795 pb_vcs_copy($scheme,"$uri/$oldver",$newurl);
[1381]2796 pb_log(2,"Checkout $newurl to $ENV{'PBCONFDIR'}/$newver\n");
[1469]2797 pb_vcs_up($scheme,"$ENV{'PBCONFDIR'}");
[361]2798
[366]2799 # Duplicate and extract project
[1381]2800 my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/$newver";
[366]2801
[1381]2802 pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$oldver to $newurl2\n");
[1469]2803 pb_vcs_copy($scheme2,"$pburl->{$ENV{'PBPROJ'}}/$oldver",$newurl2);
[366]2804
[1381]2805 my $tmp = $ENV{'PBDIR'};
2806 $tmp =~ s|$oldver$||;
2807 pb_log(2,"Checkout $newurl2 to $tmp/$newver\n");
[1469]2808 pb_vcs_up($scheme2,"$tmp");
[1381]2809
[361]2810 # Update the .pb file
[1381]2811 open(FILE,"$ENV{'PBCONFDIR'}/$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBCONFDIR'}/$newver/$ENV{'PBPROJ'}.pb";
2812 open(OUT,"> $ENV{'PBCONFDIR'}/$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBCONFDIR'}/$newver/$ENV{'PBPROJ'}.pb.new";
[208]2813 while(<FILE>) {
[1420]2814 if (/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldvertxt$/) {
2815 s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldvertxt$/projver $ENV{'PBPROJ'} = $newvertxt/;
[1381]2816 pb_log(0,"Changing projver from $oldvertxt to $newvertxt in $ENV{'PBCONFDIR'}/$newver/$ENV{'PBPROJ'}.pb\n");
2817 }
2818 if (/^testver/) {
2819 s/^testver/#testver/;
2820 pb_log(0,"Commenting testver in $ENV{'PBCONFDIR'}/$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
2821 }
2822 if (/^delivery/) {
[1420]2823 my $txt = $_;
2824 chomp($txt);
2825 pb_log(0,"Please check delivery ($txt) in $ENV{'PBCONFDIR'}/$newver/$ENV{'PBPROJ'}.pb\n");
[1381]2826 }
[211]2827 print OUT $_;
[208]2828 }
2829 close(FILE);
[211]2830 close(OUT);
[1381]2831 rename("$ENV{'PBCONFDIR'}/$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBCONFDIR'}/$newver/$ENV{'PBPROJ'}.pb");
[363]2832
[479]2833 # Checking pbcl files
2834 foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
[590]2835 # Compute new pbcl file
2836 my $f2 = $f;
[1381]2837 $f2 =~ s|$ENV{'PBROOTDIR'}|$ENV{'PBCONFDIR'}/$newver/|;
[479]2838 open(PBCL,$f) || die "Unable to open $f";
2839 my $foundnew = 0;
2840 while (<PBCL>) {
[1381]2841 $foundnew = 1 if (/^$newvertxt \(/);
[479]2842 }
2843 close(PBCL);
[590]2844 open(OUT,"> $f2") || die "Unable to write to $f2: $!";
[479]2845 open(PBCL,$f) || die "Unable to open $f";
2846 while (<PBCL>) {
[1381]2847 print OUT "$_" if (not /^$oldvertxt \(/);
2848 if ((/^$oldvertxt \(/) && ($foundnew == 0)) {
2849 print OUT "$newvertxt ($pbdate)\n";
[479]2850 print OUT "- TBD\n";
2851 print OUT "\n";
[1381]2852 pb_log(0,"WARNING: version $newvertxt not found in $f so added to $f2...\n") if ($foundnew == 0);
[479]2853 }
2854 }
2855 close(OUT);
2856 close(PBCL);
2857 }
2858
[1381]2859 pb_log(2,"Checkin $ENV{'PBCONFDIR'}/$newver\n");
2860 pb_cms_checkin($scheme,"$ENV{'PBCONFDIR'}/$newver",undef);
[199]2861}
2862
[293]2863#
[1176]2864# Return the list of VMs/VEs/RMs we are working on
[105]2865# $all is a flag to know if we return all of them
2866# or only some (if all we publish also tar files in addition to pkgs
2867#
[772]2868sub pb_get2v {
[91]2869
[320]2870my $vtype = shift;
2871my @v;
[105]2872my $all = 0;
[320]2873my $pbv = 'PBV';
[1176]2874my $vlist = $vtype."list";
[91]2875
[320]2876# Get VM/VE list
2877if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
2878 my ($ptr) = pb_conf_get($vlist);
2879 $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
[105]2880 $all = 1;
[91]2881}
[320]2882pb_log(2,"$vtype: $ENV{$pbv}\n");
2883@v = split(/,/,$ENV{$pbv});
2884return(\@v,$all);
[91]2885}
2886
[1541]2887# This function creates a giant script to configure a particular VM/VE/RM, it then copies the
2888# script to the target.
2889
[1176]2890# Function to create a potentialy missing pb account on the VM/VE/RM, and adds it to sudo
2891# Needs to use root account to connect to the VM/VE/RM
[320]2892# pb will take your local public SSH key to access
[1176]2893# the pb account in the VM/VE/RM later on if needed
[772]2894sub pb_setup2v {
[320]2895
2896my $vtype = shift;
[1140]2897my $sbx = shift || undef;
[320]2898
[772]2899my ($vm,$all) = pb_get2v($vtype);
[353]2900
[346]2901# Script generated
2902my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
[320]2903
[1143]2904# Adapt // mode to memory size
2905$pbparallel = pb_set_parallel($vtype);
2906
[1176]2907my $pm;
2908if (defined $pbparallel) {
2909 $pm = new Parallel::ForkManager($pbparallel);
[1143]2910
[1176]2911 # Set which port the VM/RM will use to communicate
2912 $pm->run_on_start(\&pb_set_port);
2913}
[1143]2914
2915my $counter = 0;
[652]2916foreach my $v (@$vm) {
[1143]2917 $counter++;
2918 # Modulo pbparallel
[1176]2919 $counter = 1 if ((defined $pbparallel) && ($counter > $pbparallel));
[1143]2920 $pm->start($counter) and next if (defined $pbparallel);
2921
[891]2922 # Get distro context
[1177]2923 my $pbos = pb_distro_get_context($v);
[891]2924
[1216]2925 # Deal with date sync.
2926 my $ntpline = pb_date2v($vtype,$pbos);
2927
[1176]2928 # Name of the account to deal with for VM/VE/RM
[353]2929 # Do not use the one passed potentially with -a
2930 my ($pbac) = pb_conf_get($vtype."login");
[354]2931 my ($key,$zero0,$zero1,$zero2);
[639]2932 my ($vmexist,$vmpid);
[346]2933
[1176]2934 # Prepare the script to be executed on the VM/VE/RM
[681]2935 # in $ENV{'PBDESTDIR'}/setupv
2936 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
2937
2938 print SCRIPT << 'EOF';
2939#!/usr/bin/perl -w
2940
2941use strict;
2942use File::Copy;
2943
2944# We should not need in this script more functions than what is provided
[1140]2945# by Base, Conf and Distribution to avoid problems at exec time.
[681]2946# They are appended at the end.
2947
[1156]2948# Define mandatory global vars
[681]2949our $pbdebug;
2950our $pbLOG;
2951our $pbsynmsg = "pbscript";
2952our $pbdisplaytype = "text";
2953our $pblocale = "";
2954pb_log_init($pbdebug, $pbLOG);
[1425]2955EOF
2956 print SCRIPT << "EOF";
[1548]2957\$Global::pb_stop_on_error = $Global::pb_stop_on_error;
[1425]2958pb_temp_init($pbkeep);
[1511]2959pb_conf_init("$ENV{'PBPROJ'}");
[681]2960
2961EOF
2962
[1176]2963 # Launch the VM/VE/RM - Usage of snapshot disabled
[773]2964 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0,0,0);
[755]2965
[1156]2966 my $keyfile;
2967 my $nport;
2968 my $vmhost;
2969
[1255]2970 # Prepare the key to be used and transfered remotely
2971 $keyfile = pb_ssh_get(1);
2972
[1176]2973 if ($vtype =~ /(v|r)m/) {
[1215]2974 my ($vmport);
2975 ($vmhost,$vmport) = pb_conf_get($vtype."host",$vtype."port");
[1179]2976 $nport = pb_get_port($vmport,$pbos,$vtype);
[347]2977
[1176]2978 # Skip that VM/RM if something went wrong
[442]2979 next if (($vmpid == 0) && ($vmexist == 0));
[353]2980
[354]2981 # Store the pub key part in a variable
2982 open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
2983 ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
2984 close(FILE);
2985
2986 $key = "\Q$zero1";
2987
[1105]2988 # We call true to avoid problems if SELinux is not activated, but chcon is present and returns in that case 1
2989 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; /bin/true; fi\"","Copying local keys to $vtype. This may require the root password");
[1176]2990 # once this is done, we can do what we need on the VM/RM remotely
[681]2991 } elsif ($vtype eq "ve") {
[1029]2992 print SCRIPT << "EOF";
[940]2993# For VE we need a good null dev
2994pb_system("rm -f /dev/null; mknod /dev/null c 1 3; chmod 777 /dev/null");
[1541]2995
[681]2996# For VE we first need to mount some FS
2997pb_system("mount -t proc /proc /proc");
[346]2998
[354]2999EOF
[1541]3000 } else {
3001 die "Unknown virtual type $vtype";
[681]3002 }
[1029]3003
[1190]3004 if ($vtype =~ /(v|r)m/) {
[354]3005 print SCRIPT << 'EOF';
3006# Removes duplicate in .ssh/authorized_keys of our key if needed
3007#
3008my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
3009open(PBFILE,$file1) || die "Unable to open $file1";
3010open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
3011my $count = 0;
3012while (<PBFILE>) {
[517]3013
[354]3014EOF
3015 print SCRIPT << "EOF";
3016 if (/ $key /) {
3017 \$count++;
3018 }
3019print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
3020}
3021close(PBFILE);
3022close(PBOUT);
3023rename("\$file1.new",\$file1);
3024chmod 0600,\$file1;
[517]3025
[354]3026EOF
3027 }
3028 print SCRIPT << 'EOF';
3029
3030# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
3031#
[346]3032my $file="/etc/passwd";
[320]3033open(PBFILE,$file) || die "Unable to open $file";
3034my $found = 0;
3035while (<PBFILE>) {
[346]3036EOF
[353]3037 print SCRIPT << "EOF";
3038 \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
[346]3039EOF
[891]3040
[1176]3041# TODO: use an external parameter
[891]3042my $home = "/home";
3043# Solaris doesn't like that we use /home
[1177]3044$home = "/export/home" if ($pbos->{'type'} eq "pkg");
[891]3045
3046 print SCRIPT << "EOF";
[320]3047}
3048close(PBFILE);
3049
[891]3050if ( \$found == 0 ) {
3051 if ( ! -d "$home" ) {
3052 pb_mkdir_p("$home");
[320]3053 }
[346]3054EOF
[1179]3055 # TODO: Level of portability of these cmds ? Critical now for RM
[1255]3056 # TODO: Check existence before adding to avoid errors
[353]3057 print SCRIPT << "EOF";
[1051]3058pb_system("/usr/sbin/groupadd $pbac->{$ENV{'PBPROJ'}}","Adding group $pbac->{$ENV{'PBPROJ'}}");
3059pb_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'}})");
[427]3060}
[661]3061EOF
[320]3062
[1176]3063 # Copy the content of our local conf file to the VM/VE/RM
[891]3064 my $content = pb_get_content(pb_distro_conffile());
3065 print SCRIPT << "EOF";
3066 #
3067 # Create a temporary local conf file for distribution support
3068 # This is created here before its use later. Its place is hardcoded, so no choice for the path
3069 #
3070 my \$tempconf = pb_distro_conffile();
3071 pb_mkdir_p(dirname(\$tempconf));
3072 open(CONF,"> \$tempconf") || die "Unable to create \$tempconf";
3073 print CONF q{$content};
3074 close(CONF);
3075EOF
3076
[1176]3077 if ($vtype =~ /(v|r)m/) {
[661]3078 print SCRIPT << "EOF";
[354]3079# allow ssh entry to build
3080#
[891]3081mkdir "$home/$pbac->{$ENV{'PBPROJ'}}/.ssh",0700;
[347]3082# Allow those accessing root to access the build account
[891]3083copy("\$ENV{'HOME'}/.ssh/authorized_keys","$home/$pbac->{$ENV{'PBPROJ'}}/.ssh/authorized_keys");
[320]3084chmod 0600,".ssh/authorized_keys";
[891]3085pb_system("chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} $home/$pbac->{$ENV{'PBPROJ'}}","Finish setting up the account env for $pbac->{$ENV{'PBPROJ'}}");
[320]3086
[346]3087EOF
[661]3088}
[353]3089 print SCRIPT << 'EOF';
[347]3090# No passwd for build account only keys
[320]3091$file="/etc/shadow";
[684]3092if (-f $file) {
3093 open(PBFILE,$file) || die "Unable to open $file";
3094 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
3095 while (<PBFILE>) {
[346]3096EOF
[353]3097 print SCRIPT << "EOF";
[684]3098 s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
3099 s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
[910]3100 s/^$pbac->{$ENV{'PBPROJ'}}:\\*LK\\*:/$pbac->{$ENV{'PBPROJ'}}:NP:/; #Solaris e.g.
[346]3101EOF
[684]3102 print SCRIPT << 'EOF';
3103 print PBOUT $_;
3104 }
3105 close(PBFILE);
3106 close(PBOUT);
3107 rename("$file.new",$file);
3108 chmod 0640,$file;
3109 }
[320]3110
[448]3111# Keep the VM in text mode
3112$file="/etc/inittab";
[450]3113if (-f $file) {
3114 open(PBFILE,$file) || die "Unable to open $file";
3115 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
3116 while (<PBFILE>) {
3117 s/^(..):5:initdefault:$/$1:3:initdefault:/;
3118 print PBOUT $_;
3119 }
3120 close(PBFILE);
3121 close(PBOUT);
3122 rename("$file.new",$file);
3123 chmod 0640,$file;
[448]3124}
3125
[320]3126# pb has to be added to portage group on gentoo
3127
[1177]3128# We need to have that pb_distro_get_context function
[888]3129# Get it from Project-Builder::Distribution
[891]3130# And we now need the conf file required for this to work created above
[888]3131
[1177]3132my $pbos = pb_distro_get_context();
3133print "distro tuple: ".Dumper($pbos)."\n";
[891]3134
[346]3135# Adapt sudoers
[888]3136# sudo is not default on Solaris and needs to be installed first
3137# from http://www.sunfreeware.com/programlistsparc10.html#sudo
[1177]3138if ($pbos->{'type'} eq "pkg") {
[888]3139 $file="/usr/local/etc/sudoers";
3140} else {
3141 $file="/etc/sudoers";
3142}
[346]3143open(PBFILE,$file) || die "Unable to open $file";
3144open(PBOUT,"> $file.new") || die "Unable to open $file.new";
3145while (<PBFILE>) {
3146EOF
[1190]3147 # Skip what will be generated
[353]3148 print SCRIPT << "EOF";
[1190]3149 next if (/^$pbac->{$ENV{'PBPROJ'}}\\s+/);
3150 next if (/^Defaults:$pbac->{$ENV{'PBPROJ'}}\\s+/);
3151 next if (/^Defaults:root \!requiretty/);
[1541]3152 next if (/^Defaults:root env_keep/);
[346]3153EOF
[353]3154 print SCRIPT << 'EOF';
[346]3155 s/Defaults[ \t]+requiretty//;
3156 print PBOUT $_;
3157}
3158close(PBFILE);
3159EOF
[353]3160 print SCRIPT << "EOF";
[1032]3161# Some distro force requiretty at compile time, so disable here
3162print PBOUT "Defaults:$pbac->{$ENV{'PBPROJ'}} !requiretty\n";
[1035]3163print PBOUT "Defaults:root !requiretty\n";
[1179]3164# Keep proxy configuration while using sudo
[1198]3165print PBOUT "Defaults:$pbac->{$ENV{'PBPROJ'}} env_keep += \\\"http_proxy ftp_proxy\\\"\n";
[1541]3166print PBOUT "Defaults:root env_keep += \\\"http_proxy ftp_proxy\\\"\n";
[1179]3167EOF
3168 # Try to restrict security to what is really needed
3169 if ($vtype =~ /^vm/) {
[1197]3170 my $hpath = pb_distro_get_param($pbos,pb_conf_get("ospathcmd-halt"));
[1198]3171 my @sudocmds = pb_get_sudocmds($pbos,$ntpline,"sudo $hpath");
[1179]3172 print SCRIPT << "EOF";
3173# This is needed in order to be able on VM to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
3174# Build account $pbac->{$ENV{'PBPROJ'}} in VM also needs to setup date and install deps.
3175# Nothing else should be needed
3176EOF
[1189]3177 foreach my $c (@sudocmds) {
[1426]3178 print SCRIPT "print PBOUT \"$pbac->{$ENV{'PBPROJ'}} ALL = NOPASSWD: $c\\n\";\n";
[1179]3179 }
3180 } elsif ($vtype =~ /^rm/) {
[1190]3181 my @sudocmds = pb_get_sudocmds($pbos,$ntpline);
[1179]3182 print SCRIPT << "EOF";
3183# Build account $pbac->{$ENV{'PBPROJ'}} in RM only needs to setup date and install deps if needed each time
3184EOF
[1189]3185 foreach my $c (@sudocmds) {
[1426]3186 print SCRIPT "print PBOUT \"$pbac->{$ENV{'PBPROJ'}} ALL = NOPASSWD: $c\\n\";\n";
[1179]3187 }
3188 } else {
3189 print SCRIPT << "EOF";
3190# Build account $pbac->{$ENV{'PBPROJ'}} for VE needs to do a lot in the host (and chroot), so allow without restriction for now
[353]3191print PBOUT "$pbac->{$ENV{'PBPROJ'}} ALL=(ALL) NOPASSWD:ALL\n";
[346]3192EOF
[1179]3193}
[353]3194 print SCRIPT << 'EOF';
[346]3195close(PBOUT);
3196rename("$file.new",$file);
3197chmod 0440,$file;
3198
3199EOF
[891]3200
[1190]3201 if ($vtype =~ /(v|r)m/) {
3202 # Sync date
3203 # do it after sudoers is setup
3204 print SCRIPT "pb_system(\"$ntpline\");\n";
3205 }
[891]3206 # We may need a proxy configuration. Get it from the local env
3207
[1541]3208 # TODO: make this apply to the bootstrapping also.
3209 my ($ftp_proxy_map, $http_proxy_map) = pb_conf_get_if('ftp_proxy', 'http_proxy');
3210 my $ftp_proxy = pb_distro_get_param($pbos, $ftp_proxy_map);
3211 my $http_proxy = pb_distro_get_param($pbos, $http_proxy_map);
3212
[1542]3213 $ENV{'ftp_proxy'} = $ftp_proxy if ((defined $ftp_proxy) && ($ftp_proxy ne '') && (not defined $ENV{'ftp_proxy'}));
3214 $ENV{'http_proxy'} = $http_proxy if ((defined $http_proxy) && ($http_proxy ne '') && (not defined $ENV{'http_proxy'}));
[1541]3215
[891]3216 if (defined $ENV{'http_proxy'}) {
3217 print SCRIPT "\$ENV\{'http_proxy'\}=\"$ENV{'http_proxy'}\";\n";
3218 }
3219
3220 if (defined $ENV{'ftp_proxy'}) {
3221 print SCRIPT "\$ENV\{'ftp_proxy'\}=\"$ENV{'ftp_proxy'}\";\n";
3222 }
3223
3224 print SCRIPT << 'EOF';
[353]3225
[346]3226# Suse wants sudoers as 640
[1177]3227if ((($pbos->{'name'} eq "sles") && (($pbos->{'version'} =~ /10/) || ($pbos->{'version'} =~ /9/))) || (($pbos->{'name'} eq "opensuse") && ($pbos->{'version'} =~ /10.[012]/))) {
[346]3228 chmod 0640,$file;
3229}
3230
[1109]3231# First install all required packages
[1177]3232pb_system("yum clean all","Cleaning yum env") if (($pbos->{'name'} eq "fedora") || ($pbos->{'name'} eq "asianux") || ($pbos->{'name'} eq "rhel"));
[1109]3233my ($ospkgdep) = pb_conf_get_if("ospkgdep");
3234
[1177]3235my $pkgdep = pb_distro_get_param($pbos,$ospkgdep);
3236pb_distro_installdeps(undef,$pbos,pb_distro_only_deps_needed($pbos,join(' ',split(/,/,$pkgdep))));
[1109]3237
3238EOF
[1177]3239 my $itype = pb_distro_get_param($pbos,pb_conf_get("pbinstalltype"));
[1176]3240 # Install from sandbox mean a file base install
3241 $itype = "file" if (defined $sbx);
[1132]3242 if ($itype =~ /^file/) {
[1140]3243 my $cmdget;
3244 if (defined $sbx) {
3245 # Install from sandbox mean using the result of the just passed sbx2build command
3246 # Get content saved in cms2build
3247 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
[1432]3248 my $pbextdir = pb_get_extdir();
[1140]3249 die "Unable to get package list" if (not defined $pkg);
3250
3251 # We consider 2 specific packages
3252 my $vertag1 = $pkg->{"ProjectBuilder"};
3253 my $vertag2 = $pkg->{"project-builder"};
3254 # get the version of the current package - maybe different
[1459]3255 pb_log(2,"Vertag1: $vertag1\n");
3256 pb_log(2,"Vertag2: $vertag2\n");
[1140]3257 my ($pbver1,$tmp1) = split(/-/,$vertag1);
3258 my ($pbver2,$tmp2) = split(/-/,$vertag2);
[1156]3259 # Copy inside the VE
3260 if ($vtype eq "ve") {
3261 my ($vepath) = pb_conf_get("vepath");
[1432]3262 copy("$ENV{'PBDESTDIR'}/ProjectBuilder-$pbver1$pbextdir.tar.gz","$vepath->{$ENV{'PBPROJ'}}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/tmp");
3263 copy("$ENV{'PBDESTDIR'}/project-builder-$pbver2$pbextdir.tar.gz","$vepath->{$ENV{'PBPROJ'}}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/tmp");
[1156]3264 } else {
[1432]3265 pb_system("scp -i $keyfile -p -o UserKnownHostsFile=/dev/null -P $nport $ENV{'PBDESTDIR'}/ProjectBuilder-$pbver1$pbextdir.tar.gz $ENV{'PBDESTDIR'}/project-builder-$pbver2$pbextdir.tar.gz root\@$vmhost->{$ENV{'PBPROJ'}}:/tmp","Copying local project files to $vtype.");
[1156]3266 }
[1432]3267 $cmdget = "mv /tmp/ProjectBuilder-$pbver1$pbextdir.tar.gz ProjectBuilder-latest.tar.gz ; mv /tmp/project-builder-$pbver2$pbextdir.tar.gz project-builder-latest.tar.gz";
[1140]3268 } else {
3269 $cmdget = "wget --passive-ftp ftp://ftp.project-builder.org/src/ProjectBuilder-latest.tar.gz; wget --passive-ftp ftp://ftp.project-builder.org/src/project-builder-latest.tar.gz";
3270 }
[1109]3271 print SCRIPT << 'EOF';
3272# Then install manually the missing perl modules
3273my ($osperldep,$osperlver) = pb_conf_get_if("osperldep","osperlver");
3274
[1177]3275my $perldep = pb_distro_get_param($pbos,$osperldep);
[1109]3276foreach my $m (split(/,/,$perldep)) {
3277 # Skip empty deps
3278 next if ($m =~ /^\s*$/);
3279 my $dir = $m;
3280 $dir =~ s/-.*//;
3281 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}");
3282}
[1140]3283EOF
[1425]3284 print SCRIPT << 'EOF';
3285pb_system("rm -rf ProjectBuilder-* ; rm -rf project-builder-* ; rm -rf `perl -V:installvendorlib | awk -F\"'\" '{print \$2}'`/ProjectBuilder ;
[1109]3286EOF
[1425]3287 print SCRIPT " $cmdget ; ";
3288 print SCRIPT << 'EOF'
3289gzip -cd ProjectBuilder-latest.tar.gz | tar xf - ; cd ProjectBuilder-* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf ProjectBuilder-* ; 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");
3290EOF
[1132]3291 } elsif ($itype =~ /^pkg/) {
[1109]3292 # pkg based install. We need to point to the project-builder.org repository
3293 print SCRIPT << 'EOF';
[1177]3294my $pkgforpb = pb_distro_get_param($pbos,pb_conf_get_if("ospkg"));
3295pb_distro_setuposrepo($pbos);
3296pb_distro_installdeps(undef,$pbos,pb_distro_only_deps_needed($pbos,join(' ',split(/,/,$pkgforpb))));
[1109]3297EOF
3298 } else {
3299 # Unknown install type
3300 die("Unknown install type $itype->{$ENV{'PBPROJ'}} for param pbinstalltype");
3301 }
3302 print SCRIPT << 'EOF';
[902]3303pb_system("pb 2>&1 | head -5",undef,"verbose");
[1189]3304pb_system("pbdistrocheck",undef,"verbose");
[357]3305EOF
[681]3306 if ($vtype eq "ve") {
3307 print SCRIPT << 'EOF';
3308# For VE we need to umount some FS at the end
3309
3310pb_system("umount /proc");
[696]3311
3312# Create a basic network file if not already there
3313
3314my $nf="/etc/sysconfig/network";
[1177]3315if ((! -f $nf) && ($pbos->{'type'} eq "rpm")) {
[696]3316 open(NF,"> $nf") || die "Unable to create $nf";
3317 print NF "NETWORKING=yes\n";
3318 print NF "HOSTNAME=localhost\n";
3319 close(NF);
3320}
3321chmod 0755,$nf;
[681]3322EOF
3323 }
3324
[1177]3325 # Adds pb_distro_get_context and all functions needed from ProjectBuilder::Distribution, Conf and Base
[1545]3326 foreach my $m ("ProjectBuilder/Base.pm","ProjectBuilder/Distribution.pm","ProjectBuilder/Conf.pm") {
3327 foreach my $d (@INC) {
3328 my $f = "$d/$m";
[405]3329 if (-f "$f") {
[1545]3330 open(PBD,"$f") || die "Unable to open $f: $!";
[405]3331 while (<PBD>) {
[891]3332 next if (/^package/);
3333 next if (/^use Exporter/);
3334 next if (/^use ProjectBuilder::/);
3335 next if (/^our /);
[405]3336 print SCRIPT $_;
3337 }
3338 close(PBD);
[1545]3339 # We just need the first one of each file wrt @INC - hopefully that's the right one.
3340 last;
[353]3341 }
[347]3342 }
3343 }
[1156]3344 # Use a fake pb_version_init version here
3345 print SCRIPT << "EOF";
3346sub pb_version_init {
3347
3348return("$projectbuilderver","$projectbuilderrev");
3349}
33501;
3351EOF
[353]3352 close(SCRIPT);
3353 chmod 0755,"$pbscript";
3354
[442]3355 # That build script needs to be run as root and force stop of VM at end
[353]3356 $pbaccount = "root";
[442]3357
[1111]3358 # Force shutdown of VM except if it was already launched
[748]3359 my $pbforce = 0;
[442]3360 if ((! $vmexist) && ($vtype eq "vm")) {
[748]3361 $pbforce = 1;
[442]3362 }
3363
[748]3364 pb_script2v($pbscript,$vtype,$pbforce,$v);
[1143]3365 $pm->finish if (defined $pbparallel);
[347]3366}
[1176]3367$pm->wait_all_children if (defined $pbparallel);
[353]3368return;
[346]3369}
3370
[772]3371# Function to create a snapshot named 'pb' for VMs and a compressed tar for VEs
3372sub pb_snap2v {
[748]3373
3374my $vtype = shift;
3375
[772]3376my ($vm,$all) = pb_get2v($vtype);
[748]3377
3378# Script generated
3379my $pbscript = "$ENV{'PBDESTDIR'}/snapv";
3380
[898]3381my ($pbac) = pb_conf_get($vtype."login");
3382
[748]3383foreach my $v (@$vm) {
[1138]3384 if ($vtype eq "ve") {
3385 # Get distro context
[1177]3386 my $pbos = pb_distro_get_context($v);
[1138]3387 my ($vepath) = pb_conf_get("vepath");
[971]3388
[1138]3389 # Test if an existing snapshot exists and remove it if there is a VE
[1177]3390 if ((-f "$vepath->{$ENV{'PBPROJ'}}/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz") &&
3391 (! -d "$vepath->{$ENV{'PBPROJ'}}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}")) {
3392 pb_system("sudo rm -f $vepath->{$ENV{'PBPROJ'}}/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz","Removing previous snapshot $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz");
[1138]3393 }
[971]3394 }
3395
[748]3396 # Prepare the script to be executed on the VM/VE
3397 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
3398 print SCRIPT << 'EOF';
3399 #!/bin/bash
[776]3400 sleep 2
[748]3401EOF
3402 close(SCRIPT);
3403 chmod 0755,"$pbscript";
3404
3405 # Force shutdown of VM/VE
3406 # Force snapshot of VM/VE
[773]3407 pb_script2v($pbscript,$vtype,1,$v,1);
[748]3408}
3409return;
3410}
3411
[1176]3412# Function to update VMs/VEs/RMs with the latest distribution content
[1111]3413sub pb_update2v {
3414
3415my $vtype = shift;
3416
3417my ($vm,$all) = pb_get2v($vtype);
3418
3419# Script generated
3420my $pbscript = "$ENV{'PBDESTDIR'}/updatev";
3421
3422my ($pbac) = pb_conf_get($vtype."login");
3423
3424foreach my $v (@$vm) {
3425 # Get distro context
[1177]3426 my $pbos = pb_distro_get_context($v);
[1111]3427
[1176]3428 # Prepare the script to be executed on the VM/VE/RM
[1111]3429 # in $ENV{'PBDESTDIR'}/updatev
3430 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
3431
3432 print SCRIPT << 'EOF';
3433 #!/bin/bash
3434 sleep 2
3435EOF
3436 # VE needs a good /proc
3437 if ($vtype eq "ve") {
[1179]3438 print SCRIPT "sudo /bin/mount -t proc /proc /proc\n";
[1111]3439 }
[1177]3440 print SCRIPT "$pbos->{'update'}\n";
[1111]3441 if ($vtype eq "ve") {
[1179]3442 print SCRIPT "sudo /bin/umount /proc\n";
[1111]3443 }
3444 close(SCRIPT);
3445 chmod 0755,"$pbscript";
3446
3447 # Force shutdown of VM except
3448 pb_script2v($pbscript,$vtype,1,$v);
3449}
3450return;
3451}
3452
[471]3453sub pb_announce {
3454
[1386]3455 my $antype = shift;
3456
[473]3457 # Get all required parameters
[477]3458 my ($pbpackager,$pbrepo,$pbml,$pbsmtp) = pb_conf_get("pbpackager","pbrepo","pbml","pbsmtp");
[1392]3459 my ($pkgv, $pkgt, $testver) = pb_conf_get_if("pkgver","pkgtag","testver");
3460 if (((not defined $testver) || (not defined $testver->{$ENV{'PBPROJ'}}) || ($testver->{$ENV{'PBPROJ'}} !~ /true/i)) && ($antype eq "Clean")) {
3461 # We just clean for test versions
3462 pb_log(0,"Unable to clean SSH repository for non testver version\n");
3463 return;
3464 }
[471]3465 my $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
3466 my @pkgs = @$pkg;
3467 my %pkgs;
3468 my $first = 0;
3469
[1282]3470 # Get all distros concerned
3471 my $pbos = pb_distro_get_context();
3472 my $distrolist = pb_get_distros($pbos,undef);
3473 my %dl;
[1386]3474 my %theorlist;
3475 my %archlist;
[1282]3476 foreach my $d (split(/,/,$distrolist)) {
[1386]3477 my ($d1,$d2,$d3) = split(/-/,$d);
[1282]3478 $dl{$d1}++;
3479 }
3480
[473]3481 # Command to find packages on repo
[1282]3482 my $findstr = "find ".join(" ",keys %dl)." ";
[1392]3483 my $srcstr = "";
[473]3484 # Generated announce files
3485 my @files;
[471]3486
3487 foreach my $pbpkg (@pkgs) {
3488 if ($first != 0) {
3489 $findstr .= "-o ";
3490 }
3491 $first++;
3492 if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
3493 $pbver = $pkgv->{$pbpkg};
3494 } else {
3495 $pbver = $ENV{'PBPROJVER'};
3496 }
3497 if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
3498 $pbtag = $pkgt->{$pbpkg};
3499 } else {
3500 $pbtag = $ENV{'PBPROJTAG'};
3501 }
3502
[547]3503 # TODO: use virtual/real names here now
[1285]3504 my $pbrealpkg = $pbpkg;
3505 my $pbrealpkgrpm = pb_cms_get_real_pkg($pbpkg,"rpm");
3506 my $pbrealpkgdeb = pb_cms_get_real_pkg($pbpkg,"deb");
[1392]3507 if ($antype eq "Clean") {
[1432]3508 # We only clean test versions anyway
3509 $pbtag = "0";
3510 my $nver = $pbver;
3511 my $ntag = "[2-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]";
3512 $pbver .= $ntag;
3513 $findstr .= "-name \'$pbrealpkgrpm-$pbver-$pbtag\.*.rpm\' -o -name \'$pbrealpkgrpm-debug-$pbver-$pbtag\.*.rpm\' -o -name \'$pbrealpkgdeb"."_$pbver-$pbtag"."_*\.deb\' -o -name \'$pbrealpkgdeb"."_$pbver-$pbtag.dsc\' -o -name \'$pbrealpkgdeb"."_$pbver-$pbtag.tar.gz\' -o -name \'$pbrealpkg-$nver"."_p$ntag\.ebuild\' -o -name \'$pbrealpkg-$pbver-$pbtag*\.pkg\' -o -name \'$pbrealpkg-$pbver-$pbtag*\.sd\' ";
[1393]3514 $srcstr .= "src/$pbrealpkg-$pbver.tar.gz src/$pbrealpkg-$pbver.pbconf.tar.gz ";
[1392]3515 } else {
[1420]3516 my @date=pb_get_date();
3517 # the matching is only done on packages made the same day for test version. Hopefully this is enough
[1432]3518 my $nver = $pbver;
3519 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i) && ($antype eq "Check")) {
3520 $pbtag = "0";
3521 my $ntag .= strftime("%Y%m%d*", @date);
3522 $nver = $pbver."_p$ntag";
3523 $pbver .= $ntag;
3524 }
3525 $findstr .= "-name \'$pbrealpkgrpm-$pbver-$pbtag\.*.rpm\' -o -name \'$pbrealpkgdeb"."_$pbver*\.deb\' -o -name \'$pbrealpkg-$nver*\.ebuild\' -o -name \'$pbrealpkg-$pbver*\.pkg\' -o -name \'$pbrealpkg-$pbver*\.sd\' ";
[1392]3526 }
[473]3527
[1386]3528 if ($antype eq "Announce") {
3529 my $chglog;
[473]3530
[1386]3531 pb_cms_init($pbinit);
3532 # Get project info on log file and generate tmp files used later on
3533 $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
3534 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
3535 $chglog = undef if (! -f $chglog);
[473]3536
[1386]3537 open(OUT,"> $ENV{'PBTMP'}/$pbpkg.ann") || die "Unable to create $ENV{'PBTMP'}/$pbpkg.ann: $!";
3538 my $pb;
3539 $pb->{'realpkg'} = $pbrealpkg;
3540 $pb->{'ver'} = $pbver;
3541 $pb->{'tag'} = $pbtag;
3542 $pb->{'date'} = $pbdate;
[1432]3543 $pb->{'extdir'} = pb_get_extdir();
[1386]3544 $pb->{'chglog'} = $chglog;
3545 $pb->{'packager'} = $pbpackager;
3546 $pb->{'proj'} = $ENV{'PBPROJ'};
3547 $pb->{'repo'} = $pbrepo;
3548 $pb->{'pbos'}->{'type'} = "announce";
3549 $pb->{'pbos'}->{'suffix'} = "none";
3550 pb_changelog($pb,\*OUT,"yes");
3551 close(OUT);
3552 push(@files,"$ENV{'PBTMP'}/$pbpkg.ann");
[1392]3553 } elsif ($antype eq "Check") {
[1386]3554 # For the check we also build the theoritical complete list we should get
3555 foreach my $d (split(/,/,$distrolist)) {
3556 $pbos = pb_distro_get_context($d);
3557 if ($pbos->{'type'} eq "rpm") {
3558 $theorlist{"$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/$pbrealpkgrpm-$pbver-$pbtag$pbos->{'suffix'}"} = 0;
3559 } elsif ($pbos->{'type'} eq "deb") {
3560 $theorlist{"$pbos->{'name'}/$pbos->{'version'}/$pbrealpkgdeb"."_$pbver-$pbtag"} = 0;
[1420]3561 # TODO are we always using the last arch ?
[1386]3562 $archlist{"$pbos->{'name'}/$pbos->{'version'}/$pbrealpkgdeb"."_$pbver-$pbtag"} = "$pbos->{'arch'}";
3563 } elsif ($pbos->{'type'} eq "ebuild") {
[1424]3564 my $prefix = "-r";
3565 $prefix = "_p" if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i));
3566 $theorlist{"$pbos->{'name'}/$pbos->{'version'}/$pbrealpkg-$pbver$prefix$pbtag.ebuild"} = 0;
3567 $archlist{"$pbos->{'name'}/$pbos->{'version'}/$pbrealpkg-$pbver$prefix$pbtag.ebuild"} = "$pbos->{'arch'}";
[1386]3568 } elsif ($pbos->{'type'} eq "pkg") {
3569 $theorlist{"$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/$pbrealpkg-$pbver-$pbtag.pkg"} = 0;
3570 } else {
3571 pb_log(1,"No theoritical list possible for type $pbos->{'type'}\n");
3572 }
3573 }
3574 }
3575 pb_log(2,"theorlist : ".Dumper(%theorlist)."\n");
[471]3576 }
[1392]3577 if ($antype eq "Announce") {
3578 $findstr .= " | grep -Ev \'src.rpm\'";
3579 } elsif ($antype eq "Clean") {
3580 $findstr .= " | xargs rm -f -v $srcstr ";
3581 }
[471]3582
3583 # Prepare the command to run and execute it
3584 open(PBS,"> $ENV{'PBTMP'}/pbscript") || die "Unable to create $ENV{'PBTMP'}/pbscript";
[1392]3585 print PBS "#!/bin/bash\n";
[1282]3586 print PBS "set -x\n" if ($pbdebug gt 1);
[1295]3587 print PBS "$findstr | sort 2> /dev/null\n";
[471]3588 close(PBS);
3589 chmod 0755,"$ENV{'PBTMP'}/pbscript";
3590 pb_send2target("Announce");
3591
[490]3592 my $sl = "Project $ENV{'PBPROJ'} version $ENV{'PBPROJVER'} is now available";
[1386]3593 if ($antype eq "Announce") {
3594 # Get subject line
3595 pb_log(0,"Please enter the title of your announce\n");
3596 pb_log(0,"(By default: $sl)\n");
3597 my $sl2 = <STDIN>;
3598 $sl = $sl2 if ($sl2 !~ /^$/);
[490]3599
[1386]3600 # Prepare a template of announce
3601 open(ANN,"> $ENV{'PBTMP'}/announce.html") || die "Unable to create $ENV{'PBTMP'}/announce.html: $!";
3602 print ANN << "EOF";
[490]3603$sl</p>
[471]3604
[473]3605<p>The project team is happy to announce the availability of a newest version of $ENV{'PBPROJ'} $ENV{'PBPROJVER'}. Enjoy it as usual!</p>
[471]3606<p>
3607Now available at <a href="$pbrepo->{$ENV{'PBPROJ'}}">$pbrepo->{$ENV{'PBPROJ'}}</a>
3608</p>
3609<p>
3610EOF
[1386]3611 }
3612
[1137]3613 open(LOG,"$ENV{'PBTMP'}/system.$$.log") || die "Unable to read $ENV{'PBTMP'}/system.$$.log: $!";
[1386]3614 if ($antype eq "Announce") {
3615 my $col = 2;
3616 my $i = 1;
3617 print ANN << 'EOF';
[1440]3618<TABLE WIDTH="100%" CELLPADDING="0" CELLSPACING="0" BORDER="0">
[473]3619<TR>
3620EOF
[1386]3621 while (<LOG>) {
3622 print ANN "<TD><A HREF=\"$pbrepo->{$ENV{'PBPROJ'}}/$_\">$_</A></TD>";
3623 $i++;
3624 if ($i > $col) {
3625 print ANN "</TR>\n<TR>";
3626 $i = 1;
3627 }
[473]3628 }
[1393]3629 } elsif ($antype eq "Clean") {
3630 while (<LOG>) {
3631 # skip errors
3632 next if ($_ !~ /^removed /);
3633 pb_log(0,"$_");
3634 }
[1386]3635 } else {
3636 # In Check mode we need to compare the 2 lists (real and theoritical)
3637 while (<LOG>) {
3638 # Get package name and remove what is in extra for the theoritical list (arch at the end)
3639 chomp();
3640 # skip find errors
3641 next if (/^find:/);
3642 my $p = $_;
3643 $p =~ s/\.(i[3456]86|x86_64|noarch|src)\.rpm$//;
3644 $p =~ s/_(i[3456]86|amd64|all).deb$//;
[1424]3645 $p =~ s/(-0\.[0-9]{8})[0-9]{6}/$1*/ if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i));
3646 $p =~ s/(-r|_p[0-9]+)\.ebuild/$1*/ if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i));
[1386]3647 $theorlist{$p} = -2 if (not defined $theorlist{$p});
3648 $theorlist{$p} = $theorlist{$p} + 1;
3649 }
3650 pb_log(2,"theorlist : ".Dumper(%theorlist)."\n");
[471]3651 }
3652 close(LOG);
[1386]3653
[1393]3654 # Nothing more for the cleanssh case
3655 return if ($antype eq "Clean");
3656
[1386]3657 if ($antype eq "Check") {
3658 my ($chkex) = pb_conf_get_if("checkexclude");
3659 my $vmbuildlist = "";
3660 my $vebuildlist = "";
3661 my $rmbuildlist = "";
3662 my @pt = pb_conf_get_if("vmlist","velist","rmlist");
3663 foreach my $t (sort keys %theorlist) {
3664 if (defined $theorlist{$t} and $theorlist{$t} >= 1) {
3665 pb_log(1,"Packages found for $t\n");
3666 } elsif (defined $theorlist{$t} and $theorlist{$t} < 0) {
3667 pb_log(0,"Extra Package found for $t\n");
3668 } else {
[1420]3669 pb_log(2,"Analyzing $t\n");
[1386]3670 my ($os,$ver,$arch,$package) = split(/\//,$t);
3671 # Some distro have no arch subdir
3672 if (not defined $package) {
3673 $package = $arch;
3674 # TODO: If both arch have failed, we just make the last one
3675 $arch = $archlist{$t};
3676 }
3677 my $pbos = pb_distro_get_context("$os-$ver-$arch");
3678 my $pkgn = $package;
3679 if ($pbos->{'type'} ne "deb") {
3680 # package name is more easily found from the end for non deb
3681 # as '-' is the separator, but it can also be used in names
3682 $pkgn = reverse($package);
3683 # search the second '-' and isolate the now last part which is the full name
3684 $pkgn =~ s/([^-]+)-([^-]+)-([\S])+$/$3/;
3685 } else {
3686 $pkgn =~ s/([^_]+)_([\S])+$/$2/;
3687 }
3688 my $found = 0;
3689 # Handle the exclusion of OSes
3690 my $excl = "";
3691 $excl .= $chkex->{$pkgn} if (defined $chkex->{$pkgn});
3692 $excl .= $chkex->{"all"} if (defined $chkex->{"all"});
3693 foreach my $ex (split(/,/,$excl)) {
3694 $found = 1 if ("$os-$ver-$arch" =~ /^$ex/);
3695 }
3696 # Skip as excluded
3697 next if ($found == 1);
[1388]3698 pb_log(0,"Package NOT found for $t\n");
3699 # Avoid duplicates in list
[1386]3700 next if ($vmbuildlist =~ /$os-$ver-$arch/);
3701 next if ($vebuildlist =~ /$os-$ver-$arch/);
3702 next if ($rmbuildlist =~ /$os-$ver-$arch/);
3703 # check with which method we need to build
3704 if ((defined $pt[0]->{$ENV{'PBPROJ'}}) and ($pt[0]->{$ENV{'PBPROJ'}} =~ /$os-$ver-$arch/)) {
3705 $vmbuildlist = "$os-$ver-$arch" if ($vmbuildlist eq "");
[1388]3706 $vmbuildlist .= ",$os-$ver-$arch" if ($vmbuildlist !~ /$os-$ver-$arch/);
3707 next;
[1386]3708 }
3709 if ((defined $pt[1]->{$ENV{'PBPROJ'}}) and ($pt[1]->{$ENV{'PBPROJ'}} =~ /$os-$ver-$arch/)) {
3710 $vebuildlist = "$os-$ver-$arch" if ($vebuildlist eq "");
[1388]3711 $vebuildlist .= ",$os-$ver-$arch" if ($vebuildlist !~ /$os-$ver-$arch/);
3712 next;
[1386]3713 }
3714 if ((defined $pt[2]->{$ENV{'PBPROJ'}}) and ($pt[2]->{$ENV{'PBPROJ'}} =~ /$os-$ver-$arch/)) {
3715 $rmbuildlist = "$os-$ver-$arch" if ($rmbuildlist eq "");
[1388]3716 $rmbuildlist .= ",$os-$ver-$arch" if ($rmbuildlist !~ /$os-$ver-$arch/);
[1386]3717 }
3718 }
3719 }
3720 # If we want to rebuild automatically, let's do it
3721 if (defined $opts{'rebuild'}) {
3722 # SandBox or CMS
3723 pb_log(0,"Rebuilding from SandBox\n");
3724 pb_log(0,"for VMs: $vmbuildlist\n") if ($vmbuildlist ne "");
3725 pb_log(0,"for VEs: $vebuildlist\n") if ($vebuildlist ne "");
3726 pb_log(0,"for RMs: $rmbuildlist\n") if ($rmbuildlist ne "");
3727 pb_cms2build("SandBox");
3728 # Which mode
3729 $ENV{'PBV'} = $vmbuildlist;
3730 pb_build2v("vm","build") if ($vmbuildlist ne "");
3731 $ENV{'PBV'} = $vebuildlist;
3732 pb_build2v("ve","build") if ($vebuildlist ne "");
3733 $ENV{'PBV'} = $rmbuildlist;
3734 pb_build2v("rm","build") if ($rmbuildlist ne "");
3735 }
3736 # For the check part this is now finished
3737 return;
3738 }
3739
[473]3740 print ANN << "EOF";
3741</TR>
3742</TABLE>
3743</p>
[471]3744
[473]3745<p>As usual source packages are also available in the same directory.</p>
3746
3747<p>
3748Changes are :
3749</p>
3750<p>
3751EOF
3752 # Get each package changelog content
3753 foreach my $f (sort(@files)) {
3754 open(IN,"$f") || die "Unable to read $f:$!";
3755 while (<IN>) {
3756 print ANN $_;
3757 }
3758 close(IN);
3759 print ANN "</p><p>\n";
3760 }
3761 print ANN "</p>\n";
[471]3762 close(ANN);
[473]3763
3764 # Allow for modification
[974]3765 my $editor = "vi";
3766 $editor = $ENV{'EDITOR'} if (defined $ENV{'EDITOR'});
3767 pb_system("$editor $ENV{'PBTMP'}/announce.html","Allowing modification of the announce","noredir");
[473]3768
3769 # Store it in DB for external usage (Web pages generation)
3770 my $db = "$ENV{'PBCONFDIR'}/announces3.sql";
3771
3772 my $precmd = "";
3773 if (! -f $db) {
3774 $precmd = "CREATE TABLE announces (id INTEGER PRIMARY KEY AUTOINCREMENT, date DATE, announce VARCHAR[65535])";
3775 }
3776
3777 my $dbh = DBI->connect("dbi:SQLite:dbname=$db","","",
3778 { RaiseError => 1, AutoCommit => 1 })
3779 || die "Unable to connect to $db";
3780
3781 if ($precmd ne "") {
3782 my $sth = $dbh->prepare(qq{$precmd})
3783 || die "Unable to create table into $db";
3784 $sth->execute();
3785 }
3786
3787 # To read whole file
3788 local $/;
3789 open(ANN,"$ENV{'PBTMP'}/announce.html") || die "Unable to read $ENV{'PBTMP'}/announce.html: $!";
3790 my $announce = <ANN>;
3791 close(ANN);
3792
3793 pb_log(2,"INSERT INTO announces VALUES (NULL, $pbdate, $announce)");
3794 my $sth = $dbh->prepare(qq{INSERT INTO announces VALUES (NULL,?,?)})
3795 || die "Unable to insert into $db";
3796 $sth->execute($pbdate, $announce);
[698]3797 $sth->finish();
[473]3798 $dbh->disconnect;
3799
3800 # Then deliver it on the Web
3801 # $TOOLHOME/livwww www
3802
3803 # Mail it to project's ML
3804 open(ML,"| w3m -dump -T text/html > $ENV{'PBTMP'}/announce.txt") || die "Unable to create $ENV{'PBTMP'}/announce.txt: $!";
3805 print ML << 'EOF';
3806<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/x html1/DTD/xhtml1-strict.dtd">
3807
3808<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" xml:lang="en" lang="en">
3809 <head>
3810 </head>
3811 <body>
3812 <p>
3813EOF
3814 open(ANN,"$ENV{'PBTMP'}/announce.html") || die "Unable to read $ENV{'PBTMP'}/announce.html: $!";
3815 while(<ANN>) {
3816 print ML $_;
3817 }
3818 print ML << 'EOF';
3819</body>
3820</html>
3821EOF
3822 close(ML);
3823
[477]3824 # To read whole file
3825 local $/;
3826 open(ANN,"$ENV{'PBTMP'}/announce.txt") || die "Unable to read $ENV{'PBTMP'}/announce.txt: $!";
3827 my $msg = <ANN>;
3828 close(ANN);
3829
3830 # Preparation of headers
[1134]3831 eval
3832 {
3833 require Mail::Sendmail;
3834 Mail::Sendmail->import();
3835 };
3836 if ($@) {
3837 # Mail::Sendmail not found not sending mail !
3838 pb_log(0,"No Mail::Sendmail module found so not sending any mail !\n");
3839 } else {
3840 my %mail = (
[477]3841 To => $pbml->{$ENV{'PBPROJ'}},
3842 From => $pbpackager->{$ENV{'PBPROJ'}},
3843 Smtp => $pbsmtp->{$ENV{'PBPROJ'}},
3844 Body => $msg,
[490]3845 Subject => "[ANNOUNCE] $sl",
[477]3846 );
3847
[1134]3848 # Send mail
3849 if (! sendmail(%mail)) {
3850 if ((defined $Mail::Sendmail::error) and (defined $Mail::Sendmail::log)) {
3851 die "Unable to send mail ($Mail::Sendmail::error): $Mail::Sendmail::log";
3852 }
[1109]3853 }
3854 }
[471]3855}
3856
[547]3857#
3858# Creates a set of HTML file containing the news for the project
3859# based on what has been generated by the pb_announce function
3860#
3861sub pb_web_news2html {
3862
[556]3863 my $dest = shift || $ENV{'PBTMP'};
3864
[547]3865 # Get all required parameters
[1064]3866 my ($pkgv, $pkgt) = pb_conf_get_if("pkgver","pkgtag");
[547]3867
3868 # DB of announces for external usage (Web pages generation)
3869 my $db = "$ENV{'PBCONFDIR'}/announces3.sql";
3870
3871 my $dbh = DBI->connect("dbi:SQLite:dbname=$db","","",
3872 { RaiseError => 1, AutoCommit => 1 })
3873 || die "Unable to connect to $db";
3874 # For date handling
3875 $ENV{LANGUAGE}="C";
[559]3876 my $firstjan = strftime("%Y-%m-%d", 0, 0, 0, 1, 0, localtime->year(), 0, 0, -1);
3877 my $oldfirst = strftime("%Y-%m-%d", 0, 0, 0, 1, 0, localtime->year()-1, 0, 0, -1);
3878 pb_log(2,"firstjan: $firstjan, oldfirst: $oldfirst, pbdate:$pbdate\n");
[547]3879 my $all = $dbh->selectall_arrayref("SELECT id,date,announce FROM announces ORDER BY date DESC");
[556]3880 my %news;
3881 $news{"cy"} = ""; # current year's news
3882 $news{"ly"} = ""; # last year news
3883 $news{"py"} = ""; # previous years news
3884 $news{"fp"} = ""; # first page news
[547]3885 my $cpt = 4; # how many news for first page
3886 # Extract info from DB
3887 foreach my $row (@$all) {
3888 my ($id, $date, $announce) = @$row;
[559]3889 $news{"cy"} = $news{"cy"}."<p><B>$date</B> $announce\n" if ((($date cmp $pbdate) le 0) && (($firstjan cmp $date) le 0));
3890 $news{"ly"} = $news{"ly"}."<p><B>$date</B> $announce\n" if ((($date cmp $firstjan) le 0) && (($oldfirst cmp $date) le 0));
3891 $news{"py"} = $news{"py"}."<p><B>$date</B> $announce\n" if (($date cmp $oldfirst) le 0);
[556]3892 $news{"fp"} = $news{"fp"}."<p><B>$date</B> $announce\n" if ($cpt > 0);
[547]3893 $cpt--;
3894 }
[556]3895 pb_log(1,"news{fp}: ".$news{"fp"}."\n");
[547]3896 $dbh->disconnect;
[556]3897
3898 # Generate the HTML content
3899 foreach my $pref (keys %news) {
3900 open(NEWS,"> $dest/pb_web_$pref"."news.html") || die "Unable to create $dest/pb_web_$pref"."news.html: $!";
3901 print NEWS "$news{$pref}";
3902 close(NEWS);
3903 }
[547]3904}
3905
[556]3906
[347]3907# Return the SSH key file to use
3908# Potentially create it if needed
3909
3910sub pb_ssh_get {
3911
3912my $create = shift || 0; # Do not create keys by default
3913
[1545]3914my ($pbagent) = pb_conf_get_if("pbusesshagent");
3915# use ssh-agent if asked so.
3916return(undef) if (($create == 0) && (defined $pbagent->{$ENV{'PBPROJ'}}) && ($pbagent->{$ENV{'PBPROJ'}} =~ /true/io));
3917
[347]3918# Check the SSH environment
3919my $keyfile = undef;
3920
3921# We have specific keys by default
3922$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
[348]3923if (!(-e $keyfile) && ($create eq 1)) {
[347]3924 pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
3925}
3926
3927$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
3928$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
3929$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
[1545]3930die "Unable to find your public ssh key under $ENV{'HOME'}/.ssh" if (not defined $keyfile);
[347]3931return($keyfile);
3932}
3933
3934
[145]3935# Returns the pid of a running VM command using a specific VM file
[142]3936sub pb_check_ps {
3937 my $vmcmd = shift;
3938 my $vmm = shift;
3939 my $vmexist = 0; # FALSE by default
3940
3941 open(PS, "ps auxhww|") || die "Unable to call ps";
3942 while (<PS>) {
3943 next if (! /$vmcmd/);
3944 next if (! /$vmm/);
3945 my ($void1, $void2);
3946 ($void1, $vmexist, $void2) = split(/ +/);
3947 last;
3948 }
3949 return($vmexist);
3950}
3951
3952
[77]3953sub pb_extract_build_files {
[25]3954
3955my $src=shift;
3956my $dir=shift;
[26]3957my $ddir=shift;
[500]3958my $mandatory=shift || "spec";
[28]3959my @files;
[25]3960
[1219]3961my $flag = "mayfail" if (($mandatory eq "patch") || ($mandatory eq "src"));
[500]3962my $res;
3963
[188]3964if ($src =~ /tar\.gz$/) {
[500]3965 $res = pb_system("tar xfpz $src $dir","Extracting $mandatory files from $src",$flag);
[188]3966} elsif ($src =~ /tar\.bz2$/) {
[500]3967 $res = pb_system("tar xfpj $src $dir","Extracting $mandatory files from $src",$flag);
[188]3968} else {
3969 die "Unknown compression algorithm for $src";
3970}
[500]3971# If not mandatory return now
[1220]3972return() if (($res != 0) and (($mandatory eq "patch") || ($mandatory eq "src")));
[1486]3973opendir(DIR,"$dir") || die "Unable to open directory $dir: $!";
[25]3974foreach my $f (readdir(DIR)) {
3975 next if ($f =~ /^\./);
[500]3976 # Skip potential patch dir
3977 next if ($f =~ /^pbpatch/);
[1219]3978 # Skip potential source dir
3979 next if ($f =~ /^pbsrc/);
[1480]3980 # Skip potential backup files
3981 next if ($f =~ /~$/);
[26]3982 move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
[315]3983 pb_log(2,"mv $dir/$f $ddir\n");
[28]3984 push @files,"$ddir/$f";
[25]3985}
3986closedir(DIR);
[26]3987# Not enough but still a first cleanup
[74]3988pb_rm_rf("$dir");
[28]3989return(@files);
[25]3990}
3991
[315]3992sub pb_list_bfiles {
3993
3994my $dir = shift;
3995my $pbpkg = shift;
3996my $bfiles = shift;
3997my $pkgfiles = shift;
3998my $supfiles = shift;
[1363]3999# subdir to keep if recursive mode, empty by default
4000my $subdir = shift || "";
[1367]4001# In a recursive function , we need a local var as DIR handle
4002my $bdir;
[315]4003
[1363]4004pb_log(2,"DEBUG: entering pb_list_bfiles in $dir: ".Dumper($bfiles)."\n");
[1367]4005opendir($bdir,"$dir") || die "Unable to open dir $dir: $!";
4006foreach my $f (readdir($bdir)) {
[1363]4007 pb_log(3,"DEBUG: pb_list_bfiles found $f\n");
[315]4008 next if ($f =~ /^\./);
[1363]4009 if (-d "$dir/$f") {
[1098]4010 # Recurse for directories (Debian 3.0 format e.g.)
[1363]4011 pb_log(2,"DEBUG: pb_list_bfiles recurse in $dir/$f\n");
4012 pb_list_bfiles("$dir/$f",$pbpkg,$bfiles,$pkgfiles,$supfiles,$f);
[1098]4013 next;
4014 }
[1363]4015
4016 my $key = $f;
4017 # if recursive then store also the subdir
4018 $key = "$subdir/$f" if ($subdir ne "");
4019 $bfiles->{$key} = "$dir/$f";
4020 $bfiles->{$key} =~ s~$ENV{'PBROOTDIR'}~~;
[315]4021 if (defined $supfiles->{$pbpkg}) {
[1363]4022 $pkgfiles->{$key} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
[315]4023 }
4024}
[1367]4025closedir($bdir);
[1185]4026pb_log(2,"DEBUG: exiting pb_list_bfiles: ".Dumper($bfiles)."\n");
[315]4027}
4028
[1185]4029sub pb_add_coma {
4030
4031my $str = shift;
4032my $addstr = shift;
4033
4034$str .= "," if (defined $str);
4035$str .= $addstr;
4036return($str);
4037}
4038
[1130]4039sub pb_list_sfiles {
[395]4040
[1130]4041my $sdir = shift;
[1185]4042my $ptr = shift;
[1177]4043my $pbos = shift;
[1130]4044my $extdir = shift;
4045
[1185]4046pb_log(2,"DEBUG: entering pb_list_sfiles: ".Dumper($ptr)."\n");
4047my $key = "$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}";
4048
[1130]4049# Prepare local sources for this distro - They are always applied first - May be a problem one day
4050# This function works for both patches and additional sources
4051foreach my $p (sort(<$sdir/*>)) {
[1185]4052 $ptr->{$key} = pb_add_coma($ptr->{$key},"file://$p") if (($p =~ /\.all$/) || ($p =~ /\.$pbos->{'os'}$/) || ($p =~ /\.$pbos->{'type'}$/) || ($p =~ /\.$pbos->{'family'}$/) || ($p =~ /\.$pbos->{'name'}$/) || ($p =~ /\.$pbos->{'name'}-$pbos->{'version'}$/) ||($p =~ /\.$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}$/));
[1130]4053}
4054
4055# Prepare also remote sources to be included - Applied after the local ones
[1185]4056foreach my $p ("all","$pbos->{'os'}","$pbos->{'type'}","$pbos->{'family'}","$pbos->{'name'}","$pbos->{'name'}-$pbos->{'version'}","$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}") {
[1130]4057 my $f = "$extdir.".".$p";
4058 next if (not -f $f);
4059 if (not open(PATCH,$f)) {
4060 pb_display("Unable to open existing external source file content $f\n");
4061 next;
4062 }
4063 while (<PATCH>) {
4064 chomp();
[1185]4065 $ptr->{$key} = pb_add_coma($ptr->{$key},"$_");
[1130]4066 }
4067 close(PATCH);
4068}
[1185]4069pb_log(2,"DEBUG: exiting pb_list_sfiles: ".Dumper($ptr)."\n");
[1186]4070return($ptr);
[1130]4071}
4072
[395]4073#
4074# Return the list of packages we are working on in a non CMS action
4075#
4076sub pb_get_pkg {
4077
4078my @pkgs = ();
4079
4080my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
4081@pkgs = keys %$var;
4082
4083pb_log(0,"Packages: ".join(',',@pkgs)."\n");
4084return(\@pkgs);
4085}
4086
[1176]4087# Manages VM/RM SSH port communication
[1143]4088sub pb_get_port {
4089
4090my $port = shift;
[1179]4091my $pbos = shift;
[1143]4092my $cmt = shift;
[1179]4093my $nport;
[1143]4094
4095die "No port passed in parameter. Report to dev team\n" if (not defined $port);
[1179]4096# key is project on VM, but machine tuple for RM
4097if ($cmt =~ /^RM/i) {
4098 $nport = $port->{"$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}"};
4099} else {
4100 $nport = $port->{$ENV{'PBPROJ'}};
4101}
4102pb_log(2,"pb_get_port with $nport\n");
[1143]4103# Maybe a port was given as parameter so overwrite
4104$nport = "$pbport" if (defined $pbport);
[1268]4105# Maybe in // mode so use the env var set up as an offset to the base port, except when called from send2target for Packages or for RM
[1281]4106if (($cmt ne "Packages") && ($cmt !~ /^RM/i)) {
[1143]4107 $nport += $ENV{'PBVMPORT'} if ((defined $pbparallel) && (defined $ENV{'PBVMPORT'}));
4108}
[1146]4109pb_log(2,"pb_get_port returns $nport\n");
[1143]4110return($nport);
4111}
4112
4113sub pb_set_port {
4114
4115my ($pid,$ident) = @_;
[1146]4116pb_log(2,"pb_set_port for VM ($pid), id $ident\n");
[1143]4117$ENV{'PBVMPORT'} = $ident;
[1146]4118pb_log(2,"pb_set_port sets PBVMPORT in env to $ENV{'PBVMPORT'}\n");
[1143]4119}
4120
4121sub pb_set_parallel {
4122
4123my $vtype = shift;
4124
[1146]4125pb_log(2,"pb_set_parallel vtype: $vtype\n");
[1143]4126# Take care of memory size if VM, parallel mode and more than 1 action
4127if ((defined $pbparallel) && ($pbparallel ne 1) && ($vtype eq "vm")) {
4128 eval
4129 {
4130 require Linux::SysInfo;
4131 Linux::SysInfo->import();
4132 };
4133 if ($@) {
[1153]4134 # Linux::SysInfo not found
[1388]4135 pb_log(1,"ADVISE: Install Linux::SysInfo to benefit from automatic parallelism optimization.\nOr optimize manually pbparallel in your pb.conf file\nUsing $pbparallel processes max at a time for the moment\nWARNING: This may consume too much memory for your system\n");
[1143]4136 } else {
4137 # Using the memory size
4138 my $si = Linux::SysInfo::sysinfo();
4139 if (not defined $si) {
[1388]4140 pb_log(1,"ADVISE: Install Linux::SysInfo to benefit from automatic parallelism optimization.\nOr optimize manually pbparallel in your pb.conf file\nUsing $pbparallel processes max at a time for the moment\nWARNING: This may consume too much memory for your system\n");
[1143]4141 } else {
4142 # Keep the number of VM whose memory can be allocated
4143 my $ram = $si->{"totalram"}-$si->{"sharedram"}-$si->{"bufferram"};
4144 my $ram2;
[1153]4145 my ($vmmem) = pb_conf_get_if("vmmem");
[1146]4146
[1153]4147 my $v = "default";
4148 if ((defined $vmmem) and (defined $vmmem->{$v})) {
4149 $ram2 = $vmmem->{$v};
[1143]4150 } else {
4151 # Default for KVM/QEMU
4152 $ram2 = 128;
4153 }
4154 $pbparallel = sprintf("%d",$ram/$ram2);
4155 }
[1153]4156 pb_log(1,"Using $pbparallel processes at a time\n");
[1143]4157 }
4158}
[1176]4159pb_log(2,"pb_set_parallel returns: $pbparallel\n") if (defined $pbparallel);
[1143]4160return($pbparallel);
4161}
4162
[1179]4163sub pb_get_sudocmds {
4164
4165my $pbos = shift;
[1190]4166my %sudocmds;
[1143]4167
[1198]4168pb_log(2,"pb_get_sudocmds entering with lines:".Dumper(@_)."\n");
4169foreach my $c (split(/;/,$pbos->{'update'}),split(/;/,$pbos->{'install'}),@_) {
4170 pb_log(2,"pb_get_sudocmds analyses $c\n");
4171 next if ($c !~ /^\s*sudo/);
4172 # remove sudo and leading spaces
4173 $c =~ s/^\s*sudo\s+//;
[1192]4174 # keep only the command, not the params
4175 $c =~ s/([^\s]+)\s.*$/$1/;
[1190]4176 $sudocmds{$c} = "";
[1179]4177}
[1198]4178pb_log(2,"pb_get_sudocmds returns ".Dumper(keys %sudocmds)."\n");
[1190]4179return(keys %sudocmds);
[1179]4180}
4181
[1278]4182sub pb_sign_pkgs {
[1179]4183
[1278]4184my $pbos = shift;
4185my $made = shift;
4186
4187pb_log(2,"entering pb_sign_pkg: $made ".Dumper($pbos)."\n");
4188my ($passfile, $passphrase, $passpath) = pb_conf_get_if("pbpassfile","pbpassphrase","pbpasspath");
4189$ENV{'PBPASSPHRASE'} = $passphrase->{$ENV{'PBPROJ'}} if ((not defined $ENV{'PBPASSPHRASE'}) && (defined $passphrase->{$ENV{'PBPROJ'}}));
4190$ENV{'PBPASSFILE'} = $passfile->{$ENV{'PBPROJ'}} if ((not defined $ENV{'PBPASSFILE'})&& (defined $passfile->{$ENV{'PBPROJ'}})) ;
4191$ENV{'PBPASSPATH'} = $passpath->{$ENV{'PBPROJ'}} if ((not defined $ENV{'PBPASSPATH'})&& (defined $passpath->{$ENV{'PBPROJ'}})) ;
4192
[1279]4193# Remove extra spaces
4194$made =~ s/\s+/ /g;
4195$made =~ s/^\s//g;
4196$made =~ s/\s$//g;
4197
[1278]4198if ($pbos->{'type'} eq "rpm") {
4199 eval
4200 {
4201 require RPM4::Sign;
4202 RPM4::Sign->import();
4203 };
4204 if ($@) {
4205 # RPM4::Sign not found
4206 pb_log(1,"WARNING: Install RPM4::Sign to benefit from automatic package signing.\n");
4207 } else {
4208 return if ((not defined $ENV{'PBPASSPHRASE'}) and (not defined $ENV{'PBPASSFILE'}));
4209 my $sign = RPM4::Sign->new(
4210 passphrase => $ENV{'PBPASSPHRASE'},
4211 name => $ENV{'PBPACKAGER'},
4212 path => $ENV{'PBPASSPATH'},
4213 password_file => $ENV{'PBPASSFILE'},
4214 );
4215
4216 pb_log(0,"Signing RPM packages...\n");
4217 pb_log(2,"pb_sign_pkg: pkgs:".Dumper(split(/ /,$made))."\n");
4218 $sign->rpmssign(split(/ /,$made));
4219 }
4220} elsif ($pbos->{'type'} eq "deb") {
[1279]4221 my $changes = "";
4222 foreach my $c (split(/ /,$made)) {
[1537]4223 $changes .= " $ENV{'PBBUILDDIR'}/$c" if (($c =~ /\.changes$/) && (-f "$ENV{PBBUILDDIR}/$c"));
[1279]4224 }
[1386]4225 my $debsigncmd = pb_check_req("debsign",1);
[1545]4226 pb_system("$debsigncmd -m\'$ENV{'PBPACKAGER'}\' $changes","Signing DEB packages",undef,1) if ($changes ne "");
[1278]4227} else {
4228 pb_log(0,"I don't know yet how to sign packages for type $pbos->{'type'}.\nPlease give feedback to dev team\n");
[1279]4229}
[1278]4230pb_log(2,"exiting pb_sign_pkg\n");
4231}
4232
[1282]4233# return list of all distributins supported, coma separated
4234sub pb_get_distros {
4235
4236my $pbos = shift;
4237my $pbtarget = shift;
4238
4239my $tmpl = "$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'},";
4240
4241# Get list of distributions for which we need to generate build files if no target
[1402]4242if (not defined $pbtarget) {
[1282]4243 my @pt = pb_conf_get_if("vmlist","velist","rmlist");
4244 if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
4245 $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
4246 }
4247 if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
[1386]4248 # The 2 lists need to be grouped with a ',' separating them
[1282]4249 if ($tmpl ne "") {
4250 $tmpl .= ",";
4251 }
4252 $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
4253 }
4254 if (defined $pt[2]->{$ENV{'PBPROJ'}}) {
4255 # The lists needs to be grouped with a ',' separating them
4256 if ($tmpl ne "") {
4257 $tmpl .= ",";
4258 }
4259 $tmpl .= $pt[2]->{$ENV{'PBPROJ'}}
4260 }
4261}
4262return($tmpl);
4263}
4264
[1432]4265sub pb_get_extdir () {
4266
4267 # the pbrc file should contain it and whatever the key, we take it
4268 my ($ed) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbextdir");
4269 pb_log(2,"ed: ".Dumper($ed)."\n");
4270 my $pbextdir = "";
4271 foreach my $k (keys %$ed) {
4272 $pbextdir = $ed->{$k};
[1459]4273 # In case we have an empty field, empty it completely
4274 pb_log(2,"pbextdir: ***$pbextdir***\n");
4275 $pbextdir =~ s/^\s*$//;
[1432]4276 }
[1459]4277 pb_log(2,"pbextdir: ***$pbextdir***\n");
[1432]4278 return($pbextdir);
4279}
4280
[395]42811;
Note: See TracBrowser for help on using the repository browser.