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

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