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

Last change on this file since 549 was 549, checked in by Bruno Cornec, 16 years ago

Solve a display issue on patches

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