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

Last change on this file since 1117 was 1117, checked in by Bruno Cornec, 13 years ago

r4058@localhost: bruno | 2010-11-26 11:42:34 +0100

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