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

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