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

Last change on this file since 395 was 395, checked in by Bruno Cornec, 16 years ago
  • Move all reusable functions into Base
  • Move all pb only functions into pb
  • pod doc for Base begining
  • Property svn:executable set to *
File size: 98.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 Pod::Usage;
15use Data::Dumper;
16use English;
17use File::Basename;
18use File::Copy;
19use File::Path;
20use File::stat;
21use File::Temp qw(tempdir);
22use Date::Manip;
23use Time::localtime qw(localtime);
24use POSIX qw(strftime);
25
26
27# Global variables
28use lib qw (lib);
29use ProjectBuilder::Distribution;
30use ProjectBuilder::Version;
31use ProjectBuilder::Base;
32
33my %opts; # CLI Options
34my $action; # action to realize
35my $test = "FALSE"; # Not used
36my $force = 0; # Force VE/VM rebuild
37my $option = ""; # Not used
38my @pkgs; # list of packages
39my $pbtag; # Global Tag variable
40my $pbver; # Global Version variable
41my $pbscript; # Name of the script
42my %pbver; # per package
43my %pbtag; # per package
44my $pbrev; # Global REVISION variable
45my $pbaccount; # Login to use to connect to the VM
46my $pbport; # Port to use to connect to the VM
47my $newver; # New version to create
48my $iso; # ISO image for the VM to create
49
50my @date = pb_get_date();
51my $pbdate = strftime("%Y-%m-%d", @date);
52
53=pod
54
55=head1 NAME
56
57pb, aka project-builder.org - builds packages for your projects
58
59=head1 DESCRIPTION
60
61pb helps you build various packages directly from your project sources.
62Those sources could be handled by a CMS (Configuration Management System)
63such as Subversion, CVS, ... or being a simple reference to a compressed tar file.
64It's based on a set of configuration files, a set of provided macros to help
65you keeping build files as generic as possible. For example, a single .spec
66file should be required to generate for all rpm based distributions, even
67if you could also have multiple .spec files if required.
68
69=head1 SYNOPSIS
70
71pb [-vhq][-r pbroot][-p project][[-s script -a account -P port][-m mach-1[,...]]][-i iso] <action> [<pkg1> ...]
72
73pb [--verbose][--help][--man][--quiet][--revision pbroot][--project project][[--script script --account account --port port][--machine mach-1[,...]]][--iso iso] <action> [<pkg1> ...]
74
75=head1 OPTIONS
76
77=over 4
78
79=item B<-v|--verbose>
80
81Print a brief help message and exits.
82
83=item B<-q|--quiet>
84
85Do not print any output.
86
87=item B<-h|--help>
88
89Print a brief help message and exits.
90
91=item B<--man>
92
93Prints the manual page and exits.
94
95=item B<-m|--machine machine1[,machine2,...]>
96
97Name of the Virtual Machines (VM) or Virtual Environments (VE) you want to build on (coma separated).
98All if none precised (or use the env variable PBV).
99
100=item B<-s|--script script>
101
102Name of the script you want to execute on the related VMs or VEs.
103
104=item B<-i|--iso iso_image>
105
106Name of the ISO image of the distribution you want to install on the related VMs.
107
108=item B<-a|--account account>
109
110Name of the account to use to connect on the related VMs.
111
112=item B<-P|--port port_number>
113
114Port number to use to connect on the related VMs.\n";
115
116=item B<-p|--project project_name>
117
118Name of the project you're working on (or use the env variable PBPROJ)
119
120=item B<-r|--revision revision>
121
122Path Name of the project revision under the CMS (or use the env variable PBROOT)
123
124=item B<-V|--version new_version>
125
126New version of the project to create based on the current one.
127
128=back
129
130=head1 ARGUMENTS
131
132<action> can be:
133
134=over 4
135
136=item B<cms2build>
137
138Create tar files for the project under your CMS.
139CMS supported are SVN and CVS
140parameters are packages to build
141if not using default list
142
143=item B<build2pkg>
144
145Create packages for your running distribution
146
147=item B<cms2pkg>
148
149cms2build + build2pkg
150
151=item B<build2ssh>
152
153Send the tar files to a SSH host
154
155=item B<cms2ssh>
156
157cms2build + build2ssh
158
159=item B<pkg2ssh>
160
161Send the packages built to a SSH host
162
163=item B<build2vm>
164
165Create packages in VMs, launching them if needed
166and send those packages to a SSH host once built
167VM type supported are QEMU
168
169=item B<build2ve>
170
171Create packages in VEs, creating it if needed
172and send those packages to a SSH host once built
173
174=item B<cms2vm>
175
176cms2build + build2vm
177
178=item B<cms2ve>
179
180cms2build + build2ve
181
182=item B<launchvm>
183
184Launch one virtual machine
185
186=item B<launchve>
187
188Launch one virtual environment
189
190=item B<script2vm>
191
192Launch one virtual machine if needed
193and executes a script on it
194
195=item B<script2ve>
196
197Execute a script in a virtual environment
198
199=item B<newvm>
200
201Create a new virtual machine
202
203=item B<newve>
204
205Create a new virtual environment
206
207=item B<setupvm>
208
209Setup a virtual machine for pb usage
210
211=item B<setupve>
212
213Setup a virtual environment for pb usage
214
215=item B<newver>
216
217Create a new version of the project derived
218from the current one
219
220=item B<newproj>
221
222Create a new project and a template set of
223configuration files under pbconf
224
225=back
226
227<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).
228
229=head1 WEB SITES
230
231The 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/>.
232
233=head1 USER MAILING LIST
234
235None exists for the moment.
236
237=head1 CONFIGURATION FILES
238
239Each pb user may have a configuration in F<$HOME/.pbrc>. The values in this file may overwrite any other configuration file value.
240
241Here is an example of such a configuration file:
242
243 #
244 # Define for each project the URL of its pbconf repository
245 # No default option allowed here as they need to be all different
246 #
247 # URL of the pbconf content
248 # This is the format of a classical URL with the extension of additional schema such as
249 # svn+ssh, cvs+ssh, ...
250 #
251 pbconfurl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe/pbconf
252
253 # This is normaly defined in the project's configuration file
254 # Url of the project
255 #
256 pburl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe
257
258 # All these URLs needs to be defined here as the are the entry point
259 # for how to build packages for the project
260 #
261 pbconfurl pb = svn+ssh://svn.project-builder.org/mondo/svn/pb/pbconf
262 pbconfurl mondorescue = svn+ssh://svn.project-builder.org/mondo/svn/project-builder/mondorescue/pbconf
263 pbconfurl collectl = svn+ssh://bruno@svn.mondorescue.org/mondo/svn/project-builder/collectl/pbconf
264 pbconfurl netperf = svn+ssh://svn.mondorescue.org/mondo/svn/project-builder/netperf/pbconf
265
266 # Under that dir will take place everything related to pb
267 # If you want to use VMs/chroot/..., then use $ENV{'HOME'} to make it portable
268 # to your VMs/chroot/...
269 # if not defined then /var/cache
270 pbdefdir default = $ENV{'HOME'}/project-builder
271 pbdefdir pb = $ENV{'HOME'}
272 pbdefdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
273 pbdefdir mondorescue = $ENV{'HOME'}/mondo/svn
274
275 # pbconfdir points to the directory where the CMS content of the pbconfurl is checked out
276 # If not defined, pbconfdir is under pbdefdir/pbproj/pbconf
277 pbconfdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs/pbconf
278 pbconfdir mondorescue = $ENV{'HOME'}/mondo/svn/pbconf
279
280 # pbdir points to the directory where the CMS content of the pburl is checked out
281 # If not defined, pbdir is under pbdefdir/pbproj
282 # Only defined if we have access to the dev of the project
283 pbdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
284 pbdir mondorescue = $ENV{'HOME'}/mondo/svn
285
286 # -daemonize doesn't work with qemu 0.8.2
287 vmopt default = -m 384
288
289=head1 AUTHORS
290
291The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
292
293=head1 COPYRIGHT
294
295Project-Builder.org is distributed under the GPL v2.0 license
296described in the file C<COPYING> included with the distribution.
297
298=cut
299
300# ---------------------------------------------------------------------------
301
302# Old syntax
303#getopts('a:fhi:l:m:P:p:qr:s:vV:',\%opts);
304
305my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
306
307GetOptions("help|?|h" => \$opts{'h'},
308 "man" => \$opts{'man'},
309 "verbose|v+" => \$opts{'v'},
310 "quiet|q" => \$opts{'q'},
311 "log-files|l=s" => \$opts{'l'},
312 "force|f" => \$opts{'f'},
313 "account|a=s" => \$opts{'a'},
314 "revision|r=s" => \$opts{'r'},
315 "script|s=s" => \$opts{'s'},
316 "machines|mock|m=s" => \$opts{'m'},
317 "port|P=i" => \$opts{'P'},
318 "project|p=s" => \$opts{'p'},
319 "iso|i=s" => \$opts{'i'},
320 "version|V=s" => \$opts{'V'},
321) || pb_syntax(-1,0);
322
323if (defined $opts{'h'}) {
324 pb_syntax(0,1);
325}
326if (defined $opts{'man'}) {
327 pb_syntax(0,2);
328}
329if (defined $opts{'v'}) {
330 $debug = $opts{'v'};
331 pb_log(0,"Debug value: $debug\n");
332}
333if (defined $opts{'f'}) {
334 $force=1;
335}
336if (defined $opts{'q'}) {
337 $debug=-1;
338}
339if (defined $opts{'l'}) {
340 open(LOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
341 $LOG = \*LOG;
342 $debug = 0 if ($debug == -1);
343 }
344pb_log_init($debug, $LOG);
345
346# Handle root of the project if defined
347if (defined $opts{'r'}) {
348 $ENV{'PBROOTDIR'} = $opts{'r'};
349}
350# Handle virtual machines if any
351if (defined $opts{'m'}) {
352 $ENV{'PBV'} = $opts{'m'};
353}
354if (defined $opts{'s'}) {
355 $pbscript = $opts{'s'};
356}
357if (defined $opts{'a'}) {
358 $pbaccount = $opts{'a'};
359 die "option -a requires a -s script option" if (not defined $pbscript);
360}
361if (defined $opts{'P'}) {
362 $pbport = $opts{'P'};
363}
364if (defined $opts{'V'}) {
365 $newver = $opts{'V'};
366}
367if (defined $opts{'i'}) {
368 $iso = $opts{'i'};
369}
370
371# Get Action
372$action = shift @ARGV;
373die pb_syntax(-1,1) if (not defined $action);
374
375my ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir);
376my $pbinit = undef;
377$pbinit = 1 if ($action =~ /^newproj$/);
378
379# Handles project name if any
380# And get global params
381($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) = pb_env_init($opts{'p'},$pbinit,$action);
382
383pb_log(0,"Project: $ENV{'PBPROJ'}\n");
384pb_log(0,"Action: $action\n");
385
386# Act depending on action
387if ($action =~ /^cms2build$/) {
388 pb_cms2build();
389} elsif ($action =~ /^build2pkg$/) {
390 pb_build2pkg();
391} elsif ($action =~ /^cms2pkg$/) {
392 pb_cms2build();
393 pb_build2pkg();
394} elsif ($action =~ /^build2ssh$/) {
395 pb_build2ssh();
396} elsif ($action =~ /^cms2ssh$/) {
397 pb_cms2build();
398 pb_build2ssh();
399} elsif ($action =~ /^pkg2ssh$/) {
400 pb_pkg2ssh();
401} elsif ($action =~ /^build2ve$/) {
402 pb_build2v("ve");
403} elsif ($action =~ /^build2vm$/) {
404 pb_build2v("vm");
405} elsif ($action =~ /^cms2ve$/) {
406 pb_cms2build();
407 pb_build2v("ve");
408} elsif ($action =~ /^cms2vm$/) {
409 pb_cms2build();
410 pb_build2v("vm");
411} elsif ($action =~ /^launchvm$/) {
412 pb_launchv("vm",$ENV{'PBV'},0);
413} elsif ($action =~ /^launchve$/) {
414 pb_launchv("ve",$ENV{'PBV'},0);
415} elsif ($action =~ /^script2vm$/) {
416 pb_script2v($pbscript,"vm");
417} elsif ($action =~ /^script2ve$/) {
418 pb_script2v($pbscript,"ve");
419} elsif ($action =~ /^newver$/) {
420 pb_newver();
421} elsif ($action =~ /^newve$/) {
422 pb_launchv("ve",$ENV{'PBV'},1);
423} elsif ($action =~ /^newvm$/) {
424 pb_launchv("vm",$ENV{'PBV'},1);
425} elsif ($action =~ /^setupve$/) {
426 pb_setup_v("ve");
427} elsif ($action =~ /^setupvm$/) {
428 pb_setup_v("vm");
429} elsif ($action =~ /^newproj$/) {
430 # Nothing to do - already done in pb_env_init
431} elsif ($action =~ /^clean$/) {
432} else {
433 pb_log(0,"\'$action\' is not available\n");
434 pb_syntax(-2,1);
435}
436
437sub pb_cms2build {
438
439 my $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
440 my @pkgs = @$pkg;
441 my %pkgs;
442
443 my ($scheme, $uri) = pb_cms_init($pbinit);
444
445 my ($pkgv, $pkgt) = pb_conf_get_if("pkgver","pkgtag");
446
447 # declare packager for filtering
448 my ($tmp) = pb_conf_get("pbpackager");
449 $ENV{'PBPACKAGER'} = $tmp->{$ENV{'PBPROJ'}};
450
451 foreach my $pbpkg (@pkgs) {
452 $ENV{'PBPKG'} = $pbpkg;
453 if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
454 $pbver = $pkgv->{$pbpkg};
455 } else {
456 $pbver = $ENV{'PBPROJVER'};
457 }
458 if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
459 $pbtag = $pkgt->{$pbpkg};
460 } else {
461 $pbtag = $ENV{'PBPROJTAG'};
462 }
463
464 $pbrev = $ENV{'PBREVISION'};
465 pb_log(0,"\n");
466 pb_log(0,"Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n");
467 die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
468 # Clean up dest if necessary. The export will recreate it
469 my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver";
470 pb_rm_rf($dest) if (-d $dest);
471
472 # Export CMS tree for the concerned package to dest
473 # And generate some additional files
474 $OUTPUT_AUTOFLUSH=1;
475
476 # computes in which dir we have to work
477 my $dir = $defpkgdir->{$pbpkg};
478 $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
479 pb_log(2,"def:".Dumper($defpkgdir)." ext: ".Dumper($extpkgdir)." \n");
480
481 # Exporting from CMS
482 pb_cms_export($uri,"$ENV{'PBDIR'}/$dir",$dest);
483
484 # Get project info on authors and log file
485 my $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
486 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
487 $chglog = undef if (! -f $chglog);
488
489 my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
490 $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
491 $authors = "/dev/null" if (! -f $authors);
492
493 # Extract cms log history and store it
494 if ((defined $chglog) && (! -f "$dest/NEWS")) {
495 pb_log(2,"Generating NEWS file from $chglog\n");
496 copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
497 }
498 pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors);
499
500 my %build;
501
502 my @pt;
503 @pt = pb_conf_get_if("vmlist","velist");
504 my $tmpl = "";
505 if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
506 $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
507 }
508 if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
509 # the 2 lists needs to be grouped with a ',' separated them
510 if ($tmpl ne "") {
511 $tmpl .= ",";
512 }
513 $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
514 }
515 foreach my $d (split(/,/,$tmpl)) {
516 my ($name,$ver,$arch) = split(/-/,$d);
517 chomp($arch);
518 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
519 pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n");
520 pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
521
522 # Filter build files from the less precise up to the most with overloading
523 # Filter all files found, keeping the name, and generating in dest
524
525 # Find all build files first relatively to PBROOTDIR
526 # Find also all specific files referenced in the .pb conf file
527 my %bfiles = ();
528 my %pkgfiles = ();
529 $build{"$ddir-$dver"} = "yes";
530
531 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dtype") {
532 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dtype",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
533 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dfam") {
534 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
535 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir") {
536 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
537 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver") {
538 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
539 } else {
540 $build{"$ddir-$dver"} = "no";
541 next;
542 }
543 pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
544
545 # Get all filters to apply
546 my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
547
548 # Apply now all the filters on all the files concerned
549 # destination dir depends on the type of file
550 if (defined $ptr) {
551 foreach my $f (values %bfiles,values %pkgfiles) {
552 pb_filter_file_pb("$ENV{'PBROOTDIR'}/$f",$ptr,"$dest/pbconf/$ddir-$dver/".basename($f),$dtype,$pbsuf,$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$defpkgdir,$extpkgdir,$ENV{'PBPACKAGER'},$chglog);
553 }
554 }
555 }
556 my @found;
557 my @notfound;
558 foreach my $b (keys %build) {
559 push @found,$b if ($build{$b} =~ /yes/);
560 push @notfound,$b if ($build{$b} =~ /no/);
561 }
562 pb_log(0,"Build files generated for ".join(',',@found)."\n");
563 pb_log(0,"No Build files found for ".join(',',@notfound)."\n") if (@notfound);
564 # Get the generic filter (all.pbf) and
565 # apply those to the non-build files including those
566 # generated by pbinit if applicable
567
568 # Get only all.pbf filter
569 my $ptr = pb_get_filters($pbpkg);
570
571 my $liste ="";
572 if (defined $filteredfiles->{$pbpkg}) {
573 foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
574 pb_filter_file_inplace($ptr,"$dest/$f",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'});
575 $liste = "$f $liste";
576 }
577 }
578 pb_log(2,"Files ".$liste."have been filtered\n");
579
580 # Prepare the dest directory for archive
581 if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
582 pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'});
583 chmod 0755,"$ENV{'PBTMP'}/pbinit";
584 pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit");
585 }
586
587 # Archive dest dir
588 chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
589 # Possibility to look at PBSRC to guess more the filename
590 pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
591 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
592
593 # Keep track of version-tag per pkg
594 $pkgs{$pbpkg} = "$pbver-$pbtag";
595
596 # Final cleanup
597 pb_rm_rf($dest) if (-d $dest);
598 }
599
600 # Keep track of per package version
601 pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
602 open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
603 foreach my $pbpkg (@pkgs) {
604 print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
605 }
606 close(PKG);
607
608 # Keep track of what is generated by default
609 # We need to store the dir and info on version-tag
610 # Base our content on the existing .pb file
611 copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
612 open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
613 print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
614 print LAST "pbprojver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
615 print LAST "pbprojtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
616 print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
617 close(LAST);
618}
619
620sub pb_build2pkg {
621
622 # Get the running distro to build on
623 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
624 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
625
626 # Get list of packages to build
627 # Get content saved in cms2build
628 my $ptr = pb_get_pkg();
629 @pkgs = @$ptr;
630
631 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
632 $pkg = { } if (not defined $pkg);
633
634 chdir "$ENV{'PBBUILDDIR'}";
635 my $made = ""; # pkgs made during build
636 foreach my $pbpkg (@pkgs) {
637 my $vertag = $pkg->{$pbpkg};
638 # get the version of the current package - maybe different
639 ($pbver,$pbtag) = split(/-/,$vertag);
640
641 my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
642 pb_log(2,"Source file: $src\n");
643
644 pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
645 if ($dtype eq "rpm") {
646 foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
647 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
648 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";
649 }
650 }
651
652 # Remove in case a previous link/file was there
653 unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
654 symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
655 # We need to first extract the spec file
656 my @specfile;
657 @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
658
659 pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
660 # set LANGUAGE to check for correct log messages
661 $ENV{'LANGUAGE'}="C";
662 foreach my $f (@specfile) {
663 if ($f =~ /\.spec$/) {
664 pb_system("rpmbuild --define \'packager $ENV{'PBPACKAGER'}\' --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
665 last;
666 }
667 }
668 $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
669 if (-f "/usr/bin/rpmlint") {
670 pb_system("rpmlint $made","Checking validity of rpms with rpmlint");
671 }
672 } elsif ($dtype eq "deb") {
673 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
674 pb_system("tar xfz $src","Extracting sources");
675
676 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
677 pb_rm_rf("debian");
678 symlink "pbconf/$ddir-$dver","debian" || die "Unable to symlink to pbconf/$ddir-$dver";
679 chmod 0755,"debian/rules";
680 pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package");
681 $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
682 if (-f "/usr/bin/lintian") {
683 pb_system("lintian $made","Checking validity of debs with lintian");
684 }
685 } elsif ($dtype eq "ebuild") {
686 my @ebuildfile;
687 # For gentoo we need to take pb as subsystem name
688 # We put every apps here under sys-apps. hope it's correct
689 # We use pb's home dir in order o have a single OVERLAY line
690 my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
691 pb_mkdir_p($tmpd) if (! -d "$tmpd");
692 pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
693
694 # We need to first extract the ebuild file
695 @ebuildfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$tmpd");
696
697 # Prepare the build env for gentoo
698 my $found = 0;
699 my $pbbd = $ENV{'HOME'};
700 $pbbd =~ s|/|\\/|g;
701 if (-r "/etc/make.conf") {
702 open(MAKE,"/etc/make.conf");
703 while (<MAKE>) {
704 $found = 1 if (/$pbbd\/portage/);
705 }
706 close(MAKE);
707 }
708 if ($found == 0) {
709 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
710 }
711 #$found = 0;
712 #if (-r "/etc/portage/package.keywords") {
713 #open(KEYW,"/etc/portage/package.keywords");
714 #while (<KEYW>) {
715 #$found = 1 if (/portage\/pb/);
716 #}
717 #close(KEYW);
718 #}
719 #if ($found == 0) {
720 #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
721 #}
722
723 # Build
724 foreach my $f (@ebuildfile) {
725 if ($f =~ /\.ebuild$/) {
726 move($f,"$tmpd/$pbpkg-$pbver.ebuild");
727 pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package");
728 # Now move it where pb expects it
729 pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
730 move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
731 }
732 }
733
734 $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver.ebuild";
735 } elsif ($dtype eq "slackware") {
736 $made="$made build-$pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
737 pb_mkdir_p("$ENV{'PBBUILDDIR'}/install") if (! -d "$ENV{'PBBUILDDIR'}/install");
738 } else {
739 die "Unknown dtype format $dtype";
740 }
741 }
742 # Keep track of what is generated so that we can get them back from VMs
743 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
744 print KEEP "$made\n";
745 close(KEEP);
746}
747
748sub pb_build2ssh {
749 pb_send2target("Sources");
750}
751
752sub pb_pkg2ssh {
753 pb_send2target("Packages");
754}
755
756# By default deliver to the the public site hosting the
757# ftp structure (or whatever) or a VM/VE
758sub pb_send2target {
759
760 my $cmt = shift;
761 my $v = shift || undef;
762 my $vmexist = shift || 0; # 0 is FALSE
763 my $vmpid = shift || 0; # 0 is FALSE
764
765 my $host = "sshhost";
766 my $login = "sshlogin";
767 my $dir = "sshdir";
768 my $port = "sshport";
769 my $tmout = "sshtmout";
770 my $path = "sshpath";
771 my $conf = "sshconf";
772 my $rebuild = "sshrebuild";
773 if (($cmt eq "vm") || ($cmt eq "Script")) {
774 $login = "vmlogin";
775 $dir = "pbdefdir";
776 $tmout = "vmtmout";
777 $rebuild = "vmrebuild";
778 # Specific VM
779 $host = "vmhost";
780 $port = "vmport";
781 } elsif ($cmt eq "ve") {
782 $login = "velogin";
783 $dir = "pbdefdir";
784 $tmout = "vetmout";
785 # Specific VE
786 $path = "vepath";
787 $conf = "veconf";
788 $rebuild = "verebuild";
789 }
790 my $cmd = "";
791
792 my $ptr = pb_get_pkg();
793 @pkgs = @$ptr;
794
795 # Get the running distro to consider
796 my ($odir,$over,$oarch) = (undef, undef, undef);
797 if (defined $v) {
798 ($odir,$over,$oarch) = split(/-/,$v);
799 }
800 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
801 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
802
803 # Get list of packages to build
804 # Get content saved in cms2build
805 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
806 $pkg = { } if (not defined $pkg);
807
808 my $src = "";
809 chdir "$ENV{'PBBUILDDIR'}";
810 foreach my $pbpkg (@pkgs) {
811 my $vertag = $pkg->{$pbpkg};
812 # get the version of the current package - maybe different
813 ($pbver,$pbtag) = split(/-/,$vertag);
814
815 if (($cmt eq "Sources") || ($cmt eq "vm") || ($cmt eq "ve")) {
816 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
817 if ($cmd eq "") {
818 $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
819 } else {
820 $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
821 }
822 }
823 }
824 if (($cmt eq "vm") || ($cmt eq "ve")) {
825 $src="$src $ENV{'PBDESTDIR'}/pbscript $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc";
826 } elsif ($cmt eq "Script") {
827 $src="$src $ENV{'PBDESTDIR'}/pbscript";
828 } elsif ($cmt eq "Packages") {
829 # Get package list from file made during build2pkg
830 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
831 $src = <KEEP>;
832 chomp($src);
833 close(KEEP);
834 if ($dtype eq "rpm") {
835 # Also make a pbscript to generate yum/urpmi bases
836 # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
837 } elsif ($dtype eq "deb") {
838 # Also make a pbscript to generate apt bases
839 # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
840 }
841 }
842 # Remove potential leading spaces (cause problem with basename)
843 $src =~ s/^ *//;
844 my $basesrc = "";
845 foreach my $i (split(/ +/,$src)) {
846 $basesrc .= " ".basename($i);
847 }
848
849 pb_log(0,"Sources handled ($cmt): $src\n");
850 pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf))."\n");
851 my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf) = pb_conf_get($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf);
852 pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
853 # Not mandatory
854 my ($testver) = pb_conf_get_if("testver");
855
856 my $mac;
857 # Useless for VE
858 if ($cmt ne "ve") {
859 $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
860 # Overwrite account value if passed as parameter
861 $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
862 pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
863 }
864
865 my $tdir;
866 my $bdir;
867 if (($cmt eq "Sources") || ($cmt eq "Script")) {
868 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
869 } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
870 $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
871 $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
872 # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
873 $bdir =~ s|\$ENV.+\}/||;
874 } elsif ($cmt eq "Packages") {
875 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
876 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
877 # This is a test pkg => target dir is under test
878 $tdir .= "/test";
879 }
880 } else {
881 return;
882 }
883
884 # Useless for VE
885 my $nport;
886 if ($cmt ne "ve") {
887 $nport = $sshport->{$ENV{'PBPROJ'}};
888 $nport = "$pbport" if (defined $pbport);
889 }
890
891 # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
892 $tdir =~ s|\$ENV.+\}/||;
893
894 my $tm = $vtmout->{$ENV{'PBPROJ'}};
895
896 # ssh communication if not VE
897 # should use a hash instead...
898 my ($shcmd,$cpcmd,$cptarget,$cp2target);
899 if ($cmt ne "ve") {
900 my $keyfile = pb_ssh_get(0);
901 $shcmd = "ssh -i $keyfile -q -p $nport $mac";
902 $cpcmd = "scp -i $keyfile -p -P $nport";
903 $cptarget = "$mac:$tdir";
904 if ($cmt eq "vm") {
905 $cp2target = "$mac:$bdir";
906 }
907 } else {
908 my $tp = $vepath->{$ENV{'PBPROJ'}};
909 $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
910 $cpcmd = "cp -a ";
911 $cptarget = "$tp/$tdir";
912 $cp2target = "$tp/$bdir";
913 }
914
915 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");
916 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
917 # For VE we need to change the owner manually - To be tested if needed
918 #if ($cmt eq "ve") {
919 #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
920 #}
921 pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi\' | bash\"","Executing pbscript on $cptarget if needed");
922 if (($cmt eq "vm") || ($cmt eq "ve")) {
923 # Get back info on pkg produced, compute their name and get them from the VM
924 pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
925 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
926 my $src = <KEEP>;
927 chomp($src);
928 close(KEEP);
929 $src =~ s/^ *//;
930 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
931 # Change pgben to make the next send2target happy
932 my $made = "";
933 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
934 foreach my $p (split(/ +/,$src)) {
935 my $j = basename($p);
936 pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
937 $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
938 }
939 print KEEP "$made\n";
940 close(KEEP);
941 pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
942
943 # We want to send them to the ssh account so overwrite what has been done before
944 undef $pbaccount;
945 pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
946 pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
947 if ((! $vmexist) && ($cmt eq "vm")) {
948 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)");
949 }
950 pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
951 }
952}
953
954sub pb_script2v {
955 my $pbscript=shift;
956 my $vtype=shift;
957
958 # Prepare the script to be executed on the VM
959 # in $ENV{'PBDESTDIR'}/pbscript
960 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
961 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
962 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
963 }
964
965 my ($vm,$all) = pb_get_v($vtype);
966 my ($vmexist,$vmpid) = (undef,undef);
967
968 foreach my $v (@$vm) {
969 # Launch the VM/VE
970 if ($vtype eq "vm") {
971 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
972
973 # Skip that VM if something went wrong
974 next if (($vmpid == 0) && ($vmexist ==0));
975 }
976
977 # Gather all required files to send them to the VM
978 # and launch the build through pbscript
979 pb_send2target("Script","$v",$vmexist,$vmpid);
980
981 }
982}
983
984sub pb_launchv {
985 my $vtype = shift;
986 my $v = shift;
987 my $create = shift || 0; # By default do not create a VM
988
989 die "No VM/VE defined, unable to launch" if (not defined $v);
990 # Keep only the first VM in case many were given
991 $v =~ s/,.*//;
992
993 # Which is our local arch ? (standardize on i386 for those platforms)
994 my $arch = `uname -m`;
995 chomp($arch);
996 $arch =~ s/i.86/i386/;
997
998 # Launch the VMs/VEs
999 if ($vtype eq "vm") {
1000 die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
1001
1002 my ($ptr,$vmopt,$vmport,$vmpath,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmport","vmpath","vmtmout","vmsize");
1003
1004 my $vmtype = $ptr->{$ENV{'PBPROJ'}};
1005 if (not defined $ENV{'PBVMOPT'}) {
1006 $ENV{'PBVMOPT'} = "";
1007 }
1008 if (defined $vmopt->{$ENV{'PBPROJ'}}) {
1009 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
1010 }
1011 my $nport = $vmport->{$ENV{'PBPROJ'}};
1012 $nport = "$pbport" if (defined $pbport);
1013
1014 my $cmd;
1015 my $vmcmd; # has to be used for pb_check_ps
1016 my $vmm; # has to be used for pb_check_ps
1017 if ($vmtype eq "qemu") {
1018 my $qemucmd32;
1019 my $qemucmd64;
1020 if ($arch eq "x86_64") {
1021 $qemucmd32 = "/usr/bin/qemu-system-i386";
1022 $qemucmd64 = "/usr/bin/qemu";
1023 } else {
1024 $qemucmd32 = "/usr/bin/qemu";
1025 $qemucmd64 = "/usr/bin/qemu-system-x86_64";
1026 }
1027 if ($v =~ /x86_64/) {
1028 $vmcmd = "$qemucmd64 -no-kqemu";
1029 } else {
1030 $vmcmd = "$qemucmd32";
1031 }
1032 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
1033 if ($create != 0) {
1034 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
1035 }
1036 $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
1037 } elsif ($vmtype eq "xen") {
1038 } elsif ($vmtype eq "vmware") {
1039 } else {
1040 die "VM of type $vmtype not supported. Report to the dev team";
1041 }
1042 my ($tmpcmd,$void) = split(/ +/,$cmd);
1043 my $vmexist = pb_check_ps($tmpcmd,$vmm);
1044 my $vmpid = 0;
1045 if (! $vmexist) {
1046 if ($create != 0) {
1047 if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
1048 pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
1049 } elsif ($vmtype eq "vmware") {
1050 } else {
1051 }
1052 }
1053 if (! -f "$vmm") {
1054 pb_log(0,"Unable to find VM $vmm\n");
1055 } else {
1056 pb_system("$cmd &","Launching the VM $vmm");
1057 pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
1058 $vmpid = pb_check_ps($tmpcmd,$vmm);
1059 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
1060 }
1061 } else {
1062 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
1063 }
1064 return($vmexist,$vmpid);
1065 # VE here
1066 } else {
1067 # Get VE context
1068 my ($ptr,$vepath,$vetmout,$verebuild,$veconf) = pb_conf_get("vetype","vepath","vetmout","verebuild","veconf");
1069 my $vetype = $ptr->{$ENV{'PBPROJ'}};
1070
1071 # Get distro context
1072 my ($name,$ver,$darch) = split(/-/,$v);
1073 chomp($darch);
1074 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
1075
1076 if ($vetype eq "chroot") {
1077 # Architecture consistency
1078 if ($arch ne $darch) {
1079 die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
1080 }
1081
1082 if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
1083 # We have to rebuild the chroot
1084 if ($dtype eq "rpm") {
1085 pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1086 # Once setup we need to install some packages, the pb account, ...
1087 pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
1088 #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1089 } elsif ($dtype eq "deb") {
1090 pb_system("","Creating the pbuilder VE");
1091 } elsif ($dtype eq "ebuild") {
1092 die "Please teach the dev team how to build gentoo chroot";
1093 } else {
1094 die "Unknown distribution type $dtype. Report to dev team";
1095 }
1096 }
1097 # Nothing more to do for VE. No real launch
1098 } else {
1099 die "VE of type $vetype not supported. Report to the dev team";
1100 }
1101 }
1102}
1103
1104sub pb_build2v {
1105
1106my $vtype = shift;
1107
1108# Prepare the script to be executed on the VM/VE
1109# in $ENV{'PBDESTDIR'}/pbscript
1110#my ($ntp) = pb_conf_get($vtype."ntp");
1111#my $vntp = $ntp->{$ENV{'PBPROJ'}};
1112
1113open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1114print SCRIPT "#!/bin/bash\n";
1115print SCRIPT "echo ... Execution needed\n";
1116print SCRIPT "# This is in directory delivery\n";
1117print SCRIPT "# Setup the variables required for building\n";
1118print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
1119print SCRIPT "# Preparation for pb\n";
1120print SCRIPT "mv .pbrc \$HOME\n";
1121print SCRIPT "cd ..\n";
1122# Force new date to be in the future compared to the date of the tar file by adding 1 minute
1123my @date=pb_get_date();
1124$date[1]++;
1125my $upddate = strftime("%m%d%H%M%Y", @date);
1126#print SCRIPT "echo Setting up date on $vntp...\n";
1127# Or use ntpdate if available TBC
1128print SCRIPT "sudo date $upddate\n";
1129# Get list of packages to build and get some ENV vars as well
1130my $ptr = pb_get_pkg();
1131@pkgs = @$ptr;
1132my $p = join(' ',@pkgs) if (@pkgs);
1133print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
1134print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
1135print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
1136print SCRIPT "# Build\n";
1137print SCRIPT "echo Building packages on $vtype...\n";
1138print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
1139close(SCRIPT);
1140chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1141
1142my ($v,$all) = pb_get_v($vtype);
1143
1144# Send tar files when we do a global generation
1145pb_build2ssh() if ($all == 1);
1146
1147my ($vmexist,$vmpid) = (undef,undef);
1148
1149foreach my $v (@$v) {
1150 if ($vtype eq "vm") {
1151 # Launch the VM
1152 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1153
1154 # Skip that VM if it something went wrong
1155 next if (($vmpid == 0) && ($vmexist == 0));
1156 }
1157 # Gather all required files to send them to the VM/VE
1158 # and launch the build through pbscript
1159 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
1160 pb_send2target($vtype,"$v",$vmexist,$vmpid);
1161}
1162}
1163
1164
1165sub pb_newver {
1166
1167 die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
1168
1169 # Need this call for PBDIR
1170 my ($scheme2,$uri) = pb_cms_init($pbinit);
1171
1172 my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
1173 $uri = $pbconf->{$ENV{'PBPROJ'}};
1174 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1175
1176 # Checking CMS repositories status
1177 my ($pburl) = pb_conf_get("pburl");
1178 ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
1179
1180 if ($scheme !~ /^svn/) {
1181 die "Only SVN is supported at the moment";
1182 }
1183 my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
1184 die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
1185
1186 $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
1187 die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
1188
1189 # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
1190 # we want to get for the root of the new URL
1191
1192 my $tmp = $ENV{'PBROOTDIR'};
1193 $tmp =~ s|^$ENV{'PBCONFDIR'}||;
1194
1195 my $newurl = "$uri/".dirname($tmp)."/$newver";
1196 # Should probably use projver in the old file
1197 my $oldver= basename($tmp);
1198
1199 # Checking pbcl files
1200 foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
1201 open(PBCL,$f) || die "Unable to open $f";
1202 my $foundnew = 0;
1203 while (<PBCL>) {
1204 $foundnew = 1 if (/^$newver \(/);
1205 }
1206 close(PBCL);
1207 die "ERROR: version $newver not found in $f" if ($foundnew == 0);
1208 }
1209
1210 # Duplicate and extract project-builder part
1211 pb_log(2,"Copying $uri/$tmp to $newurl\n");
1212 pb_cms_copy($scheme,"$uri/$tmp",$newurl);
1213 pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
1214 pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
1215
1216 # Duplicate and extract project
1217 my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
1218
1219 pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
1220 pb_cms_copy($scheme,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
1221 pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
1222 pb_cms_up($scheme,"$ENV{'PBDIR'}/..");
1223
1224 # Update the .pb file
1225 open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
1226 open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
1227 while(<FILE>) {
1228 s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
1229 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/);
1230 s/^testver/#testver/;
1231 pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
1232 print OUT $_;
1233 }
1234 close(FILE);
1235 close(OUT);
1236 rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
1237
1238 pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
1239 pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver");
1240}
1241
1242#
1243# Return the list of VMs/VEs we are working on
1244# $all is a flag to know if we return all of them
1245# or only some (if all we publish also tar files in addition to pkgs
1246#
1247sub pb_get_v {
1248
1249my $vtype = shift;
1250my @v;
1251my $all = 0;
1252my $vlist;
1253my $pbv = 'PBV';
1254
1255if ($vtype eq "vm") {
1256 $vlist = "vmlist";
1257} elsif ($vtype eq "ve") {
1258 $vlist = "velist";
1259}
1260# Get VM/VE list
1261if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
1262 my ($ptr) = pb_conf_get($vlist);
1263 $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
1264 $all = 1;
1265}
1266pb_log(2,"$vtype: $ENV{$pbv}\n");
1267@v = split(/,/,$ENV{$pbv});
1268return(\@v,$all);
1269}
1270
1271# Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
1272# Needs to use root account to connect to the VM/VE
1273# pb will take your local public SSH key to access
1274# the pb account in the VM later on if needed
1275sub pb_setup_v {
1276
1277my $vtype = shift;
1278
1279my ($vm,$all) = pb_get_v($vtype);
1280
1281# Script generated
1282my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
1283
1284foreach my $v (@$vm) {
1285 # Name of the account to deal with for VM/VE
1286 # Do not use the one passed potentially with -a
1287 my ($pbac) = pb_conf_get($vtype."login");
1288 my ($key,$zero0,$zero1,$zero2);
1289 my ($vmexist,$vmpid);
1290
1291 if ($vtype eq "vm") {
1292 # Prepare the key to be used and transfered remotely
1293 my $keyfile = pb_ssh_get(1);
1294
1295 my ($vmhost,$vmport) = pb_conf_get("vmhost","vmport");
1296 my $nport = $vmport->{$ENV{'PBPROJ'}};
1297 $nport = "$pbport" if (defined $pbport);
1298
1299 # Launch the VM
1300 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1301
1302 # Skip that VM if something went wrong
1303 return if (($vmpid == 0) && ($vmexist == 0));
1304
1305 # Store the pub key part in a variable
1306 open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
1307 ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
1308 close(FILE);
1309
1310 $key = "\Q$zero1";
1311
1312 pb_system("cat $keyfile.pub | ssh -q -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 will require the root password");
1313 # once this is done, we can do what we want on the VM remotely
1314 }
1315
1316 # Prepare the script to be executed on the VM/VE
1317 # in $ENV{'PBDESTDIR'}/setupv
1318
1319 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
1320 print SCRIPT << 'EOF';
1321#!/usr/bin/perl -w
1322
1323use strict;
1324use File::Copy;
1325
1326EOF
1327 if ($vtype eq "vm") {
1328 print SCRIPT << 'EOF';
1329# Removes duplicate in .ssh/authorized_keys of our key if needed
1330#
1331my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
1332open(PBFILE,$file1) || die "Unable to open $file1";
1333open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
1334my $count = 0;
1335while (<PBFILE>) {
1336EOF
1337 print SCRIPT << "EOF";
1338 if (/ $key /) {
1339 \$count++;
1340 }
1341print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
1342}
1343close(PBFILE);
1344close(PBOUT);
1345rename("\$file1.new",\$file1);
1346chmod 0600,\$file1;
1347EOF
1348 }
1349 print SCRIPT << 'EOF';
1350
1351# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
1352#
1353my $file="/etc/passwd";
1354open(PBFILE,$file) || die "Unable to open $file";
1355my $found = 0;
1356while (<PBFILE>) {
1357EOF
1358 print SCRIPT << "EOF";
1359 \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
1360EOF
1361 print SCRIPT << 'EOF';
1362}
1363close(PBFILE);
1364
1365if ( $found == 0 ) {
1366 if ( ! -d "/home" ) {
1367 mkdir "/home";
1368 }
1369EOF
1370 print SCRIPT << "EOF";
1371system "groupadd $pbac->{$ENV{'PBPROJ'}}";
1372system "useradd $pbac->{$ENV{'PBPROJ'}} -g $pbac->{$ENV{'PBPROJ'}} -m -d /home/$pbac->{$ENV{'PBPROJ'}}";
1373
1374# allow ssh entry to build
1375#
1376chdir "/home/$pbac->{$ENV{'PBPROJ'}}";
1377mkdir ".ssh",0700;
1378# Allow those accessing root to access the build account
1379copy("\$ENV{'HOME'}/.ssh/authorized_keys",".ssh/authorized_keys");
1380chmod 0600,".ssh/authorized_keys";
1381system 'chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} .ssh';
1382
1383EOF
1384 print SCRIPT << 'EOF';
1385}
1386
1387# No passwd for build account only keys
1388$file="/etc/shadow";
1389open(PBFILE,$file) || die "Unable to open $file";
1390open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1391while (<PBFILE>) {
1392EOF
1393 print SCRIPT << "EOF";
1394 s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
1395 s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
1396EOF
1397 print SCRIPT << 'EOF';
1398 print PBOUT $_;
1399}
1400close(PBFILE);
1401close(PBOUT);
1402rename("$file.new",$file);
1403chmod 0640,$file;
1404
1405# pb has to be added to portage group on gentoo
1406
1407# Adapt sudoers
1408$file="/etc/sudoers";
1409open(PBFILE,$file) || die "Unable to open $file";
1410open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1411while (<PBFILE>) {
1412EOF
1413 print SCRIPT << "EOF";
1414 next if (/^$pbac->{$ENV{'PBPROJ'}} /);
1415EOF
1416 print SCRIPT << 'EOF';
1417 s/Defaults[ \t]+requiretty//;
1418 print PBOUT $_;
1419}
1420close(PBFILE);
1421EOF
1422 print SCRIPT << "EOF";
1423# This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
1424print PBOUT "$pbac->{$ENV{'PBPROJ'}} ALL=(ALL) NOPASSWD:ALL\n";
1425EOF
1426 print SCRIPT << 'EOF';
1427close(PBOUT);
1428rename("$file.new",$file);
1429chmod 0440,$file;
1430
1431EOF
1432
1433 my $SCRIPT = \*SCRIPT;
1434
1435 pb_install_deps($SCRIPT);
1436
1437 print SCRIPT << 'EOF';
1438# Suse wants sudoers as 640
1439if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
1440 chmod 0640,$file;
1441}
1442
1443# Sync date
1444#system "/usr/sbin/ntpdate ntp.pool.org";
1445
1446system "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-*";
1447system "pb 2>&1 | head -5";
1448EOF
1449 if ((! $vmexist) && ($vtype eq "vm")) {
1450 print SCRIPT << 'EOF';
1451system "sudo /sbin/halt -p";
1452EOF
1453 }
1454
1455 # Adds pb_distro_init from ProjectBuilder::Distribution
1456 foreach my $d (@INC) {
1457 my $f = "$d/ProjectBuilder/Distribution.pm";
1458 if (-f "$f") {
1459 open(PBD,"$f") || die "Unable to open $f";
1460 while (<PBD>) {
1461 next if (/^package/);
1462 next if (/^use Exporter/);
1463 next if (/^\@our /);
1464 print SCRIPT $_;
1465 }
1466 close(PBD);
1467 last;
1468 }
1469 }
1470 close(SCRIPT);
1471 chmod 0755,"$pbscript";
1472
1473 # That build script needs to be run as root
1474 $pbaccount = "root";
1475 pb_script2v($pbscript,$vtype);
1476}
1477return;
1478}
1479
1480sub pb_install_deps {
1481
1482my $SCRIPT = shift;
1483
1484print {$SCRIPT} << 'EOF';
1485# We need to have that pb_distro_init function
1486# Get it from Project-Builder::Distribution
1487my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
1488print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
1489
1490# Get and install pb
1491my $insdm = "rm -rf Date-Manip* ; wget http://search.cpan.org/CPAN/authors/id/S/SB/SBECK/Date-Manip-5.48.tar.gz ; tar xvfz Date-Manip-5.48.tar.gz ; cd Date-Manip* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf Date-Manip*";
1492my $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*";
1493my $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*";
1494my $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*";
1495
1496if ( $ddir eq "fedora" ) {
1497 system "yum clean all";
1498 #system "yum update -y";
1499 my $arch=`uname -m`;
1500 my $opt = "";
1501 chomp($arch);
1502 if ($arch eq "x86_64") {
1503 $opt="--exclude=*.i?86";
1504 }
1505
1506 system "yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker";
1507 if ($dver eq 4) {
1508 system "$insmb";
1509 system "$insfm";
1510 system "$insfb";
1511 }
1512} elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
1513 # Suppose pkg are installed already as no online mirror available
1514 system "rpm -e lsb 2>&1 > /dev/null";
1515 system "$insdm";
1516 system "$insmb";
1517 system "$insfm";
1518 system "$insfb";
1519} elsif ($ddir eq "suse") {
1520 # New OpenSuSE
1521 system "$insmb";
1522 system "$insfm";
1523 system "$insfb";
1524 system "export TERM=linux ; liste=\"\" ; for i in make wget patch sudo perl-DateManip perl-File-HomeDir xntp; 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";
1525} elsif ( $dfam eq "md" ) {
1526 system "urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo";
1527 if (($ddir eq "mandrake") && ($dver eq "10.1")) {
1528 system "$insdm";
1529 } else {
1530 system "urpmi --auto perl-DateManip";
1531 }
1532} elsif ( $dfam eq "du" ) {
1533 if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
1534 #system "apt-get update";
1535 system "$insfb";
1536 system "$insfm";
1537 system "apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl";
1538 } else {
1539 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";
1540 }
1541} elsif ( $dfam eq "gen" ) {
1542 #system "emerge -u system ; emerge wget sudo ntp DateManip File-MimeInfo";
1543 system "emerge wget sudo ntp DateManip File-MimeInfo";
1544} else {
1545 print "No pkg to install\n";
1546}
1547EOF
1548}
1549
1550# Return the SSH key file to use
1551# Potentially create it if needed
1552
1553sub pb_ssh_get {
1554
1555my $create = shift || 0; # Do not create keys by default
1556
1557# Check the SSH environment
1558my $keyfile = undef;
1559
1560# We have specific keys by default
1561$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
1562if (!(-e $keyfile) && ($create eq 1)) {
1563 pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
1564}
1565
1566$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
1567$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
1568$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
1569die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
1570return($keyfile);
1571}
1572
1573
1574# Returns the pid of a running VM command using a specific VM file
1575sub pb_check_ps {
1576 my $vmcmd = shift;
1577 my $vmm = shift;
1578 my $vmexist = 0; # FALSE by default
1579
1580 open(PS, "ps auxhww|") || die "Unable to call ps";
1581 while (<PS>) {
1582 next if (! /$vmcmd/);
1583 next if (! /$vmm/);
1584 my ($void1, $void2);
1585 ($void1, $vmexist, $void2) = split(/ +/);
1586 last;
1587 }
1588 return($vmexist);
1589}
1590
1591
1592sub pb_extract_build_files {
1593
1594my $src=shift;
1595my $dir=shift;
1596my $ddir=shift;
1597my @files;
1598
1599if ($src =~ /tar\.gz$/) {
1600 pb_system("tar xfpz $src $dir","Extracting build files");
1601} elsif ($src =~ /tar\.bz2$/) {
1602 pb_system("tar xfpj $src $dir","Extracting build files");
1603} else {
1604 die "Unknown compression algorithm for $src";
1605}
1606opendir(DIR,"$dir") || die "Unable to open directory $dir";
1607foreach my $f (readdir(DIR)) {
1608 next if ($f =~ /^\./);
1609 move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
1610 pb_log(2,"mv $dir/$f $ddir\n");
1611 push @files,"$ddir/$f";
1612}
1613closedir(DIR);
1614# Not enough but still a first cleanup
1615pb_rm_rf("$dir");
1616return(@files);
1617}
1618
1619sub pb_list_bfiles {
1620
1621my $dir = shift;
1622my $pbpkg = shift;
1623my $bfiles = shift;
1624my $pkgfiles = shift;
1625my $supfiles = shift;
1626
1627opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
1628foreach my $f (readdir(BDIR)) {
1629 next if ($f =~ /^\./);
1630 $bfiles->{$f} = "$dir/$f";
1631 $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
1632 if (defined $supfiles->{$pbpkg}) {
1633 $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
1634 }
1635}
1636closedir(BDIR);
1637}
1638
1639sub pb_syntax {
1640
1641my $exit_status = shift || -1;
1642my $verbose_level = shift || 0;
1643
1644my $filehandle = \*STDERR;
1645
1646$filehandle = \*STDOUT if ($exit_status == 0);
1647
1648pod2usage( { -message => "pb (aka project-builder.org) Version $projectbuilderver-$projectbuilderrev\n",
1649 -exitval => $exit_status ,
1650 -verbose => $verbose_level,
1651 -output => $filehandle } );
1652}
1653
1654sub pb_env_init {
1655
1656my $proj=shift || undef;
1657my $pbinit=shift || undef;
1658my $action=shift;
1659my $ver;
1660my $tag;
1661
1662$ENV{'PBETC'} = "$ENV{'HOME'}/.pbrc";
1663
1664#
1665# Check project name
1666# Could be with env var PBPROJ
1667# or option -p
1668# if not define take the first in conf file
1669#
1670if ((defined $ENV{'PBPROJ'}) &&
1671 (not (defined $proj))) {
1672 $proj = $ENV{'PBPROJ'};
1673}
1674
1675#
1676# We get the pbconf file for that project
1677# and use its content
1678#
1679my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
1680pb_log(2,"DEBUG pbconfurl: ".Dumper($pbconf)."\n");
1681
1682my %pbconf = %$pbconf;
1683if (not defined $proj) {
1684 # Take the first as the default project
1685 $proj = (keys %pbconf)[0];
1686 if (defined $proj) {
1687 pb_log(1,"WARNING: using $proj as default project as none has been specified\n");
1688 pb_log(1," Please either create a pbconfurl reference for project $proj in $ENV{'PBETC'}\n");
1689 pb_log(1," or call pb with the -p project option or use the env var PBPROJ\n");
1690 pb_log(1," if you want to use another project\n");
1691 }
1692}
1693die "No project defined - use env var PBPROJ or -p proj or a pbconfurl entry in $ENV{'PBETC'}" if (not (defined $proj));
1694
1695# That's always the environment variable that will be used
1696$ENV{'PBPROJ'} = $proj;
1697pb_log(2,"PBPROJ: $ENV{'PBPROJ'}\n");
1698
1699if (not defined ($pbconf{$ENV{'PBPROJ'}})) {
1700 die "Please create a pbconfurl reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n";
1701}
1702
1703#
1704# Detect the root dir for hosting all the content generated with pb
1705#
1706# Tree will look like this:
1707#
1708# maint pbdefdir PBDEFDIR dev dir (optional)
1709# | |
1710# ------------------------ --------------------
1711# | | | |
1712# pbproj1 pbproj2 PBPROJ pbproj1 pbproj2 PBPROJDIR
1713# | |
1714# --------------------------------------------- ----------
1715# * * * | | | * *
1716# tag dev pbconf ... build delivery PBCONFDIR dev tag
1717# | | | PBDESTDIR |
1718# --- ------ pbrc PBBUILDDIR -------
1719# | | | | |
1720# 1.1 dev tag 1.0 1.1 PBDIR
1721# |
1722# -------
1723# | |
1724# 1.0 1.1 PBROOTDIR
1725# |
1726# ----------------------------------
1727# | | | |
1728# pkg1 pbproj1.pb pbfilter pbcl
1729# |
1730# -----------------
1731# | | |
1732# rpm deb pbfilter
1733#
1734#
1735# (*) By default, if no relocation in .pbrc, dev dir is taken in the maint pbdefdir (when appropriate)
1736# Names under a pbproj and the corresponding pbconf should be similar
1737#
1738
1739my ($pbdefdir) = pb_conf_get_if("pbdefdir");
1740
1741if (not defined $ENV{'PBDEFDIR'}) {
1742 if ((not defined $pbdefdir) || (not defined $pbdefdir->{$ENV{'PBPROJ'}})) {
1743 pb_log(1,"WARNING: no pbdefdir defined, using /var/cache\n");
1744 pb_log(1," Please create a pbdefdir reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
1745 pb_log(1," if you want to use another directory\n");
1746 $ENV{'PBDEFDIR'} = "/var/cache";
1747 } else {
1748 # That's always the environment variable that will be used
1749 $ENV{'PBDEFDIR'} = $pbdefdir->{$ENV{'PBPROJ'}};
1750 }
1751}
1752# Expand potential env variable in it
1753eval { $ENV{'PBDEFDIR'} =~ s/(\$ENV.+\})/$1/eeg };
1754
1755pb_log(2,"PBDEFDIR: $ENV{'PBDEFDIR'}\n");
1756#
1757# Set delivery directory
1758#
1759$ENV{'PBDESTDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/delivery";
1760
1761pb_log(2,"PBDESTDIR: $ENV{'PBDESTDIR'}\n");
1762#
1763# Removes all directory existing below the delivery dir
1764# as they are temp dir only
1765# Files stay and have to be cleaned up manually if needed
1766# those files serves as communication channels between pb phases
1767# Removing them prevents a following phase to detect what has been done before
1768#
1769if (-d $ENV{'PBDESTDIR'}) {
1770 opendir(DIR,$ENV{'PBDESTDIR'}) || die "Unable to open directory $ENV{'PBDESTDIR'}: $!";
1771 foreach my $d (readdir(DIR)) {
1772 next if ($d =~ /^\./);
1773 next if (-f "$ENV{'PBDESTDIR'}/$d");
1774 pb_rm_rf("$ENV{'PBDESTDIR'}/$d") if (-d "$ENV{'PBDESTDIR'}/$d");
1775 }
1776 closedir(DIR);
1777}
1778if (! -d "$ENV{'PBDESTDIR'}") {
1779 pb_mkdir_p($ENV{'PBDESTDIR'}) || die "Unable to recursively create $ENV{'PBDESTDIR'}";
1780}
1781
1782#
1783# Set build directory
1784#
1785$ENV{'PBBUILDDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/build";
1786if (! -d "$ENV{'PBBUILDDIR'}") {
1787 pb_mkdir_p($ENV{'PBBUILDDIR'}) || die "Unable to recursively create $ENV{'PBBUILDDIR'}";
1788}
1789
1790pb_log(2,"PBBUILDDIR: $ENV{'PBBUILDDIR'}\n");
1791#
1792# Set temp directory
1793#
1794if (not defined $ENV{'TMPDIR'}) {
1795 $ENV{'TMPDIR'}="/tmp";
1796}
1797$ENV{'PBTMP'} = tempdir( "pb.XXXXXXXXXX", DIR => $ENV{'TMPDIR'}, CLEANUP => 1 );
1798pb_log(2,"PBTMP: $ENV{'PBTMP'}\n");
1799
1800#
1801# The following part is only useful when in cms2something of newver
1802# In VMs/VEs we want to skip that by providing good env vars.
1803# return values in that case are useless
1804#
1805if (($action =~ /^cms2/) || ($action =~ /^newver$/)) {
1806
1807 #
1808 # Check pbconf cms compliance
1809 #
1810 pb_cms_compliant("pbconfdir",'PBCONFDIR',"$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/pbconf",$pbconf{$ENV{'PBPROJ'}},$pbinit);
1811
1812 # Check where is our PBROOTDIR (release tag name can't be guessed the first time)
1813 #
1814 if (not defined $ENV{'PBROOTDIR'}) {
1815 if (! -f ("$ENV{'PBDESTDIR'}/pbrc")) {
1816 opendir(DIR,$ENV{'PBCONFDIR'}) || die "Unable to open directory $ENV{'PBCONFDIR'}: $!";
1817 my $maxmtime = 0;
1818 foreach my $d (readdir(DIR)) {
1819 pb_log(3,"Looking at \'$d\'...");
1820 next if ($d =~ /^\./);
1821 next if (! -d "$ENV{'PBCONFDIR'}/$d");
1822 my $s = stat("$ENV{'PBCONFDIR'}/$d");
1823 next if (not defined $s);
1824 pb_log(3,"KEEP\n");
1825 # Keep the most recent
1826 pb_log(2," $s->mtime\n");
1827 if ($s->mtime > $maxmtime) {
1828 $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$d";
1829 $maxmtime = $s->mtime;
1830 }
1831 }
1832 closedir(DIR);
1833 die "No directory found under $ENV{'PBCONFDIR'}" if (not defined $ENV{'PBROOTDIR'});
1834 pb_log(1,"WARNING: no pbroot defined, using $ENV{'PBROOTDIR'}\n");
1835 pb_log(1," Please use -r release if you want to use another release\n");
1836 } else {
1837 my ($pbroot) = pb_conf_read_if("$ENV{'PBDESTDIR'}/pbrc","pbroot");
1838 # That's always the environment variable that will be used
1839 die "Please remove inconsistent $ENV{'PBDESTDIR'}/pbrc" if ((not defined $pbroot) || (not defined $pbroot->{$ENV{'PBPROJ'}}));
1840 $ENV{'PBROOTDIR'} = $pbroot->{$ENV{'PBPROJ'}};
1841 }
1842 } else {
1843 # transform in full path if relative
1844 $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$ENV{'PBROOTDIR'}" if ($ENV{'PBROOTDIR'} !~ /^\//);
1845 pb_mkdir_p($ENV{'PBROOTDIR'}) if (defined $pbinit);
1846 die "$ENV{'PBROOTDIR'} is not a directory" if (not -d $ENV{'PBROOTDIR'});
1847 }
1848
1849 return if ($action =~ /^newver$/);
1850
1851 my %version = ();
1852 my %defpkgdir = ();
1853 my %extpkgdir = ();
1854 my %filteredfiles = ();
1855 my %supfiles = ();
1856
1857 if ((-f "$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") and (not defined $pbinit)) {
1858 # List of pkg to build by default (mandatory)
1859 my ($defpkgdir,$pbpackager, $pkgv, $pkgt) = pb_conf_get("defpkgdir","pbpackager","projver","projtag");
1860 # List of additional pkg to build when all is called (optional)
1861 # Valid version names (optional)
1862 # List of files to filter (optional)
1863 # Project version and tag (optional)
1864 my ($extpkgdir, $version, $filteredfiles, $supfiles) = pb_conf_get_if("extpkgdir","version","filteredfiles","supfiles");
1865 pb_log(2,"DEBUG: defpkgdir: ".Dumper($defpkgdir)."\n");
1866 pb_log(2,"DEBUG: extpkgdir: ".Dumper($extpkgdir)."\n");
1867 pb_log(2,"DEBUG: version: ".Dumper($version)."\n");
1868 pb_log(2,"DEBUG: filteredfiles: ".Dumper($filteredfiles)."\n");
1869 pb_log(2,"DEBUG: supfiles: ".Dumper($supfiles)."\n");
1870 # Global
1871 %defpkgdir = %$defpkgdir;
1872 %extpkgdir = %$extpkgdir if (defined $extpkgdir);
1873 %version = %$version if (defined $version);
1874 %filteredfiles = %$filteredfiles if (defined $filteredfiles);
1875 %supfiles = %$supfiles if (defined $supfiles);
1876 #
1877 # Get global Version/Tag
1878 #
1879 if (not defined $ENV{'PBPROJVER'}) {
1880 if ((defined $pkgv) && (defined $pkgv->{$ENV{'PBPROJ'}})) {
1881 $ENV{'PBPROJVER'}=$pkgv->{$ENV{'PBPROJ'}};
1882 } else {
1883 die "No projver found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1884 }
1885 }
1886 die "Invalid version name $ENV{'PBPROJVER'} in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb" if (($ENV{'PBPROJVER'} !~ /[0-9.]+/) && (not defined $version) && ($ENV{'PBPROJVER'} =~ /$version{$ENV{'PBPROJ'}}/));
1887
1888 if (not defined $ENV{'PBPROJTAG'}) {
1889 if ((defined $pkgt) && (defined $pkgt->{$ENV{'PBPROJ'}})) {
1890 $ENV{'PBPROJTAG'}=$pkgt->{$ENV{'PBPROJ'}};
1891 } else {
1892 die "No projtag found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1893 }
1894 }
1895 die "Invalid tag name $ENV{'PBPROJTAG'} in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb" if ($ENV{'PBPROJTAG'} !~ /[0-9.]+/);
1896
1897
1898 if (not defined $ENV{'PBPACKAGER'}) {
1899 if ((defined $pbpackager) && (defined $pbpackager->{$ENV{'PBPROJ'}})) {
1900 $ENV{'PBPACKAGER'}=$pbpackager->{$ENV{'PBPROJ'}};
1901 } else {
1902 die "No pbpackager found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1903 }
1904 }
1905 } else {
1906 if (defined $pbinit) {
1907 my $ptr = pb_get_pkg();
1908 my @pkgs = @$ptr;
1909 @pkgs = ("pkg1") if (not @pkgs);
1910
1911 open(CONF,"> $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") || die "Unable to create $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1912 print CONF << "EOF";
1913#
1914# Project Builder configuration file
1915# For project $ENV{'PBPROJ'}
1916#
1917# \$Id\$
1918#
1919
1920#
1921# What is the project URL
1922#
1923#pburl $ENV{'PBPROJ'} = svn://svn.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1924#pburl $ENV{'PBPROJ'} = svn://svn+ssh.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1925#pburl $ENV{'PBPROJ'} = cvs://cvs.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1926#pburl $ENV{'PBPROJ'} = http://www.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
1927#pburl $ENV{'PBPROJ'} = ftp://ftp.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
1928#pburl $ENV{'PBPROJ'} = file:///src/$ENV{'PBPROJ'}-devel.tar.gz
1929#pburl $ENV{'PBPROJ'} = dir:///src/$ENV{'PBPROJ'}-devel
1930
1931# Check whether project is well formed
1932# (containing already a directory with the project-version name)
1933#pbwf $ENV{'PBPROJ'} = 1
1934
1935#
1936# Packager label
1937#
1938#pbpackager $ENV{'PBPROJ'} = William Porte <bill\@$ENV{'PBPROJ'}.org>
1939#
1940
1941# For delivery to a machine by SSH (potentially the FTP server)
1942# Needs hostname, account and directory
1943#
1944#sshhost $ENV{'PBPROJ'} = www.$ENV{'PBPROJ'}.org
1945#sshlogin $ENV{'PBPROJ'} = bill
1946#sshdir $ENV{'PBPROJ'} = /$ENV{'PBPROJ'}/ftp
1947#sshport $ENV{'PBPROJ'} = 22
1948
1949#
1950# For Virtual machines management
1951# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
1952# followed by '-' and by release number
1953# followed by '-' and by architecture
1954# a .vmtype extension will be added to the resulting string
1955# a QEMU rhel-3-i286 here means that the VM will be named rhel-3-i386.qemu
1956#
1957#vmlist $ENV{'PBPROJ'} = mandrake-10.1-i386,mandrake-10.2-i386,mandriva-2006.0-i386,mandriva-2007.0-i386,mandriva-2007.1-i386,mandriva-2008.0-i386,redhat-7.3-i386,redhat-9-i386,fedora-4-i386,fedora-5-i386,fedora-6-i386,fedora-7-i386,fedora-8-i386,rhel-3-i386,rhel-4-i386,rhel-5-i386,suse-10.0-i386,suse-10.1-i386,suse-10.2-i386,suse-10.3-i386,sles-9-i386,sles-10-i386,gentoo-nover-i386,debian-3.1-i386,debian-4.0-i386,ubuntu-6.06-i386,ubuntu-7.04-i386,ubuntu-7.10-i386,mandriva-2007.0-x86_64,mandriva-2007.1-x86_64,mandriva-2008.0-x86_64,fedora-6-x86_64,fedora-7-x86_64,fedora-8-x86_64,rhel-4-x86_64,rhel-5-x86_64,suse-10.2-x86_64,suse-10.3-x86_64,sles-10-x86_64,gentoo-nover-x86_64,debian-4.0-x86_64,ubuntu-7.04-x86_64,ubuntu-7.10-x86_64
1958
1959#
1960# Valid values for vmtype are
1961# qemu, (vmware, xen, ... TBD)
1962#vmtype $ENV{'PBPROJ'} = qemu
1963
1964# Hash for VM stuff on vmtype
1965#vmntp default = pool.ntp.org
1966
1967# We suppose we can commmunicate with the VM through SSH
1968#vmhost $ENV{'PBPROJ'} = localhost
1969#vmlogin $ENV{'PBPROJ'} = pb
1970#vmport $ENV{'PBPROJ'} = 2222
1971
1972# Timeout to wait when VM is launched/stopped
1973#vmtmout default = 120
1974
1975# per VMs needed paramaters
1976#vmopt $ENV{'PBPROJ'} = -m 384 -daemonize
1977#vmpath $ENV{'PBPROJ'} = /home/qemu
1978#vmsize $ENV{'PBPROJ'} = 5G
1979
1980#
1981# For Virtual environment management
1982# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
1983# followed by '-' and by release number
1984# followed by '-' and by architecture
1985# a .vetype extension will be added to the resulting string
1986# a chroot rhel-3-i286 here means that the VE will be named rhel-3-i386.chroot
1987#
1988#velist $ENV{'PBPROJ'} = fedora-7-i386
1989
1990# VE params
1991#vetype $ENV{'PBPROJ'} = chroot
1992#ventp default = pool.ntp.org
1993#velogin $ENV{'PBPROJ'} = pb
1994#vepath $ENV{'PBPROJ'} = /var/lib/mock
1995#veconf $ENV{'PBPROJ'} = /etc/mock
1996#verebuild $ENV{'PBPROJ'} = false
1997
1998#
1999# Global version/tag for the project
2000#
2001#projver $ENV{'PBPROJ'} = devel
2002#projtag $ENV{'PBPROJ'} = 1
2003
2004# Hash of valid version names
2005#version $ENV{'PBPROJ'} = devel,stable
2006
2007# Adapt to your needs:
2008# Optional if you need to overwrite the global values above
2009#
2010EOF
2011
2012 foreach my $pp (@pkgs) {
2013 print CONF << "EOF";
2014#pkgver $pp = stable
2015#pkgtag $pp = 3
2016EOF
2017 }
2018 foreach my $pp (@pkgs) {
2019 print CONF << "EOF";
2020# Hash of default package/package directory
2021#defpkgdir $pp = dir-$pp
2022EOF
2023 }
2024
2025 print CONF << "EOF";
2026# Hash of additional package/package directory
2027#extpkgdir minor-pkg = dir-minor-pkg
2028
2029# List of files per pkg on which to apply filters
2030# Files are mentioned relatively to pbroot/defpkgdir
2031EOF
2032 foreach my $pp (@pkgs) {
2033 print CONF << "EOF";
2034#filteredfiles $pp = Makefile.PL,configure.in,install.sh,$pp.8
2035#supfiles $pp = $pp.init
2036EOF
2037 }
2038 close(CONF);
2039 pb_mkdir_p("$ENV{'PBROOTDIR'}/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter";
2040 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/all.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/all.pbf";
2041 print CONF << "EOF";
2042#
2043# \$Id\$
2044#
2045# Filter for all files
2046#
2047# PBSRC is replaced by the source package format
2048#filter PBSRC = ftp://ftp.$ENV{'PBPROJ'}.org/src/%{name}-%{version}.tar.gz
2049
2050# PBVER is replaced by the version (\$pbver in code)
2051filter PBVER = \$pbver
2052
2053# PBDATE is replaced by the date (\$pbdate in code)
2054filter PBDATE = \$pbdate
2055
2056# PBLOG is replaced by the changelog if value is yes
2057#filter PBLOG = yes
2058
2059# PBTAG is replaced by the tag (\$pbtag in code)
2060filter PBTAG = \$pbtag
2061
2062# PBREV is replaced by the revision (\$pbrev in code)
2063filter PBREV = \$pbrev
2064
2065# PBPKG is replaced by the package name (\$pbpkg in code)
2066filter PBPKG = \$pbpkg
2067
2068# PBPACKAGER is replaced by the packager name (\$pbpackager in code)
2069filter PBPACKAGER = \$pbpackager
2070
2071# PBDESC contains the description of the package
2072#filter PBDESC = "Bla-Bla"
2073
2074# PBURL contains the URL of the Web site of the project
2075#filter PBURL = http://www.$ENV{'PBPROJ'}.org
2076EOF
2077 close(CONF);
2078 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf";
2079 print CONF << "EOF";
2080#
2081# \$Id\$
2082#
2083# Filter for rpm build
2084#
2085
2086# PBGRP is replaced by the RPM group of apps
2087# Cf: http://fedoraproject.org/wiki/RPMGroups
2088#filter PBGRP = Applications/Archiving
2089
2090# PBLIC is replaced by the license of the application
2091# Cf: http://fedoraproject.org/wiki/Licensing
2092#filter PBLIC = GPL
2093
2094# PBDEP is replaced by the list of dependencies
2095#filter PBDEP =
2096
2097# PBSUF is replaced by the package suffix (\$pbsuf in code)
2098filter PBSUF = \$pbsuf
2099
2100# PBOBS is replaced by the Obsolete line
2101#filter PBOBS =
2102
2103EOF
2104 close(CONF);
2105 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/deb.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/deb.pbf";
2106 print CONF << "EOF";
2107#
2108# \$Id\$
2109#
2110# Filter for debian build
2111#
2112# PBGRP is replaced by the group of apps
2113filter PBGRP = utils
2114
2115# PBLIC is replaced by the license of the application
2116# Cf:
2117#filter PBLIC = GPL
2118
2119# PBDEP is replaced by the list of dependencies
2120#filter PBDEP =
2121
2122# PBSUG is replaced by the list of suggestions
2123#filter PBSUG =
2124
2125# PBREC is replaced by the list of recommandations
2126#filter PBREC =
2127
2128EOF
2129 close(CONF);
2130 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/md.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/md.pbf";
2131 print CONF << "EOF";
2132# Specific group for Mandriva for $ENV{'PBPROJ'}
2133# Cf: http://wiki.mandriva.com/en/Development/Packaging/Groups
2134#filter PBGRP = Archiving/Backup
2135
2136# PBLIC is replaced by the license of the application
2137# Cf: http://wiki.mandriva.com/en/Development/Packaging/Licenses
2138#filter PBLIC = GPL
2139
2140EOF
2141 close(CONF);
2142 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/novell.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/novell.pbf";
2143 print CONF << "EOF";
2144# Specific group for SuSE for $ENV{'PBPROJ'}
2145# Cf: http://en.opensuse.org/SUSE_Package_Conventions/RPM_Groups
2146#filter PBGRP = Productivity/Archiving/Backup
2147
2148# PBLIC is replaced by the license of the application
2149# Cf: http://en.opensuse.org/Packaging/SUSE_Package_Conventions/RPM_Style#1.6._License_Tag
2150#filter PBLIC = GPL
2151
2152EOF
2153 close(CONF);
2154 foreach my $pp (@pkgs) {
2155 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/deb") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb";
2156 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/control") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/control";
2157 print CONF << "EOF";
2158Source: PBPKG
2159Section: PBGRP
2160Priority: optional
2161Maintainer: PBPACKAGER
2162Build-Depends: debhelper (>= 4.2.20), PBDEP
2163Standards-Version: 3.6.1
2164
2165Package: PBPKG
2166Architecture: amd64 i386 ia64
2167Section: PBGRP
2168Priority: optional
2169Depends: \${shlibs:Depends}, \${misc:Depends}, PBDEP
2170Recommends: PBREC
2171Suggests: PBSUG
2172Description:
2173 PBDESC
2174 .
2175 Homepage: PBURL
2176
2177EOF
2178 close(CONF);
2179 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/copyright") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/copyright";
2180 print CONF << "EOF";
2181This package is debianized by PBPACKAGER
2182`date`
2183
2184The current upstream source was downloaded from
2185ftp://ftp.$ENV{'PBPROJ'}.org/src/.
2186
2187Upstream Authors: Put their name here
2188
2189Copyright:
2190
2191 This package is free software; you can redistribute it and/or modify
2192 it under the terms of the GNU General Public License as published by
2193 the Free Software Foundation; version 2 dated June, 1991.
2194
2195 This package is distributed in the hope that it will be useful,
2196 but WITHOUT ANY WARRANTY; without even the implied warranty of
2197 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2198 GNU General Public License for more details.
2199
2200 You should have received a copy of the GNU General Public License
2201 along with this package; if not, write to the Free Software
2202 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
2203 MA 02110-1301, USA.
2204
2205On Debian systems, the complete text of the GNU General
2206Public License can be found in /usr/share/common-licenses/GPL.
2207
2208EOF
2209 close(CONF);
2210 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/changelog") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/changelog";
2211 print CONF << "EOF";
2212PBLOG
2213EOF
2214 close(CONF);
2215 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/compat") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/compat";
2216 print CONF << "EOF";
22174
2218EOF
2219 close(CONF);
2220 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs";
2221 print CONF << "EOF";
2222EOF
2223 close(CONF);
2224 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs";
2225 print CONF << "EOF";
2226INSTALL
2227COPYING
2228AUTHORS
2229NEWS
2230README
2231EOF
2232 close(CONF);
2233 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/rules") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/rules";
2234 print CONF << 'EOF';
2235#!/usr/bin/make -f
2236# -*- makefile -*-
2237# Sample debian/rules that uses debhelper.
2238# GNU copyright 1997 to 1999 by Joey Hess.
2239#
2240# $Id$
2241#
2242
2243# Uncomment this to turn on verbose mode.
2244#export DH_VERBOSE=1
2245
2246# Define package name variable for a one-stop change.
2247PACKAGE_NAME = PBPKG
2248
2249# These are used for cross-compiling and for saving the configure script
2250# from having to guess our platform (since we know it already)
2251DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
2252DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
2253
2254CFLAGS = -Wall -g
2255
2256ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
2257 CFLAGS += -O0
2258else
2259 CFLAGS += -O2
2260endif
2261ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
2262 INSTALL_PROGRAM += -s
2263endif
2264config.status: configure
2265 dh_testdir
2266
2267 # Configure the package.
2268 CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr
2269 --mandir=\$${prefix}/share/man
2270
2271# Build both architecture dependent and independent
2272build: build-arch build-indep
2273
2274# Build architecture dependent
2275build-arch: build-arch-stamp
2276
2277build-arch-stamp: config.status
2278 dh_testdir
2279
2280 # Compile the package.
2281 $(MAKE)
2282
2283 touch build-stamp
2284
2285# Build architecture independent
2286build-indep: build-indep-stamp
2287
2288build-indep-stamp: config.status
2289 # Nothing to do, the only indep item is the manual which is available as html in original source
2290 touch build-indep-stamp
2291
2292# Clean up
2293clean:
2294 dh_testdir
2295 dh_testroot
2296 rm -f build-arch-stamp build-indep-stamp #CONFIGURE-STAMP#
2297 # Clean temporary document directory
2298 rm -rf debian/doc-temp
2299 # Clean up.
2300 -$(MAKE) distclean
2301 rm -f config.log
2302ifneq "$(wildcard /usr/share/misc/config.sub)" ""
2303 cp -f /usr/share/misc/config.sub config.sub
2304endif
2305ifneq "$(wildcard /usr/share/misc/config.guess)" ""
2306 cp -f /usr/share/misc/config.guess config.guess
2307endif
2308
2309 dh_clean
2310
2311# Install architecture dependent and independent
2312install: install-arch install-indep
2313
2314# Install architecture dependent
2315install-arch: build-arch
2316 dh_testdir
2317 dh_testroot
2318 dh_clean -k -s
2319 dh_installdirs -s
2320
2321 # Install the package files into build directory:
2322 # - start with upstream make install
2323 $(MAKE) install prefix=$(CURDIR)/debian/$(PACKAGE_NAME)/usr mandir=$(CURDIR)/debian/$(PACKAGE_NAME)/us
2324r/share/man
2325 # - copy html manual to temporary location for renaming
2326 mkdir -p debian/doc-temp
2327 dh_install -s
2328
2329# Install architecture independent
2330install-indep: build-indep
2331 dh_testdir
2332 dh_testroot
2333 dh_clean -k -i
2334 dh_installdirs -i
2335 dh_install -i
2336
2337# Must not depend on anything. This is to be called by
2338# binary-arch/binary-indep
2339# in another 'make' thread.
2340binary-common:
2341 dh_testdir
2342 dh_testroot
2343 dh_installchangelogs ChangeLog
2344 dh_installdocs
2345 dh_installman
2346 dh_link
2347 dh_strip
2348 dh_compress
2349 dh_fixperms
2350 dh_installdeb
2351 dh_shlibdeps
2352 dh_gencontrol
2353 dh_md5sums
2354 dh_builddeb
2355
2356# Build architecture independant packages using the common target.
2357binary-indep: build-indep install-indep
2358 $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
2359
2360# Build architecture dependant packages using the common target.
2361binary-arch: build-arch install-arch
2362 $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
2363
2364# Build architecture depdendent and independent packages
2365binary: binary-arch binary-indep
2366.PHONY: clean binary
2367
2368EOF
2369 close(CONF);
2370 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/rpm") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm";
2371 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec";
2372 print CONF << 'EOF';
2373#
2374# $Id$
2375#
2376
2377Summary: bla-bla
2378Summary(fr): french bla-bla
2379
2380Name: PBPKG
2381Version: PBVER
2382Release: PBTAGPBSUF
2383License: PBLIC
2384Group: PBGRP
2385Url: PBURL
2386Source: PBSRC
2387BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -u -n)
2388#Requires: PBDEP
2389
2390%description
2391PBDESC
2392
2393%description -l fr
2394french desc
2395
2396%prep
2397%setup -q
2398
2399%build
2400%configure
2401make %{?_smp_mflags}
2402
2403%install
2404%{__rm} -rf $RPM_BUILD_ROOT
2405make DESTDIR=$RPM_BUILD_ROOT install
2406
2407%clean
2408%{__rm} -rf $RPM_BUILD_ROOT
2409
2410%files
2411%defattr(-,root,root)
2412%doc ChangeLog
2413%doc INSTALL COPYING README AUTHORS NEWS
2414
2415%changelog
2416PBLOG
2417
2418EOF
2419 close(CONF);
2420 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/pbfilter";
2421
2422 pb_log(0,"\nDo not to forget to commit the pbconf directory in your CMS if needed\n");
2423 }
2424 } else {
2425 die "Unable to open $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
2426 }
2427 }
2428 umask 0022;
2429 return(\%filteredfiles, \%supfiles, \%defpkgdir, \%extpkgdir);
2430} else {
2431 # Setup the variables from what has been stored at the end of cms2build
2432 my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbroot");
2433 $ENV{'PBROOTDIR'} = $var->{$ENV{'PBPROJ'}};
2434
2435 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projver");
2436 $ENV{'PBPROJVER'} = $var->{$ENV{'PBPROJ'}};
2437
2438 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projtag");
2439 $ENV{'PBPROJTAG'} = $var->{$ENV{'PBPROJ'}};
2440
2441 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbpackager");
2442 $ENV{'PBPACKAGER'} = $var->{$ENV{'PBPROJ'}};
2443
2444 return;
2445}
2446}
2447
2448# Function which returns a pointer on a table
2449# corresponding to a set of values queried in the conf file
2450# and test the returned vaue as they need to exist in that case
2451sub pb_conf_get {
2452
2453my @param = @_;
2454my @return = pb_conf_get_if(@param);
2455
2456die "No params found for $ENV{'PBPROJ'}" if (not @return);
2457
2458foreach my $i (0..$#param) {
2459 die "No $param[$i] defined for $ENV{'PBPROJ'}" if (not defined $return[$i]);
2460}
2461return(@return);
2462}
2463
2464# Function which returns a pointer on a table
2465# corresponding to a set of values queried in the conf file
2466# Those value may be undef if they do not exist
2467sub pb_conf_get_if {
2468
2469my @param = @_;
2470
2471# Everything is returned via ptr1
2472my @ptr1 = ();
2473my @ptr2 = ();
2474@ptr1 = pb_conf_read_if("$ENV{'PBETC'}", @param) if (defined $ENV{'PBETC'});
2475@ptr2 = pb_conf_read_if("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb", @param) if ((defined $ENV{'PBROOTDIR'}) and (defined $ENV{'PBPROJ'}));
2476
2477my $p1;
2478my $p2;
2479
2480pb_log(2,"DEBUG: pb_conf_get param1: ".Dumper(@ptr1)."\n");
2481pb_log(2,"DEBUG: pb_conf_get param2: ".Dumper(@ptr2)."\n");
2482
2483foreach my $i (0..$#param) {
2484 $p1 = $ptr1[$i];
2485 $p2 = $ptr2[$i];
2486 # Always try to take the param from the home dir conf file in priority
2487 # in order to mask what could be defined under the CMS to allow for overloading
2488 if (not defined $p2) {
2489 # No ref in CMS project conf file so use the home dir one.
2490 $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if ((not defined $p1->{$ENV{'PBPROJ'}}) && (defined $p1->{'default'}));
2491 } else {
2492 # Ref found in CMS project conf file
2493 if (not defined $p1) {
2494 # No ref in home dir project conf file so use the CMS one.
2495 $p2->{$ENV{'PBPROJ'}} = $p2->{'default'} if ((not defined $p2->{$ENV{'PBPROJ'}}) && (defined $p2->{'default'}));
2496 $p1 = $p2;
2497 } else {
2498 # Both are defined - handling the overloading
2499 if (not defined $p1->{'default'}) {
2500 if (defined $p2->{'default'}) {
2501 $p1->{'default'} = $p2->{'default'};
2502 }
2503 }
2504
2505 if (not defined $p1->{$ENV{'PBPROJ'}}) {
2506 if (defined $p2->{$ENV{'PBPROJ'}}) {
2507 $p1->{$ENV{'PBPROJ'}} = $p2->{$ENV{'PBPROJ'}} if (defined $p2->{$ENV{'PBPROJ'}});
2508 } else {
2509 $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if (defined $p1->{'default'});
2510 }
2511 }
2512 # Now copy back into p1 all p2 content which doesn't exist in p1
2513 # p1 content (local) always has priority over p2 (project)
2514 foreach my $k (keys %$p2) {
2515 $p1->{$k} = $p2->{$k} if (not defined $p1->{$k});
2516 }
2517 }
2518 }
2519 $ptr1[$i] = $p1;
2520}
2521pb_log(2,"DEBUG: pb_conf_get param ptr1: ".Dumper(@ptr1)."\n");
2522return(@ptr1);
2523}
2524
2525# Setup environment for CMS system for URL passed
2526sub pb_cms_init {
2527
2528my $pbinit = shift || undef;
2529
2530my ($pburl) = pb_conf_get("pburl");
2531pb_log(2,"DEBUG: Project URL of $ENV{'PBPROJ'}: $pburl->{$ENV{'PBPROJ'}}\n");
2532my ($scheme, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
2533
2534my ($pbprojdir) = pb_conf_get_if("pbprojdir");
2535
2536if ((defined $pbprojdir) && (defined $pbprojdir->{$ENV{'PBPROJ'}})) {
2537 $ENV{'PBPROJDIR'} = $pbprojdir->{$ENV{'PBPROJ'}};
2538} else {
2539 $ENV{'PBPROJDIR'} = "$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}";
2540}
2541
2542# Computing the default dir for PBDIR.
2543# what we have is PBPROJDIR so work from that.
2544# Tree identical between PBCONFDIR and PBROOTDIR on one side and
2545# PBPROJDIR and PBDIR on the other side.
2546
2547my $tmp = $ENV{'PBROOTDIR'};
2548$tmp =~ s|^$ENV{'PBCONFDIR'}||;
2549
2550#
2551# Check project cms compliance
2552#
2553pb_cms_compliant(undef,'PBDIR',"$ENV{'PBPROJDIR'}/$tmp",$pburl->{$ENV{'PBPROJ'}},$pbinit);
2554
2555if ($scheme =~ /^svn/) {
2556 # svnversion more precise than svn info
2557 $tmp = `(cd "$ENV{'PBDIR'}" ; svnversion .)`;
2558 chomp($tmp);
2559 $ENV{'PBREVISION'}=$tmp;
2560 $ENV{'PBCMSLOGFILE'}="svn.log";
2561} elsif (($scheme eq "file") || ($scheme eq "ftp") || ($scheme eq "http")) {
2562 $ENV{'PBREVISION'}="flat";
2563 $ENV{'PBCMSLOGFILE'}="flat.log";
2564} elsif ($scheme =~ /^cvs/) {
2565 # Way too slow
2566 #$ENV{'PBREVISION'}=`(cd "$ENV{'PBROOTDIR'}" ; cvs rannotate -f . 2>&1 | awk '{print \$1}' | grep -E '^[0-9]' | cut -d. -f2 |sort -nu | tail -1)`;
2567 #chomp($ENV{'PBREVISION'});
2568 $ENV{'PBREVISION'}="cvs";
2569 $ENV{'PBCMSLOGFILE'}="cvs.log";
2570 $ENV{'CVS_RSH'} = "ssh" if ($scheme =~ /ssh/);
2571} else {
2572 die "cms $scheme unknown";
2573}
2574
2575return($scheme,$pburl->{$ENV{'PBPROJ'}});
2576}
2577
2578sub pb_cms_export {
2579
2580my $uri = shift;
2581my $source = shift;
2582my $destdir = shift;
2583my $tmp;
2584my $tmp1;
2585
2586my @date = pb_get_date();
2587# If it's not flat, then we have a real uri as source
2588my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
2589
2590if ($scheme =~ /^svn/) {
2591 if (-d $source) {
2592 $tmp = $destdir;
2593 } else {
2594 $tmp = "$destdir/".basename($source);
2595 }
2596 pb_system("svn export $source $tmp","Exporting $source from SVN to $tmp");
2597} elsif ($scheme eq "dir") {
2598 pb_system("cp -a $path $destdir","Copying $uri from DIR to $destdir");
2599} elsif (($scheme eq "http") || ($scheme eq "ftp")) {
2600 my $f = basename($path);
2601 unlink "$ENV{'PBTMP'}/$f";
2602 if (-x "/usr/bin/wget") {
2603 pb_system("/usr/bin/wget -nv -O $ENV{'PBTMP'}/$f $uri"," ");
2604 } elsif (-x "/usr/bin/curl") {
2605 pb_system("/usr/bin/curl $uri -o $ENV{'PBTMP'}/$f","Downloading $uri with curl to $ENV{'PBTMP'}/$f\n");
2606 } else {
2607 die "Unable to download $uri.\nNo wget/curl available, please install one of those";
2608 }
2609 pb_cms_export("file://$ENV{'PBTMP'}/$f",$source,$destdir);
2610} elsif ($scheme eq "file") {
2611 use File::MimeInfo;
2612 my $mm = mimetype($path);
2613 pb_log(2,"mimetype: $mm\n");
2614 pb_mkdir_p($destdir);
2615
2616 # Check whether the file is well formed
2617 # (containing already a directory with the project-version name)
2618 my ($pbwf) = pb_conf_get_if("pbwf");
2619 if ((defined $pbwf) && (defined $pbwf->{$ENV{'PBPROJ'}})) {
2620 $destdir = dirname($destdir);
2621 }
2622
2623 if ($mm =~ /\/x-bzip-compressed-tar$/) {
2624 # tar+bzip2
2625 pb_system("cd $destdir ; tar xfj $path","Extracting $path in $destdir");
2626 } elsif ($mm =~ /\/x-lzma-compressed-tar$/) {
2627 # tar+lzma
2628 pb_system("cd $destdir ; tar xfY $path","Extracting $path in $destdir");
2629 } elsif ($mm =~ /\/x-compressed-tar$/) {
2630 # tar+gzip
2631 pb_system("cd $destdir ; tar xfz $path","Extracting $path in $destdir");
2632 } elsif ($mm =~ /\/x-tar$/) {
2633 # tar
2634 pb_system("cd $destdir ; tar xf $path","Extracting $path in $destdir");
2635 } elsif ($mm =~ /\/zip$/) {
2636 # zip
2637 pb_system("cd $destdir ; unzip $path","Extracting $path in $destdir");
2638 }
2639} elsif ($scheme =~ /^cvs/) {
2640 # CVS needs a relative path !
2641 my $dir=dirname($destdir);
2642 my $base=basename($destdir);
2643 # CVS also needs a modules name not a dir
2644 #if (-d $source) {
2645 $tmp1 = basename($source);
2646 #} else {
2647 #$tmp1 = dirname($source);
2648 #$tmp1 = basename($tmp1);
2649 #}
2650 my $optcvs = "";
2651
2652 # If we're working on the CVS itself
2653 my $cvstag = basename($ENV{'PBROOTDIR'});
2654 my $cvsopt = "";
2655 if ($cvstag eq "cvs") {
2656 my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
2657 $cvsopt = "-D \"$pbdate\"";
2658 } else {
2659 # we're working on a tag which should be the last part of PBROOTDIR
2660 $cvsopt = "-r $cvstag";
2661 }
2662 pb_system("cd $dir ; cvs -d $account\@$host:$path export $cvsopt -d $base $tmp1","Exporting $tmp1 from $source under CVS to $destdir");
2663} else {
2664 die "cms $scheme unknown";
2665}
2666}
2667
2668
2669sub pb_create_authors {
2670
2671my $authors=shift;
2672my $dest=shift;
2673my $scheme=shift;
2674
2675return if ($authors eq "/dev/null");
2676open(SAUTH,$authors) || die "Unable to open $authors";
2677# Save a potentially existing AUTHORS file and write instead toi AUTHORS.pb
2678my $ext = "";
2679if (-f "$dest/AUTHORS") {
2680 $ext = ".pb";
2681}
2682open(DAUTH,"> $dest/AUTHORS$ext") || die "Unable to create $dest/AUTHORS$ext";
2683print DAUTH "Authors of the project are:\n";
2684print DAUTH "===========================\n";
2685while (<SAUTH>) {
2686 my ($nick,$gcos) = split(/:/);
2687 chomp($gcos);
2688 print DAUTH "$gcos";
2689 if (defined $scheme) {
2690 # Do not give a scheme for flat types
2691 my $endstr="";
2692 if ("$ENV{'PBREVISION'}" ne "flat") {
2693 $endstr = " under $scheme";
2694 }
2695 print DAUTH " ($nick$endstr)\n";
2696 } else {
2697 print DAUTH "\n";
2698 }
2699}
2700close(DAUTH);
2701close(SAUTH);
2702}
2703
2704sub pb_cms_log {
2705
2706my $scheme = shift;
2707my $pkgdir = shift;
2708my $dest = shift;
2709my $chglog = shift;
2710my $authors = shift;
2711
2712pb_create_authors($authors,$dest,$scheme);
2713
2714if ($scheme =~ /^svn/) {
2715 if (! -f "$dest/ChangeLog") {
2716 if (-x "/usr/bin/svn2cl") {
2717 # In case we have no network, just create an empty one before to allow correct build
2718 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
2719 close(CL);
2720 pb_system("/usr/bin/svn2cl --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN with svn2cl");
2721 } else {
2722 # To be written from pbcl
2723 pb_system("svn log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
2724 }
2725 }
2726} elsif (($scheme eq "file") || ($scheme eq "dir") || ($scheme eq "http") || ($scheme eq "ftp")) {
2727 if (! -f "$dest/ChangeLog") {
2728 pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
2729 }
2730} elsif ($scheme =~ /^cvs/) {
2731 my $tmp=basename($pkgdir);
2732 # CVS needs a relative path !
2733 if (! -f "$dest/ChangeLog") {
2734 if (-x "/usr/bin/cvs2cl") {
2735 # In case we have no network, just create an empty one before to allow correct build
2736 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
2737 close(CL);
2738 pb_system("/usr/bin/cvs2cl --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS with cvs2cl");
2739 } else {
2740 # To be written from pbcl
2741 pb_system("cvs log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
2742 }
2743 }
2744} else {
2745 die "cms $scheme unknown";
2746}
2747}
2748
2749# This function is only called with a real CMS system
2750sub pb_cms_get_uri {
2751
2752my $scheme = shift;
2753my $dir = shift;
2754
2755my $res = "";
2756my $void = "";
2757
2758if ($scheme =~ /^svn/) {
2759 open(PIPE,"LANGUAGE=C svn info $dir |") || return("");
2760 while (<PIPE>) {
2761 ($void,$res) = split(/^URL:/) if (/^URL:/);
2762 }
2763 $res =~ s/^\s*//;
2764 close(PIPE);
2765 chomp($res);
2766} elsif ($scheme =~ /^cvs/) {
2767 # This path is always the root path of CVS, but we may be below
2768 open(FILE,"$dir/CVS/Root") || die "$dir isn't CVS controlled";
2769 $res = <FILE>;
2770 chomp($res);
2771 close(FILE);
2772 # Find where we are in the tree
2773 my $rdir = $dir;
2774 while ((! -d "$rdir/CVSROOT") && ($rdir ne "/")) {
2775 $rdir = dirname($rdir);
2776 }
2777 die "Unable to find a CVSROOT dir in the parents of $dir" if (! -d "$rdir/CVSROOT");
2778 #compute our place under that root dir - should be a relative path
2779 $dir =~ s|^$rdir||;
2780 my $suffix = "";
2781 $suffix = "$dir" if ($dir ne "");
2782
2783 my $prefix = "";
2784 if ($scheme =~ /ssh/) {
2785 $prefix = "cvs+ssh://";
2786 } else {
2787 $prefix = "cvs://";
2788 }
2789 $res = $prefix.$res.$suffix;
2790} else {
2791 die "cms $scheme unknown";
2792}
2793pb_log(2,"Found CMS info: $res\n");
2794return($res);
2795}
2796
2797sub pb_cms_copy {
2798my $scheme = shift;
2799my $oldurl = shift;
2800my $newurl = shift;
2801
2802if ($scheme =~ /^svn/) {
2803 pb_system("svn copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
2804} elsif ($scheme eq "flat") {
2805} elsif ($scheme =~ /^cvs/) {
2806} else {
2807 die "cms $scheme unknown";
2808}
2809}
2810
2811sub pb_cms_checkout {
2812my $scheme = shift;
2813my $url = shift;
2814my $destination = shift;
2815
2816if ($scheme =~ /^svn/) {
2817 pb_system("svn co $url $destination","Checking out $url to $destination ");
2818} elsif (($scheme eq "ftp") || ($scheme eq "http")) {
2819 return;
2820} elsif ($scheme =~ /^cvs/) {
2821 pb_system("cvs co $url $destination","Checking out $url to $destination ");
2822} else {
2823 die "cms $scheme unknown";
2824}
2825}
2826
2827sub pb_cms_up {
2828my $scheme = shift;
2829my $dir = shift;
2830
2831if ($scheme =~ /^svn/) {
2832 pb_system("svn up $dir","Updating $dir");
2833} elsif ($scheme eq "flat") {
2834} elsif ($scheme =~ /^cvs/) {
2835} else {
2836 die "cms $scheme unknown";
2837}
2838}
2839
2840sub pb_cms_checkin {
2841my $scheme = shift;
2842my $dir = shift;
2843
2844my $ver = basename($dir);
2845if ($scheme =~ /^svn/) {
2846 pb_system("svn ci -m \"updated to $ver\" $dir","Checking in $dir");
2847} elsif ($scheme eq "flat") {
2848} elsif ($scheme =~ /^cvs/) {
2849} else {
2850 die "cms $scheme unknown";
2851}
2852pb_cms_up($scheme,$dir);
2853}
2854
2855sub pb_cms_isdiff {
2856my $scheme = shift;
2857my $dir =shift;
2858
2859if ($scheme =~ /^svn/) {
2860 open(PIPE,"svn diff $dir |") || die "Unable to get svn diff from $dir";
2861 my $l = 0;
2862 while (<PIPE>) {
2863 $l++;
2864 }
2865 return($l);
2866} elsif ($scheme eq "flat") {
2867} elsif ($scheme =~ /^cvs/) {
2868 open(PIPE,"cvs diff $dir |") || die "Unable to get svn diff from $dir";
2869 my $l = 0;
2870 while (<PIPE>) {
2871 # Skipping normal messages
2872 next if (/^cvs diff:/);
2873 $l++;
2874 }
2875 return($l);
2876} else {
2877 die "cms $scheme unknown";
2878}
2879}
2880
2881# Get all filters to apply
2882# They're cumulative from less specific to most specific
2883# suffix is .pbf
2884
2885sub pb_get_filters {
2886
2887my @ffiles;
2888my ($ffile00, $ffile0, $ffile1, $ffile2, $ffile3);
2889my ($mfile00, $mfile0, $mfile1, $mfile2, $mfile3);
2890my $pbpkg = shift || die "No package specified";
2891my $dtype = shift || "";
2892my $dfam = shift || "";
2893my $ddir = shift || "";
2894my $dver = shift || "";
2895my $ptr = undef; # returned value pointer on the hash of filters
2896my %h;
2897
2898# Global filter files first, then package specificities
2899if (-d "$ENV{'PBROOTDIR'}/pbfilter") {
2900 $mfile00 = "$ENV{'PBROOTDIR'}/pbfilter/all.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/all.pbf");
2901 $mfile0 = "$ENV{'PBROOTDIR'}/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$dtype.pbf");
2902 $mfile1 = "$ENV{'PBROOTDIR'}/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$dfam.pbf");
2903 $mfile2 = "$ENV{'PBROOTDIR'}/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$ddir.pbf");
2904 $mfile3 = "$ENV{'PBROOTDIR'}/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$ddir-$dver.pbf");
2905
2906 push @ffiles,$mfile00 if (defined $mfile00);
2907 push @ffiles,$mfile0 if (defined $mfile0);
2908 push @ffiles,$mfile1 if (defined $mfile1);
2909 push @ffiles,$mfile2 if (defined $mfile2);
2910 push @ffiles,$mfile3 if (defined $mfile3);
2911}
2912
2913if (-d "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter") {
2914 $ffile00 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/all.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/all.pbf");
2915 $ffile0 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dtype.pbf");
2916 $ffile1 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dfam.pbf");
2917 $ffile2 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir.pbf");
2918 $ffile3 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir-$dver.pbf");
2919
2920 push @ffiles,$ffile00 if (defined $ffile00);
2921 push @ffiles,$ffile0 if (defined $ffile0);
2922 push @ffiles,$ffile1 if (defined $ffile1);
2923 push @ffiles,$ffile2 if (defined $ffile2);
2924 push @ffiles,$ffile3 if (defined $ffile3);
2925}
2926if (@ffiles) {
2927 pb_log(2,"DEBUG ffiles: ".Dumper(\@ffiles)."\n");
2928
2929 foreach my $f (@ffiles) {
2930 open(CONF,$f) || next;
2931 while(<CONF>) {
2932 if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
2933 $h{$1}{$2}=$3;
2934 }
2935 }
2936 close(CONF);
2937
2938 $ptr = $h{"filter"};
2939 pb_log(2,"DEBUG f:".Dumper($ptr)."\n");
2940 }
2941}
2942return($ptr);
2943}
2944
2945# Function which applies filter on pb build files
2946sub pb_filter_file_pb {
2947
2948my $f=shift;
2949my $ptr=shift;
2950my %filter=%$ptr;
2951my $destfile=shift;
2952my $dtype=shift;
2953my $pbsuf=shift;
2954my $pbproj=shift;
2955my $pbpkg=shift;
2956my $pbver=shift;
2957my $pbtag=shift;
2958my $pbrev=shift;
2959my $pbdate=shift;
2960my $defpkgdir = shift;
2961my $extpkgdir = shift;
2962my $pbpackager = shift;
2963my $chglog = shift || undef;
2964
2965pb_log(2,"DEBUG: From $f to $destfile\n");
2966pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
2967open(DEST,"> $destfile") || die "Unable to create $destfile";
2968open(FILE,"$f") || die "Unable to open $f: $!";
2969while (<FILE>) {
2970 my $line = $_;
2971 foreach my $s (keys %filter) {
2972 # Process single variables
2973 pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
2974 my $tmp = $filter{$s};
2975 next if (not defined $tmp);
2976 # Expand variables if any single one found
2977 pb_log(2,"DEBUG tmp: $tmp\n");
2978 if ($tmp =~ /\$/) {
2979 eval { $tmp =~ s/(\$\w+)/$1/eeg };
2980 # special case for ChangeLog only for pb
2981 } elsif (($s =~ /^PBLOG$/) && ($line =~ /^PBLOG$/)) {
2982 my $p = $defpkgdir->{$pbpkg};
2983 $p = $extpkgdir->{$pbpkg} if (not defined $p);
2984 pb_changelog($dtype, $pbpkg, $pbver, $pbtag, $pbsuf, $p, \*DEST, $tmp, $chglog);
2985 $tmp = "";
2986 }
2987 $line =~ s|$s|$tmp|;
2988 }
2989 print DEST $line;
2990}
2991close(FILE);
2992close(DEST);
2993}
2994
2995# Function which applies filter on files (external call)
2996sub pb_filter_file_inplace {
2997
2998my $ptr=shift;
2999my %filter=%$ptr;
3000my $destfile=shift;
3001my $pbproj=shift;
3002my $pbpkg=shift;
3003my $pbver=shift;
3004my $pbtag=shift;
3005my $pbrev=shift;
3006my $pbdate=shift;
3007my $pbpackager=shift;
3008
3009my $cp = "$ENV{'PBTMP'}/".basename($destfile);
3010copy($destfile,$cp) || die "Unable to create $cp";
3011
3012pb_filter_file($cp,$ptr,$destfile,$pbproj,$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$pbpackager);
3013unlink $cp;
3014}
3015
3016# Function which applies filter on files (external call)
3017sub pb_filter_file {
3018
3019my $f=shift;
3020my $ptr=shift;
3021my %filter=%$ptr;
3022my $destfile=shift;
3023my $pbproj=shift;
3024my $pbpkg=shift;
3025my $pbver=shift;
3026my $pbtag=shift;
3027my $pbrev=shift;
3028my $pbdate=shift;
3029my $pbpackager=shift;
3030
3031pb_log(2,"DEBUG: From $f to $destfile\n");
3032pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
3033open(DEST,"> $destfile") || die "Unable to create $destfile";
3034open(FILE,"$f") || die "Unable to open $f: $!";
3035while (<FILE>) {
3036 my $line = $_;
3037 foreach my $s (keys %filter) {
3038 # Process single variables
3039 pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
3040 my $tmp = $filter{$s};
3041 next if (not defined $tmp);
3042 # Expand variables if any single one found
3043 if ($tmp =~ /\$/) {
3044 eval { $tmp =~ s/(\$\w+)/$1/eeg };
3045 }
3046 $line =~ s|$s|$tmp|;
3047 }
3048 print DEST $line;
3049}
3050close(FILE);
3051close(DEST);
3052}
3053
3054#
3055# Return the list of packages we are working on in a CMS action
3056#
3057sub pb_cms_get_pkg {
3058
3059my @pkgs = ();
3060my $defpkgdir = shift || undef;
3061my $extpkgdir = shift || undef;
3062
3063# Get packages list
3064if (not defined $ARGV[0]) {
3065 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
3066} elsif ($ARGV[0] =~ /^all$/) {
3067 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
3068 push(@pkgs, keys %$extpkgdir) if (defined $extpkgdir);
3069} else {
3070 @pkgs = @ARGV;
3071}
3072pb_log(0,"Packages: ".join(',',@pkgs)."\n");
3073return(\@pkgs);
3074}
3075
3076#
3077# Return the list of packages we are working on in a non CMS action
3078#
3079sub pb_get_pkg {
3080
3081my @pkgs = ();
3082
3083my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
3084@pkgs = keys %$var;
3085
3086pb_log(0,"Packages: ".join(',',@pkgs)."\n");
3087return(\@pkgs);
3088}
3089
3090#
3091# Check pbconf/project cms compliance
3092#
3093sub pb_cms_compliant {
3094
3095my $param = shift;
3096my $envar = shift;
3097my $defdir = shift;
3098my $uri = shift;
3099my $pbinit = shift;
3100my %pdir;
3101
3102my ($pdir) = pb_conf_get_if($param) if (defined $param);
3103if (defined $pdir) {
3104 %pdir = %$pdir;
3105}
3106
3107
3108if ((defined $pdir) && (%pdir) && (defined $pdir{$ENV{'PBPROJ'}})) {
3109 # That's always the environment variable that will be used
3110 $ENV{$envar} = $pdir{$ENV{'PBPROJ'}};
3111} else {
3112 if (defined $param) {
3113 pb_log(1,"WARNING: no $param defined, using $defdir\n");
3114 pb_log(1," Please create a $param reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
3115 pb_log(1," if you want to use another directory\n");
3116 }
3117 $ENV{$envar} = "$defdir";
3118}
3119
3120# Expand potential env variable in it
3121eval { $ENV{$envar} =~ s/(\$ENV.+\})/$1/eeg };
3122pb_log(2,"$envar: $ENV{$envar}\n");
3123
3124my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
3125
3126if ((! -d "$ENV{$envar}") || (defined $pbinit)) {
3127 if (defined $pbinit) {
3128 pb_mkdir_p("$ENV{$envar}");
3129 } else {
3130 pb_log(1,"Checking out $uri\n");
3131 pb_cms_checkout($scheme,$uri,$ENV{$envar});
3132 }
3133} elsif (($scheme !~ /^cvs/) || ($scheme !~ /^svn/)) {
3134 # Do not compare if it's not a real cms
3135 return;
3136} else {
3137 pb_log(1,"$uri found locally, checking content\n");
3138 my $cmsurl = pb_cms_get_uri($scheme,$ENV{$envar});
3139 my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
3140 if ($cmsurl ne $uri) {
3141 # The local content doesn't correpond to the repository
3142 pb_log(0,"ERROR: Inconsistency detected:\n");
3143 pb_log(0," * $ENV{$envar} refers to $cmsurl but\n");
3144 pb_log(0," * $ENV{'PBETC'} refers to $uri\n");
3145 die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
3146 } else {
3147 pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
3148 # they match - do nothing - there may be local changes
3149 }
3150}
3151}
3152
3153sub pb_changelog {
3154
3155my $dtype = shift;
3156my $pkg = shift;
3157my $pbver = shift;
3158my $pbtag = shift;
3159my $dsuf = shift;
3160my $path = shift;
3161my $OUTPUT = shift;
3162my $doit = shift;
3163my $chglog = shift || undef;
3164
3165my $log = "";
3166
3167# For date handling
3168$ENV{LANG}="C";
3169
3170if ((not (defined $dtype)) || ($dtype eq "") ||
3171 (not (defined $pkg)) || ($pkg eq "") ||
3172 (not (defined $pbver)) || ($pbver eq "") ||
3173 (not (defined $pbtag)) || ($pbtag eq "") ||
3174 (not (defined $dsuf)) || ($dsuf eq "") ||
3175 (not (defined $path)) || ($path eq "") ||
3176 (not (defined $OUTPUT)) || ($OUTPUT eq "") ||
3177 (not (defined $doit)) || ($doit eq "")) {
3178 print $OUTPUT "\n";
3179 return;
3180}
3181
3182if (((not defined $chglog) || (! -f $chglog)) && ($doit eq "yes")) {
3183 #pb_log(2,"No ChangeLog file ($chglog) for $pkg\n";
3184 print $OUTPUT "\n";
3185 return;
3186}
3187
3188my $date;
3189my $ndate;
3190my $n2date;
3191my $ver;
3192my $ver2;
3193my ($pbpackager) = pb_conf_get("pbpackager");
3194
3195if (not defined $pbpackager->{$ENV{'PBPROJ'}}) {
3196 $pbpackager->{$ENV{'PBPROJ'}} = "undefined\@noproject.noorg";
3197}
3198
3199# If we don't need to do it, or don't have it fake something
3200if (((not defined $chglog) || (! -f $chglog)) && ($doit ne "yes")) {
3201 my @date=(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
3202 $date = strftime("%Y-%m-%d", @date);
3203 $ndate = UnixDate($date,"%a", "%b", "%d", "%Y");
3204 $n2date = &UnixDate($date,"%a, %d %b %Y %H:%M:%S %z");
3205 if (($dtype eq "rpm") || ($dtype eq "fc")) {
3206 $ver2 = "$pbver-$pbtag$dsuf";
3207 print $OUTPUT "* $ndate $pbpackager->{$ENV{'PBPROJ'}} $ver2\n";
3208 print $OUTPUT "- Updated to $pbver\n";
3209 }
3210 if ($dtype eq "deb") {
3211 print $OUTPUT "$pkg ($pbver) unstable; urgency=low\n";
3212 print $OUTPUT "\n";
3213 print $OUTPUT " -- $pbpackager->{$ENV{'PBPROJ'}} $n2date\n\n\n";
3214 }
3215 return;
3216}
3217
3218open(INPUT,"$chglog") || die "Unable to open $chglog (read)";
3219
3220# Skip first 4 lines
3221my $tmp = <INPUT>;
3222$tmp = <INPUT>;
3223$tmp = <INPUT>;
3224if ($dtype eq "announce") {
3225 print $OUTPUT $tmp;
3226}
3227$tmp = <INPUT>;
3228if ($dtype eq "announce") {
3229 print $OUTPUT $tmp;
3230}
3231
3232my $first=1;
3233
3234# Handle each block separated by newline
3235while (<INPUT>) {
3236 ($ver, $date) = split(/ /);
3237 $ver =~ s/^v//;
3238 chomp($date);
3239 $date =~ s/\(([0-9-]+)\)/$1/;
3240 #pb_log(2,"**$date**\n";
3241 $ndate = UnixDate($date,"%a", "%b", "%d", "%Y");
3242 $n2date = &UnixDate($date,"%a, %d %b %Y %H:%M:%S %z");
3243 #pb_log(2,"**$ndate**\n";
3244
3245 if (($dtype eq "rpm") || ($dtype eq "fc")) {
3246 if ($ver !~ /-/) {
3247 if ($first eq 1) {
3248 $ver2 = "$ver-$pbtag$dsuf";
3249 $first=0;
3250 } else {
3251 $ver2 = "$ver-1$dsuf";
3252 }
3253 } else {
3254 $ver2 = "$ver$dsuf";
3255 }
3256 print $OUTPUT "* $ndate $pbpackager->{$ENV{'PBPROJ'}} $ver2\n";
3257 print $OUTPUT "- Updated to $ver\n";
3258 }
3259 if ($dtype eq "deb") {
3260 print $OUTPUT "$pkg ($ver) unstable; urgency=low\n";
3261 print $OUTPUT "\n";
3262 }
3263
3264 $tmp = <INPUT>;
3265 while ($tmp !~ /^$/) {
3266 if ($dtype eq "deb") {
3267 $tmp =~ s/^- //;
3268 print $OUTPUT " * $tmp";
3269 } elsif ($dtype eq "rpm") {
3270 print $OUTPUT "$tmp";
3271 } else {
3272 print $OUTPUT "$tmp";
3273 }
3274 last if (eof(INPUT));
3275 $tmp = <INPUT>;
3276 }
3277 print $OUTPUT "\n";
3278
3279 if ($dtype eq "deb") {
3280 # Cf: http://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog
3281 print $OUTPUT " -- $pbpackager->{$ENV{'PBPROJ'}} $n2date\n\n\n";
3282 }
3283
3284 last if (eof(INPUT));
3285 last if ($dtype eq "announce");
3286}
3287close(INPUT);
3288}
32891;
Note: See TracBrowser for help on using the repository browser.