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

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