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

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

Still improving debian handling. Final delivery and $made still not completely correct

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