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

Last change on this file since 739 was 739, checked in by Bruno Cornec, 15 years ago

Adds clean feature

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