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

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

Split again function in modules to allow for usage with pbinit and easier reuse.

  • Property svn:executable set to *
File size: 76.0 KB
Line 
1#!/usr/bin/perl -w
2#
3# Project Builder main application
4#
5# $Id$
6#
7# Copyright B. Cornec 2007
8# Provided under the GPL v2
9
10# Syntax: see at end
11
12use strict 'vars';
13use Getopt::Long qw(:config auto_abbrev no_ignore_case);
14use Data::Dumper;
15use English;
16use File::Basename;
17use File::Copy;
18use File::stat;
19use File::Temp qw(tempdir);
20use POSIX qw(strftime);
21use lib qw (lib);
22use ProjectBuilder::Version;
23use ProjectBuilder::Base;
24use ProjectBuilder::Conf;
25use ProjectBuilder::Distribution;
26use ProjectBuilder::CMS;
27use ProjectBuilder::Filter;
28
29# Global variables
30my %opts; # CLI Options
31my $action; # action to realize
32my $test = "FALSE"; # Not used
33my $force = 0; # Force VE/VM rebuild
34my $option = ""; # Not used
35my @pkgs; # list of packages
36my $pbtag; # Global Tag variable
37my $pbver; # Global Version variable
38my $pbscript; # Name of the script
39my %pbver; # per package
40my %pbtag; # per package
41my $pbrev; # Global REVISION variable
42my $pbaccount; # Login to use to connect to the VM
43my $pbport; # Port to use to connect to the VM
44my $newver; # New version to create
45my $iso; # ISO image for the VM to create
46
47my @date = pb_get_date();
48my $pbdate = strftime("%Y-%m-%d", @date);
49
50=pod
51
52=head1 NAME
53
54pb, aka project-builder.org - builds packages for your projects
55
56=head1 DESCRIPTION
57
58pb helps you build various packages directly from your project sources.
59Those sources could be handled by a CMS (Configuration Management System)
60such as Subversion, CVS, ... or being a simple reference to a compressed tar file.
61It's based on a set of configuration files, a set of provided macros to help
62you keeping build files as generic as possible. For example, a single .spec
63file should be required to generate for all rpm based distributions, even
64if you could also have multiple .spec files if required.
65
66=head1 SYNOPSIS
67
68pb [-vhq][-r pbroot][-p project][[-s script -a account -P port][-m mach-1[,...]]][-i iso] <action> [<pkg1> ...]
69
70pb [--verbose][--help][--man][--quiet][--revision pbroot][--project project][[--script script --account account --port port][--machine mach-1[,...]]][--iso iso] <action> [<pkg1> ...]
71
72=head1 OPTIONS
73
74=over 4
75
76=item B<-v|--verbose>
77
78Print a brief help message and exits.
79
80=item B<-q|--quiet>
81
82Do not print any output.
83
84=item B<-h|--help>
85
86Print a brief help message and exits.
87
88=item B<--man>
89
90Prints the manual page and exits.
91
92=item B<-m|--machine machine1[,machine2,...]>
93
94Name of the Virtual Machines (VM) or Virtual Environments (VE) you want to build on (coma separated).
95All if none precised (or use the env variable PBV).
96
97=item B<-s|--script script>
98
99Name of the script you want to execute on the related VMs or VEs.
100
101=item B<-i|--iso iso_image>
102
103Name of the ISO image of the distribution you want to install on the related VMs.
104
105=item B<-a|--account account>
106
107Name of the account to use to connect on the related VMs.
108
109=item B<-P|--port port_number>
110
111Port number to use to connect on the related VMs.\n";
112
113=item B<-p|--project project_name>
114
115Name of the project you're working on (or use the env variable PBPROJ)
116
117=item B<-r|--revision revision>
118
119Path Name of the project revision under the CMS (or use the env variable PBROOT)
120
121=item B<-V|--version new_version>
122
123New version of the project to create based on the current one.
124
125=back
126
127=head1 ARGUMENTS
128
129<action> can be:
130
131=over 4
132
133=item B<cms2build>
134
135Create tar files for the project under your CMS.
136CMS supported are SVN and CVS
137parameters are packages to build
138if not using default list
139
140=item B<build2pkg>
141
142Create packages for your running distribution
143
144=item B<cms2pkg>
145
146cms2build + build2pkg
147
148=item B<build2ssh>
149
150Send the tar files to a SSH host
151
152=item B<cms2ssh>
153
154cms2build + build2ssh
155
156=item B<pkg2ssh>
157
158Send the packages built to a SSH host
159
160=item B<build2vm>
161
162Create packages in VMs, launching them if needed
163and send those packages to a SSH host once built
164VM type supported are QEMU
165
166=item B<build2ve>
167
168Create packages in VEs, creating it if needed
169and send those packages to a SSH host once built
170
171=item B<cms2vm>
172
173cms2build + build2vm
174
175=item B<cms2ve>
176
177cms2build + build2ve
178
179=item B<launchvm>
180
181Launch one virtual machine
182
183=item B<launchve>
184
185Launch one virtual environment
186
187=item B<script2vm>
188
189Launch one virtual machine if needed
190and executes a script on it
191
192=item B<script2ve>
193
194Execute a script in a virtual environment
195
196=item B<newvm>
197
198Create a new virtual machine
199
200=item B<newve>
201
202Create a new virtual environment
203
204=item B<setupvm>
205
206Setup a virtual machine for pb usage
207
208=item B<setupve>
209
210Setup a virtual environment for pb usage
211
212=item B<newver>
213
214Create a new version of the project derived
215from the current one
216
217=item B<newproj>
218
219Create a new project and a template set of
220configuration files under pbconf
221
222=back
223
224<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).
225
226=head1 WEB SITES
227
228The 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/>.
229
230=head1 USER MAILING LIST
231
232None exists for the moment.
233
234=head1 CONFIGURATION FILES
235
236Each pb user may have a configuration in F<$HOME/.pbrc>. The values in this file may overwrite any other configuration file value.
237
238Here is an example of such a configuration file:
239
240 #
241 # Define for each project the URL of its pbconf repository
242 # No default option allowed here as they need to be all different
243 #
244 # URL of the pbconf content
245 # This is the format of a classical URL with the extension of additional schema such as
246 # svn+ssh, cvs+ssh, ...
247 #
248 pbconfurl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe/pbconf
249
250 # This is normaly defined in the project's configuration file
251 # Url of the project
252 #
253 pburl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe
254
255 # All these URLs needs to be defined here as the are the entry point
256 # for how to build packages for the project
257 #
258 pbconfurl pb = svn+ssh://svn.project-builder.org/mondo/svn/pb/pbconf
259 pbconfurl mondorescue = svn+ssh://svn.project-builder.org/mondo/svn/project-builder/mondorescue/pbconf
260 pbconfurl collectl = svn+ssh://bruno@svn.mondorescue.org/mondo/svn/project-builder/collectl/pbconf
261 pbconfurl netperf = svn+ssh://svn.mondorescue.org/mondo/svn/project-builder/netperf/pbconf
262
263 # Under that dir will take place everything related to pb
264 # If you want to use VMs/chroot/..., then use $ENV{'HOME'} to make it portable
265 # to your VMs/chroot/...
266 # if not defined then /var/cache
267 pbdefdir default = $ENV{'HOME'}/project-builder
268 pbdefdir pb = $ENV{'HOME'}
269 pbdefdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
270 pbdefdir mondorescue = $ENV{'HOME'}/mondo/svn
271
272 # pbconfdir points to the directory where the CMS content of the pbconfurl is checked out
273 # If not defined, pbconfdir is under pbdefdir/pbproj/pbconf
274 pbconfdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs/pbconf
275 pbconfdir mondorescue = $ENV{'HOME'}/mondo/svn/pbconf
276
277 # pbdir points to the directory where the CMS content of the pburl is checked out
278 # If not defined, pbdir is under pbdefdir/pbproj
279 # Only defined if we have access to the dev of the project
280 pbdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
281 pbdir mondorescue = $ENV{'HOME'}/mondo/svn
282
283 # -daemonize doesn't work with qemu 0.8.2
284 vmopt default = -m 384
285
286=head1 AUTHORS
287
288The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
289
290=head1 COPYRIGHT
291
292Project-Builder.org is distributed under the GPL v2.0 license
293described in the file C<COPYING> included with the distribution.
294
295=cut
296
297# ---------------------------------------------------------------------------
298
299# Old syntax
300#getopts('a:fhi:l:m:P:p:qr:s:vV:',\%opts);
301
302my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
303
304# Initialize the syntax string
305
306pb_syntax_init("pb (aka project-builder.org) Version $projectbuilderver-$projectbuilderrev\n");
307
308GetOptions("help|?|h" => \$opts{'h'},
309 "man" => \$opts{'man'},
310 "verbose|v+" => \$opts{'v'},
311 "quiet|q" => \$opts{'q'},
312 "log-files|l=s" => \$opts{'l'},
313 "force|f" => \$opts{'f'},
314 "account|a=s" => \$opts{'a'},
315 "revision|r=s" => \$opts{'r'},
316 "script|s=s" => \$opts{'s'},
317 "machines|mock|m=s" => \$opts{'m'},
318 "port|P=i" => \$opts{'P'},
319 "project|p=s" => \$opts{'p'},
320 "iso|i=s" => \$opts{'i'},
321 "version|V=s" => \$opts{'V'},
322) || pb_syntax(-1,0);
323
324if (defined $opts{'h'}) {
325 pb_syntax(0,1);
326}
327if (defined $opts{'man'}) {
328 pb_syntax(0,2);
329}
330if (defined $opts{'v'}) {
331 $debug = $opts{'v'};
332 pb_log(0,"Debug value: $debug\n");
333}
334if (defined $opts{'f'}) {
335 $force=1;
336}
337if (defined $opts{'q'}) {
338 $debug=-1;
339}
340if (defined $opts{'l'}) {
341 open(LOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
342 $LOG = \*LOG;
343 $debug = 0 if ($debug == -1);
344 }
345pb_log_init($debug, $LOG);
346
347# Handle root of the project if defined
348if (defined $opts{'r'}) {
349 $ENV{'PBROOTDIR'} = $opts{'r'};
350}
351# Handle virtual machines if any
352if (defined $opts{'m'}) {
353 $ENV{'PBV'} = $opts{'m'};
354}
355if (defined $opts{'s'}) {
356 $pbscript = $opts{'s'};
357}
358if (defined $opts{'a'}) {
359 $pbaccount = $opts{'a'};
360 die "option -a requires a -s script option" if (not defined $pbscript);
361}
362if (defined $opts{'P'}) {
363 $pbport = $opts{'P'};
364}
365if (defined $opts{'V'}) {
366 $newver = $opts{'V'};
367}
368if (defined $opts{'i'}) {
369 $iso = $opts{'i'};
370}
371
372# Get Action
373$action = shift @ARGV;
374die pb_syntax(-1,1) if (not defined $action);
375
376my ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir);
377my $pbinit = undef;
378$pbinit = 1 if ($action =~ /^newproj$/);
379
380# Handles project name if any
381# And get global params
382($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) = pb_env_init($opts{'p'},$pbinit,$action);
383
384pb_log(0,"Project: $ENV{'PBPROJ'}\n");
385pb_log(0,"Action: $action\n");
386
387# Act depending on action
388if ($action =~ /^cms2build$/) {
389 pb_cms2build();
390} elsif ($action =~ /^build2pkg$/) {
391 pb_build2pkg();
392} elsif ($action =~ /^cms2pkg$/) {
393 pb_cms2build();
394 pb_build2pkg();
395} elsif ($action =~ /^build2ssh$/) {
396 pb_build2ssh();
397} elsif ($action =~ /^cms2ssh$/) {
398 pb_cms2build();
399 pb_build2ssh();
400} elsif ($action =~ /^pkg2ssh$/) {
401 pb_pkg2ssh();
402} elsif ($action =~ /^build2ve$/) {
403 pb_build2v("ve");
404} elsif ($action =~ /^build2vm$/) {
405 pb_build2v("vm");
406} elsif ($action =~ /^cms2ve$/) {
407 pb_cms2build();
408 pb_build2v("ve");
409} elsif ($action =~ /^cms2vm$/) {
410 pb_cms2build();
411 pb_build2v("vm");
412} elsif ($action =~ /^launchvm$/) {
413 pb_launchv("vm",$ENV{'PBV'},0);
414} elsif ($action =~ /^launchve$/) {
415 pb_launchv("ve",$ENV{'PBV'},0);
416} elsif ($action =~ /^script2vm$/) {
417 pb_script2v($pbscript,"vm");
418} elsif ($action =~ /^script2ve$/) {
419 pb_script2v($pbscript,"ve");
420} elsif ($action =~ /^newver$/) {
421 pb_newver();
422} elsif ($action =~ /^newve$/) {
423 pb_launchv("ve",$ENV{'PBV'},1);
424} elsif ($action =~ /^newvm$/) {
425 pb_launchv("vm",$ENV{'PBV'},1);
426} elsif ($action =~ /^setupve$/) {
427 pb_setup_v("ve");
428} elsif ($action =~ /^setupvm$/) {
429 pb_setup_v("vm");
430} elsif ($action =~ /^newproj$/) {
431 # Nothing to do - already done in pb_env_init
432} elsif ($action =~ /^clean$/) {
433} else {
434 pb_log(0,"\'$action\' is not available\n");
435 pb_syntax(-2,1);
436}
437
438sub pb_cms2build {
439
440 my $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
441 my @pkgs = @$pkg;
442 my %pkgs;
443
444 my ($scheme, $uri) = pb_cms_init($pbinit);
445
446 my ($pkgv, $pkgt) = pb_conf_get_if("pkgver","pkgtag");
447
448 # declare packager for filtering
449 my ($tmp) = pb_conf_get("pbpackager");
450 $ENV{'PBPACKAGER'} = $tmp->{$ENV{'PBPROJ'}};
451
452 foreach my $pbpkg (@pkgs) {
453 $ENV{'PBPKG'} = $pbpkg;
454 if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
455 $pbver = $pkgv->{$pbpkg};
456 } else {
457 $pbver = $ENV{'PBPROJVER'};
458 }
459 if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
460 $pbtag = $pkgt->{$pbpkg};
461 } else {
462 $pbtag = $ENV{'PBPROJTAG'};
463 }
464
465 $pbrev = $ENV{'PBREVISION'};
466 pb_log(0,"\n");
467 pb_log(0,"Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n");
468 die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
469 # Clean up dest if necessary. The export will recreate it
470 my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver";
471 pb_rm_rf($dest) if (-d $dest);
472
473 # Export CMS tree for the concerned package to dest
474 # And generate some additional files
475 $OUTPUT_AUTOFLUSH=1;
476
477 # computes in which dir we have to work
478 my $dir = $defpkgdir->{$pbpkg};
479 $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
480 pb_log(2,"def:".Dumper($defpkgdir)." ext: ".Dumper($extpkgdir)." \n");
481
482 # Exporting from CMS
483 pb_cms_export($uri,"$ENV{'PBDIR'}/$dir",$dest);
484
485 # Get project info on authors and log file
486 my $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
487 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
488 $chglog = undef if (! -f $chglog);
489
490 my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
491 $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
492 $authors = "/dev/null" if (! -f $authors);
493
494 # Extract cms log history and store it
495 if ((defined $chglog) && (! -f "$dest/NEWS")) {
496 pb_log(2,"Generating NEWS file from $chglog\n");
497 copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
498 }
499 pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors);
500
501 my %build;
502
503 my @pt;
504 @pt = pb_conf_get_if("vmlist","velist");
505 my $tmpl = "";
506 if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
507 $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
508 }
509 if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
510 # the 2 lists needs to be grouped with a ',' separated them
511 if ($tmpl ne "") {
512 $tmpl .= ",";
513 }
514 $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
515 }
516 foreach my $d (split(/,/,$tmpl)) {
517 my ($name,$ver,$arch) = split(/-/,$d);
518 chomp($arch);
519 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
520 pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n");
521 pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
522
523 # Filter build files from the less precise up to the most with overloading
524 # Filter all files found, keeping the name, and generating in dest
525
526 # Find all build files first relatively to PBROOTDIR
527 # Find also all specific files referenced in the .pb conf file
528 my %bfiles = ();
529 my %pkgfiles = ();
530 $build{"$ddir-$dver"} = "yes";
531
532 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dtype") {
533 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dtype",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
534 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dfam") {
535 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
536 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir") {
537 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
538 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver") {
539 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
540 } else {
541 $build{"$ddir-$dver"} = "no";
542 next;
543 }
544 pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
545
546 # Get all filters to apply
547 my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
548
549 # Apply now all the filters on all the files concerned
550 # destination dir depends on the type of file
551 if (defined $ptr) {
552 foreach my $f (values %bfiles,values %pkgfiles) {
553 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);
554 }
555 }
556 }
557 my @found;
558 my @notfound;
559 foreach my $b (keys %build) {
560 push @found,$b if ($build{$b} =~ /yes/);
561 push @notfound,$b if ($build{$b} =~ /no/);
562 }
563 pb_log(0,"Build files generated for ".join(',',@found)."\n");
564 pb_log(0,"No Build files found for ".join(',',@notfound)."\n") if (@notfound);
565 # Get the generic filter (all.pbf) and
566 # apply those to the non-build files including those
567 # generated by pbinit if applicable
568
569 # Get only all.pbf filter
570 my $ptr = pb_get_filters($pbpkg);
571
572 my $liste ="";
573 if (defined $filteredfiles->{$pbpkg}) {
574 foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
575 pb_filter_file_inplace($ptr,"$dest/$f",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'});
576 $liste = "$f $liste";
577 }
578 }
579 pb_log(2,"Files ".$liste."have been filtered\n");
580
581 # Prepare the dest directory for archive
582 if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
583 pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'});
584 chmod 0755,"$ENV{'PBTMP'}/pbinit";
585 pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit");
586 }
587
588 # Archive dest dir
589 chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
590 # Possibility to look at PBSRC to guess more the filename
591 pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
592 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
593
594 # Keep track of version-tag per pkg
595 $pkgs{$pbpkg} = "$pbver-$pbtag";
596
597 # Final cleanup
598 pb_rm_rf($dest) if (-d $dest);
599 }
600
601 # Keep track of per package version
602 pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
603 open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
604 foreach my $pbpkg (@pkgs) {
605 print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
606 }
607 close(PKG);
608
609 # Keep track of what is generated by default
610 # We need to store the dir and info on version-tag
611 # Base our content on the existing .pb file
612 copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
613 open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
614 print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
615 print LAST "pbprojver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
616 print LAST "pbprojtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
617 print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
618 close(LAST);
619}
620
621sub pb_build2pkg {
622
623 # Get the running distro to build on
624 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
625 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
626
627 # Get list of packages to build
628 # Get content saved in cms2build
629 my $ptr = pb_get_pkg();
630 @pkgs = @$ptr;
631
632 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
633 $pkg = { } if (not defined $pkg);
634
635 chdir "$ENV{'PBBUILDDIR'}";
636 my $made = ""; # pkgs made during build
637 foreach my $pbpkg (@pkgs) {
638 my $vertag = $pkg->{$pbpkg};
639 # get the version of the current package - maybe different
640 ($pbver,$pbtag) = split(/-/,$vertag);
641
642 my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
643 pb_log(2,"Source file: $src\n");
644
645 pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
646 if ($dtype eq "rpm") {
647 foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
648 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
649 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";
650 }
651 }
652
653 # Remove in case a previous link/file was there
654 unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
655 symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
656 # We need to first extract the spec file
657 my @specfile;
658 @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
659
660 pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
661 # set LANGUAGE to check for correct log messages
662 $ENV{'LANGUAGE'}="C";
663 foreach my $f (@specfile) {
664 if ($f =~ /\.spec$/) {
665 pb_system("rpmbuild --define \'packager $ENV{'PBPACKAGER'}\' --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
666 last;
667 }
668 }
669 $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
670 if (-f "/usr/bin/rpmlint") {
671 pb_system("rpmlint $made","Checking validity of rpms with rpmlint");
672 }
673 } elsif ($dtype eq "deb") {
674 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
675 pb_system("tar xfz $src","Extracting sources");
676
677 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
678 pb_rm_rf("debian");
679 symlink "pbconf/$ddir-$dver","debian" || die "Unable to symlink to pbconf/$ddir-$dver";
680 chmod 0755,"debian/rules";
681 pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package");
682 $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
683 if (-f "/usr/bin/lintian") {
684 pb_system("lintian $made","Checking validity of debs with lintian");
685 }
686 } elsif ($dtype eq "ebuild") {
687 my @ebuildfile;
688 # For gentoo we need to take pb as subsystem name
689 # We put every apps here under sys-apps. hope it's correct
690 # We use pb's home dir in order o have a single OVERLAY line
691 my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
692 pb_mkdir_p($tmpd) if (! -d "$tmpd");
693 pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
694
695 # We need to first extract the ebuild file
696 @ebuildfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$tmpd");
697
698 # Prepare the build env for gentoo
699 my $found = 0;
700 my $pbbd = $ENV{'HOME'};
701 $pbbd =~ s|/|\\/|g;
702 if (-r "/etc/make.conf") {
703 open(MAKE,"/etc/make.conf");
704 while (<MAKE>) {
705 $found = 1 if (/$pbbd\/portage/);
706 }
707 close(MAKE);
708 }
709 if ($found == 0) {
710 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
711 }
712 #$found = 0;
713 #if (-r "/etc/portage/package.keywords") {
714 #open(KEYW,"/etc/portage/package.keywords");
715 #while (<KEYW>) {
716 #$found = 1 if (/portage\/pb/);
717 #}
718 #close(KEYW);
719 #}
720 #if ($found == 0) {
721 #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
722 #}
723
724 # Build
725 foreach my $f (@ebuildfile) {
726 if ($f =~ /\.ebuild$/) {
727 move($f,"$tmpd/$pbpkg-$pbver.ebuild");
728 pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package");
729 # Now move it where pb expects it
730 pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
731 move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
732 }
733 }
734
735 $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver.ebuild";
736 } elsif ($dtype eq "slackware") {
737 $made="$made build-$pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
738 pb_mkdir_p("$ENV{'PBBUILDDIR'}/install") if (! -d "$ENV{'PBBUILDDIR'}/install");
739 } else {
740 die "Unknown dtype format $dtype";
741 }
742 }
743 # Keep track of what is generated so that we can get them back from VMs
744 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
745 print KEEP "$made\n";
746 close(KEEP);
747}
748
749sub pb_build2ssh {
750 pb_send2target("Sources");
751}
752
753sub pb_pkg2ssh {
754 pb_send2target("Packages");
755}
756
757# By default deliver to the the public site hosting the
758# ftp structure (or whatever) or a VM/VE
759sub pb_send2target {
760
761 my $cmt = shift;
762 my $v = shift || undef;
763 my $vmexist = shift || 0; # 0 is FALSE
764 my $vmpid = shift || 0; # 0 is FALSE
765
766 my $host = "sshhost";
767 my $login = "sshlogin";
768 my $dir = "sshdir";
769 my $port = "sshport";
770 my $tmout = "sshtmout";
771 my $path = "sshpath";
772 my $conf = "sshconf";
773 my $rebuild = "sshrebuild";
774 if (($cmt eq "vm") || ($cmt eq "Script")) {
775 $login = "vmlogin";
776 $dir = "pbdefdir";
777 $tmout = "vmtmout";
778 $rebuild = "vmrebuild";
779 # Specific VM
780 $host = "vmhost";
781 $port = "vmport";
782 } elsif ($cmt eq "ve") {
783 $login = "velogin";
784 $dir = "pbdefdir";
785 $tmout = "vetmout";
786 # Specific VE
787 $path = "vepath";
788 $conf = "veconf";
789 $rebuild = "verebuild";
790 }
791 my $cmd = "";
792
793 my $ptr = pb_get_pkg();
794 @pkgs = @$ptr;
795
796 # Get the running distro to consider
797 my ($odir,$over,$oarch) = (undef, undef, undef);
798 if (defined $v) {
799 ($odir,$over,$oarch) = split(/-/,$v);
800 }
801 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
802 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
803
804 # Get list of packages to build
805 # Get content saved in cms2build
806 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
807 $pkg = { } if (not defined $pkg);
808
809 my $src = "";
810 chdir "$ENV{'PBBUILDDIR'}";
811 foreach my $pbpkg (@pkgs) {
812 my $vertag = $pkg->{$pbpkg};
813 # get the version of the current package - maybe different
814 ($pbver,$pbtag) = split(/-/,$vertag);
815
816 if (($cmt eq "Sources") || ($cmt eq "vm") || ($cmt eq "ve")) {
817 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
818 if ($cmd eq "") {
819 $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
820 } else {
821 $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
822 }
823 }
824 }
825 if (($cmt eq "vm") || ($cmt eq "ve")) {
826 $src="$src $ENV{'PBDESTDIR'}/pbscript $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc";
827 } elsif ($cmt eq "Script") {
828 $src="$src $ENV{'PBDESTDIR'}/pbscript";
829 } elsif ($cmt eq "Packages") {
830 # Get package list from file made during build2pkg
831 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
832 $src = <KEEP>;
833 chomp($src);
834 close(KEEP);
835 if ($dtype eq "rpm") {
836 # Also make a pbscript to generate yum/urpmi bases
837 # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
838 } elsif ($dtype eq "deb") {
839 # Also make a pbscript to generate apt bases
840 # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
841 }
842 }
843 # Remove potential leading spaces (cause problem with basename)
844 $src =~ s/^ *//;
845 my $basesrc = "";
846 foreach my $i (split(/ +/,$src)) {
847 $basesrc .= " ".basename($i);
848 }
849
850 pb_log(0,"Sources handled ($cmt): $src\n");
851 pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf))."\n");
852 my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf) = pb_conf_get($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf);
853 pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
854 # Not mandatory
855 my ($testver) = pb_conf_get_if("testver");
856
857 my $mac;
858 # Useless for VE
859 if ($cmt ne "ve") {
860 $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
861 # Overwrite account value if passed as parameter
862 $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
863 pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
864 }
865
866 my $tdir;
867 my $bdir;
868 if (($cmt eq "Sources") || ($cmt eq "Script")) {
869 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
870 } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
871 $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
872 $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
873 # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
874 $bdir =~ s|\$ENV.+\}/||;
875 } elsif ($cmt eq "Packages") {
876 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
877 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
878 # This is a test pkg => target dir is under test
879 $tdir .= "/test";
880 }
881 } else {
882 return;
883 }
884
885 # Useless for VE
886 my $nport;
887 if ($cmt ne "ve") {
888 $nport = $sshport->{$ENV{'PBPROJ'}};
889 $nport = "$pbport" if (defined $pbport);
890 }
891
892 # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
893 $tdir =~ s|\$ENV.+\}/||;
894
895 my $tm = $vtmout->{$ENV{'PBPROJ'}};
896
897 # ssh communication if not VE
898 # should use a hash instead...
899 my ($shcmd,$cpcmd,$cptarget,$cp2target);
900 if ($cmt ne "ve") {
901 my $keyfile = pb_ssh_get(0);
902 $shcmd = "ssh -i $keyfile -q -p $nport $mac";
903 $cpcmd = "scp -i $keyfile -p -P $nport";
904 $cptarget = "$mac:$tdir";
905 if ($cmt eq "vm") {
906 $cp2target = "$mac:$bdir";
907 }
908 } else {
909 my $tp = $vepath->{$ENV{'PBPROJ'}};
910 $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
911 $cpcmd = "cp -a ";
912 $cptarget = "$tp/$tdir";
913 $cp2target = "$tp/$bdir";
914 }
915
916 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");
917 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
918 # For VE we need to change the owner manually - To be tested if needed
919 #if ($cmt eq "ve") {
920 #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
921 #}
922 pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi\' | bash\"","Executing pbscript on $cptarget if needed");
923 if (($cmt eq "vm") || ($cmt eq "ve")) {
924 # Get back info on pkg produced, compute their name and get them from the VM
925 pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
926 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
927 my $src = <KEEP>;
928 chomp($src);
929 close(KEEP);
930 $src =~ s/^ *//;
931 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
932 # Change pgben to make the next send2target happy
933 my $made = "";
934 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
935 foreach my $p (split(/ +/,$src)) {
936 my $j = basename($p);
937 pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
938 $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
939 }
940 print KEEP "$made\n";
941 close(KEEP);
942 pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
943
944 # We want to send them to the ssh account so overwrite what has been done before
945 undef $pbaccount;
946 pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
947 pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
948 if ((! $vmexist) && ($cmt eq "vm")) {
949 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)");
950 }
951 pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
952 }
953}
954
955sub pb_script2v {
956 my $pbscript=shift;
957 my $vtype=shift;
958
959 # Prepare the script to be executed on the VM
960 # in $ENV{'PBDESTDIR'}/pbscript
961 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
962 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
963 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
964 }
965
966 my ($vm,$all) = pb_get_v($vtype);
967 my ($vmexist,$vmpid) = (undef,undef);
968
969 foreach my $v (@$vm) {
970 # Launch the VM/VE
971 if ($vtype eq "vm") {
972 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
973
974 # Skip that VM if something went wrong
975 next if (($vmpid == 0) && ($vmexist ==0));
976 }
977
978 # Gather all required files to send them to the VM
979 # and launch the build through pbscript
980 pb_send2target("Script","$v",$vmexist,$vmpid);
981
982 }
983}
984
985sub pb_launchv {
986 my $vtype = shift;
987 my $v = shift;
988 my $create = shift || 0; # By default do not create a VM
989
990 die "No VM/VE defined, unable to launch" if (not defined $v);
991 # Keep only the first VM in case many were given
992 $v =~ s/,.*//;
993
994 # Which is our local arch ? (standardize on i386 for those platforms)
995 my $arch = `uname -m`;
996 chomp($arch);
997 $arch =~ s/i.86/i386/;
998
999 # Launch the VMs/VEs
1000 if ($vtype eq "vm") {
1001 die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
1002
1003 my ($ptr,$vmopt,$vmport,$vmpath,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmport","vmpath","vmtmout","vmsize");
1004
1005 my $vmtype = $ptr->{$ENV{'PBPROJ'}};
1006 if (not defined $ENV{'PBVMOPT'}) {
1007 $ENV{'PBVMOPT'} = "";
1008 }
1009 if (defined $vmopt->{$ENV{'PBPROJ'}}) {
1010 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
1011 }
1012 my $nport = $vmport->{$ENV{'PBPROJ'}};
1013 $nport = "$pbport" if (defined $pbport);
1014
1015 my $cmd;
1016 my $vmcmd; # has to be used for pb_check_ps
1017 my $vmm; # has to be used for pb_check_ps
1018 if ($vmtype eq "qemu") {
1019 my $qemucmd32;
1020 my $qemucmd64;
1021 if ($arch eq "x86_64") {
1022 $qemucmd32 = "/usr/bin/qemu-system-i386";
1023 $qemucmd64 = "/usr/bin/qemu";
1024 } else {
1025 $qemucmd32 = "/usr/bin/qemu";
1026 $qemucmd64 = "/usr/bin/qemu-system-x86_64";
1027 }
1028 if ($v =~ /x86_64/) {
1029 $vmcmd = "$qemucmd64 -no-kqemu";
1030 } else {
1031 $vmcmd = "$qemucmd32";
1032 }
1033 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
1034 if ($create != 0) {
1035 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
1036 }
1037 $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
1038 } elsif ($vmtype eq "xen") {
1039 } elsif ($vmtype eq "vmware") {
1040 } else {
1041 die "VM of type $vmtype not supported. Report to the dev team";
1042 }
1043 my ($tmpcmd,$void) = split(/ +/,$cmd);
1044 my $vmexist = pb_check_ps($tmpcmd,$vmm);
1045 my $vmpid = 0;
1046 if (! $vmexist) {
1047 if ($create != 0) {
1048 if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
1049 pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
1050 } elsif ($vmtype eq "vmware") {
1051 } else {
1052 }
1053 }
1054 if (! -f "$vmm") {
1055 pb_log(0,"Unable to find VM $vmm\n");
1056 } else {
1057 pb_system("$cmd &","Launching the VM $vmm");
1058 pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
1059 $vmpid = pb_check_ps($tmpcmd,$vmm);
1060 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
1061 }
1062 } else {
1063 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
1064 }
1065 return($vmexist,$vmpid);
1066 # VE here
1067 } else {
1068 # Get VE context
1069 my ($ptr,$vepath,$vetmout,$verebuild,$veconf) = pb_conf_get("vetype","vepath","vetmout","verebuild","veconf");
1070 my $vetype = $ptr->{$ENV{'PBPROJ'}};
1071
1072 # Get distro context
1073 my ($name,$ver,$darch) = split(/-/,$v);
1074 chomp($darch);
1075 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
1076
1077 if ($vetype eq "chroot") {
1078 # Architecture consistency
1079 if ($arch ne $darch) {
1080 die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
1081 }
1082
1083 if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
1084 # We have to rebuild the chroot
1085 if ($dtype eq "rpm") {
1086 pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1087 # Once setup we need to install some packages, the pb account, ...
1088 pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
1089 #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1090 } elsif ($dtype eq "deb") {
1091 pb_system("","Creating the pbuilder VE");
1092 } elsif ($dtype eq "ebuild") {
1093 die "Please teach the dev team how to build gentoo chroot";
1094 } else {
1095 die "Unknown distribution type $dtype. Report to dev team";
1096 }
1097 }
1098 # Nothing more to do for VE. No real launch
1099 } else {
1100 die "VE of type $vetype not supported. Report to the dev team";
1101 }
1102 }
1103}
1104
1105sub pb_build2v {
1106
1107my $vtype = shift;
1108
1109# Prepare the script to be executed on the VM/VE
1110# in $ENV{'PBDESTDIR'}/pbscript
1111#my ($ntp) = pb_conf_get($vtype."ntp");
1112#my $vntp = $ntp->{$ENV{'PBPROJ'}};
1113
1114open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1115print SCRIPT "#!/bin/bash\n";
1116print SCRIPT "echo ... Execution needed\n";
1117print SCRIPT "# This is in directory delivery\n";
1118print SCRIPT "# Setup the variables required for building\n";
1119print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
1120print SCRIPT "# Preparation for pb\n";
1121print SCRIPT "mv .pbrc \$HOME\n";
1122print SCRIPT "cd ..\n";
1123# Force new date to be in the future compared to the date of the tar file by adding 1 minute
1124my @date=pb_get_date();
1125$date[1]++;
1126my $upddate = strftime("%m%d%H%M%Y", @date);
1127#print SCRIPT "echo Setting up date on $vntp...\n";
1128# Or use ntpdate if available TBC
1129print SCRIPT "sudo date $upddate\n";
1130# Get list of packages to build and get some ENV vars as well
1131my $ptr = pb_get_pkg();
1132@pkgs = @$ptr;
1133my $p = join(' ',@pkgs) if (@pkgs);
1134print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
1135print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
1136print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
1137print SCRIPT "# Build\n";
1138print SCRIPT "echo Building packages on $vtype...\n";
1139print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
1140close(SCRIPT);
1141chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1142
1143my ($v,$all) = pb_get_v($vtype);
1144
1145# Send tar files when we do a global generation
1146pb_build2ssh() if ($all == 1);
1147
1148my ($vmexist,$vmpid) = (undef,undef);
1149
1150foreach my $v (@$v) {
1151 if ($vtype eq "vm") {
1152 # Launch the VM
1153 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1154
1155 # Skip that VM if it something went wrong
1156 next if (($vmpid == 0) && ($vmexist == 0));
1157 }
1158 # Gather all required files to send them to the VM/VE
1159 # and launch the build through pbscript
1160 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
1161 pb_send2target($vtype,"$v",$vmexist,$vmpid);
1162}
1163}
1164
1165
1166sub pb_newver {
1167
1168 die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
1169
1170 # Need this call for PBDIR
1171 my ($scheme2,$uri) = pb_cms_init($pbinit);
1172
1173 my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
1174 $uri = $pbconf->{$ENV{'PBPROJ'}};
1175 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1176
1177 # Checking CMS repositories status
1178 my ($pburl) = pb_conf_get("pburl");
1179 ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
1180
1181 if ($scheme !~ /^svn/) {
1182 die "Only SVN is supported at the moment";
1183 }
1184 my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
1185 die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
1186
1187 $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
1188 die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
1189
1190 # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
1191 # we want to get for the root of the new URL
1192
1193 my $tmp = $ENV{'PBROOTDIR'};
1194 $tmp =~ s|^$ENV{'PBCONFDIR'}||;
1195
1196 my $newurl = "$uri/".dirname($tmp)."/$newver";
1197 # Should probably use projver in the old file
1198 my $oldver= basename($tmp);
1199
1200 # Checking pbcl files
1201 foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
1202 open(PBCL,$f) || die "Unable to open $f";
1203 my $foundnew = 0;
1204 while (<PBCL>) {
1205 $foundnew = 1 if (/^$newver \(/);
1206 }
1207 close(PBCL);
1208 die "ERROR: version $newver not found in $f" if ($foundnew == 0);
1209 }
1210
1211 # Duplicate and extract project-builder part
1212 pb_log(2,"Copying $uri/$tmp to $newurl\n");
1213 pb_cms_copy($scheme,"$uri/$tmp",$newurl);
1214 pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
1215 pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
1216
1217 # Duplicate and extract project
1218 my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
1219
1220 pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
1221 pb_cms_copy($scheme,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
1222 pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
1223 pb_cms_up($scheme,"$ENV{'PBDIR'}/..");
1224
1225 # Update the .pb file
1226 open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
1227 open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
1228 while(<FILE>) {
1229 s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
1230 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/);
1231 s/^testver/#testver/;
1232 pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
1233 print OUT $_;
1234 }
1235 close(FILE);
1236 close(OUT);
1237 rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
1238
1239 pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
1240 pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver");
1241}
1242
1243#
1244# Return the list of VMs/VEs we are working on
1245# $all is a flag to know if we return all of them
1246# or only some (if all we publish also tar files in addition to pkgs
1247#
1248sub pb_get_v {
1249
1250my $vtype = shift;
1251my @v;
1252my $all = 0;
1253my $vlist;
1254my $pbv = 'PBV';
1255
1256if ($vtype eq "vm") {
1257 $vlist = "vmlist";
1258} elsif ($vtype eq "ve") {
1259 $vlist = "velist";
1260}
1261# Get VM/VE list
1262if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
1263 my ($ptr) = pb_conf_get($vlist);
1264 $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
1265 $all = 1;
1266}
1267pb_log(2,"$vtype: $ENV{$pbv}\n");
1268@v = split(/,/,$ENV{$pbv});
1269return(\@v,$all);
1270}
1271
1272# Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
1273# Needs to use root account to connect to the VM/VE
1274# pb will take your local public SSH key to access
1275# the pb account in the VM later on if needed
1276sub pb_setup_v {
1277
1278my $vtype = shift;
1279
1280my ($vm,$all) = pb_get_v($vtype);
1281
1282# Script generated
1283my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
1284
1285foreach my $v (@$vm) {
1286 # Name of the account to deal with for VM/VE
1287 # Do not use the one passed potentially with -a
1288 my ($pbac) = pb_conf_get($vtype."login");
1289 my ($key,$zero0,$zero1,$zero2);
1290 my ($vmexist,$vmpid);
1291
1292 if ($vtype eq "vm") {
1293 # Prepare the key to be used and transfered remotely
1294 my $keyfile = pb_ssh_get(1);
1295
1296 my ($vmhost,$vmport) = pb_conf_get("vmhost","vmport");
1297 my $nport = $vmport->{$ENV{'PBPROJ'}};
1298 $nport = "$pbport" if (defined $pbport);
1299
1300 # Launch the VM
1301 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1302
1303 # Skip that VM if something went wrong
1304 return if (($vmpid == 0) && ($vmexist == 0));
1305
1306 # Store the pub key part in a variable
1307 open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
1308 ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
1309 close(FILE);
1310
1311 $key = "\Q$zero1";
1312
1313 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");
1314 # once this is done, we can do what we want on the VM remotely
1315 }
1316
1317 # Prepare the script to be executed on the VM/VE
1318 # in $ENV{'PBDESTDIR'}/setupv
1319
1320 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
1321 print SCRIPT << 'EOF';
1322#!/usr/bin/perl -w
1323
1324use strict;
1325use File::Copy;
1326
1327EOF
1328 if ($vtype eq "vm") {
1329 print SCRIPT << 'EOF';
1330# Removes duplicate in .ssh/authorized_keys of our key if needed
1331#
1332my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
1333open(PBFILE,$file1) || die "Unable to open $file1";
1334open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
1335my $count = 0;
1336while (<PBFILE>) {
1337EOF
1338 print SCRIPT << "EOF";
1339 if (/ $key /) {
1340 \$count++;
1341 }
1342print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
1343}
1344close(PBFILE);
1345close(PBOUT);
1346rename("\$file1.new",\$file1);
1347chmod 0600,\$file1;
1348EOF
1349 }
1350 print SCRIPT << 'EOF';
1351
1352# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
1353#
1354my $file="/etc/passwd";
1355open(PBFILE,$file) || die "Unable to open $file";
1356my $found = 0;
1357while (<PBFILE>) {
1358EOF
1359 print SCRIPT << "EOF";
1360 \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
1361EOF
1362 print SCRIPT << 'EOF';
1363}
1364close(PBFILE);
1365
1366if ( $found == 0 ) {
1367 if ( ! -d "/home" ) {
1368 mkdir "/home";
1369 }
1370EOF
1371 print SCRIPT << "EOF";
1372system "groupadd $pbac->{$ENV{'PBPROJ'}}";
1373system "useradd $pbac->{$ENV{'PBPROJ'}} -g $pbac->{$ENV{'PBPROJ'}} -m -d /home/$pbac->{$ENV{'PBPROJ'}}";
1374
1375# allow ssh entry to build
1376#
1377chdir "/home/$pbac->{$ENV{'PBPROJ'}}";
1378mkdir ".ssh",0700;
1379# Allow those accessing root to access the build account
1380copy("\$ENV{'HOME'}/.ssh/authorized_keys",".ssh/authorized_keys");
1381chmod 0600,".ssh/authorized_keys";
1382system 'chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} .ssh';
1383
1384EOF
1385 print SCRIPT << 'EOF';
1386}
1387
1388# No passwd for build account only keys
1389$file="/etc/shadow";
1390open(PBFILE,$file) || die "Unable to open $file";
1391open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1392while (<PBFILE>) {
1393EOF
1394 print SCRIPT << "EOF";
1395 s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
1396 s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
1397EOF
1398 print SCRIPT << 'EOF';
1399 print PBOUT $_;
1400}
1401close(PBFILE);
1402close(PBOUT);
1403rename("$file.new",$file);
1404chmod 0640,$file;
1405
1406# pb has to be added to portage group on gentoo
1407
1408# Adapt sudoers
1409$file="/etc/sudoers";
1410open(PBFILE,$file) || die "Unable to open $file";
1411open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1412while (<PBFILE>) {
1413EOF
1414 print SCRIPT << "EOF";
1415 next if (/^$pbac->{$ENV{'PBPROJ'}} /);
1416EOF
1417 print SCRIPT << 'EOF';
1418 s/Defaults[ \t]+requiretty//;
1419 print PBOUT $_;
1420}
1421close(PBFILE);
1422EOF
1423 print SCRIPT << "EOF";
1424# This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
1425print PBOUT "$pbac->{$ENV{'PBPROJ'}} ALL=(ALL) NOPASSWD:ALL\n";
1426EOF
1427 print SCRIPT << 'EOF';
1428close(PBOUT);
1429rename("$file.new",$file);
1430chmod 0440,$file;
1431
1432EOF
1433
1434 my $SCRIPT = \*SCRIPT;
1435
1436 pb_install_deps($SCRIPT);
1437
1438 print SCRIPT << 'EOF';
1439# Suse wants sudoers as 640
1440if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
1441 chmod 0640,$file;
1442}
1443
1444# Sync date
1445#system "/usr/sbin/ntpdate ntp.pool.org";
1446
1447system "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-*";
1448system "pb 2>&1 | head -5";
1449EOF
1450 if ((! $vmexist) && ($vtype eq "vm")) {
1451 print SCRIPT << 'EOF';
1452system "sudo /sbin/halt -p";
1453EOF
1454 }
1455
1456 # Adds pb_distro_init from ProjectBuilder::Distribution
1457 foreach my $d (@INC) {
1458 my @f = ("$d/ProjectBuilder/Base.pm","$d/ProjectBuilder/Distribution.pm");
1459 foreach my $f (@f) {
1460 if (-f "$f") {
1461 open(PBD,"$f") || die "Unable to open $f";
1462 while (<PBD>) {
1463 next if (/^package/);
1464 next if (/^use Exporter/);
1465 next if (/^use ProjectBuilder::Base/);
1466 next if (/^our \@/);
1467 print SCRIPT $_;
1468 }
1469 close(PBD);
1470 }
1471 }
1472 }
1473 close(SCRIPT);
1474 chmod 0755,"$pbscript";
1475
1476 # That build script needs to be run as root
1477 $pbaccount = "root";
1478 pb_script2v($pbscript,$vtype);
1479}
1480return;
1481}
1482
1483sub pb_install_deps {
1484
1485my $SCRIPT = shift;
1486
1487print {$SCRIPT} << 'EOF';
1488# We need to have that pb_distro_init function
1489# Get it from Project-Builder::Distribution
1490my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
1491print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
1492
1493# Get and install pb
1494my $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*";
1495my $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*";
1496my $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*";
1497my $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*";
1498
1499if ( $ddir eq "fedora" ) {
1500 system "yum clean all";
1501 #system "yum update -y";
1502 my $arch=`uname -m`;
1503 my $opt = "";
1504 chomp($arch);
1505 if ($arch eq "x86_64") {
1506 $opt="--exclude=*.i?86";
1507 }
1508
1509 system "yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker";
1510 if ($dver eq 4) {
1511 system "$insmb";
1512 system "$insfm";
1513 system "$insfb";
1514 }
1515} elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
1516 # Suppose pkg are installed already as no online mirror available
1517 system "rpm -e lsb 2>&1 > /dev/null";
1518 system "$insdm";
1519 system "$insmb";
1520 system "$insfm";
1521 system "$insfb";
1522} elsif ($ddir eq "suse") {
1523 # New OpenSuSE
1524 system "$insmb";
1525 system "$insfm";
1526 system "$insfb";
1527 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";
1528} elsif ( $dfam eq "md" ) {
1529 system "urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo";
1530 if (($ddir eq "mandrake") && ($dver eq "10.1")) {
1531 system "$insdm";
1532 } else {
1533 system "urpmi --auto perl-DateManip";
1534 }
1535} elsif ( $dfam eq "du" ) {
1536 if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
1537 #system "apt-get update";
1538 system "$insfb";
1539 system "$insfm";
1540 system "apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl";
1541 } else {
1542 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";
1543 }
1544} elsif ( $dfam eq "gen" ) {
1545 #system "emerge -u system ; emerge wget sudo ntp DateManip File-MimeInfo";
1546 system "emerge wget sudo ntp DateManip File-MimeInfo";
1547} else {
1548 print "No pkg to install\n";
1549}
1550EOF
1551}
1552
1553# Return the SSH key file to use
1554# Potentially create it if needed
1555
1556sub pb_ssh_get {
1557
1558my $create = shift || 0; # Do not create keys by default
1559
1560# Check the SSH environment
1561my $keyfile = undef;
1562
1563# We have specific keys by default
1564$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
1565if (!(-e $keyfile) && ($create eq 1)) {
1566 pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
1567}
1568
1569$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
1570$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
1571$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
1572die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
1573return($keyfile);
1574}
1575
1576
1577# Returns the pid of a running VM command using a specific VM file
1578sub pb_check_ps {
1579 my $vmcmd = shift;
1580 my $vmm = shift;
1581 my $vmexist = 0; # FALSE by default
1582
1583 open(PS, "ps auxhww|") || die "Unable to call ps";
1584 while (<PS>) {
1585 next if (! /$vmcmd/);
1586 next if (! /$vmm/);
1587 my ($void1, $void2);
1588 ($void1, $vmexist, $void2) = split(/ +/);
1589 last;
1590 }
1591 return($vmexist);
1592}
1593
1594
1595sub pb_extract_build_files {
1596
1597my $src=shift;
1598my $dir=shift;
1599my $ddir=shift;
1600my @files;
1601
1602if ($src =~ /tar\.gz$/) {
1603 pb_system("tar xfpz $src $dir","Extracting build files");
1604} elsif ($src =~ /tar\.bz2$/) {
1605 pb_system("tar xfpj $src $dir","Extracting build files");
1606} else {
1607 die "Unknown compression algorithm for $src";
1608}
1609opendir(DIR,"$dir") || die "Unable to open directory $dir";
1610foreach my $f (readdir(DIR)) {
1611 next if ($f =~ /^\./);
1612 move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
1613 pb_log(2,"mv $dir/$f $ddir\n");
1614 push @files,"$ddir/$f";
1615}
1616closedir(DIR);
1617# Not enough but still a first cleanup
1618pb_rm_rf("$dir");
1619return(@files);
1620}
1621
1622sub pb_list_bfiles {
1623
1624my $dir = shift;
1625my $pbpkg = shift;
1626my $bfiles = shift;
1627my $pkgfiles = shift;
1628my $supfiles = shift;
1629
1630opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
1631foreach my $f (readdir(BDIR)) {
1632 next if ($f =~ /^\./);
1633 $bfiles->{$f} = "$dir/$f";
1634 $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
1635 if (defined $supfiles->{$pbpkg}) {
1636 $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
1637 }
1638}
1639closedir(BDIR);
1640}
1641
1642sub pb_env_init {
1643
1644my $proj=shift || undef;
1645my $pbinit=shift || undef;
1646my $action=shift;
1647my $ver;
1648my $tag;
1649
1650$ENV{'PBETC'} = "$ENV{'HOME'}/.pbrc";
1651
1652#
1653# Check project name
1654# Could be with env var PBPROJ
1655# or option -p
1656# if not define take the first in conf file
1657#
1658if ((defined $ENV{'PBPROJ'}) &&
1659 (not (defined $proj))) {
1660 $proj = $ENV{'PBPROJ'};
1661}
1662
1663#
1664# We get the pbconf file for that project
1665# and use its content
1666#
1667my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
1668pb_log(2,"DEBUG pbconfurl: ".Dumper($pbconf)."\n");
1669
1670my %pbconf = %$pbconf;
1671if (not defined $proj) {
1672 # Take the first as the default project
1673 $proj = (keys %pbconf)[0];
1674 if (defined $proj) {
1675 pb_log(1,"WARNING: using $proj as default project as none has been specified\n");
1676 pb_log(1," Please either create a pbconfurl reference for project $proj in $ENV{'PBETC'}\n");
1677 pb_log(1," or call pb with the -p project option or use the env var PBPROJ\n");
1678 pb_log(1," if you want to use another project\n");
1679 }
1680}
1681die "No project defined - use env var PBPROJ or -p proj or a pbconfurl entry in $ENV{'PBETC'}" if (not (defined $proj));
1682
1683# That's always the environment variable that will be used
1684$ENV{'PBPROJ'} = $proj;
1685pb_log(2,"PBPROJ: $ENV{'PBPROJ'}\n");
1686
1687if (not defined ($pbconf{$ENV{'PBPROJ'}})) {
1688 die "Please create a pbconfurl reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n";
1689}
1690
1691#
1692# Detect the root dir for hosting all the content generated with pb
1693#
1694# Tree will look like this:
1695#
1696# maint pbdefdir PBDEFDIR dev dir (optional)
1697# | |
1698# ------------------------ --------------------
1699# | | | |
1700# pbproj1 pbproj2 PBPROJ pbproj1 pbproj2 PBPROJDIR
1701# | |
1702# --------------------------------------------- ----------
1703# * * * | | | * *
1704# tag dev pbconf ... build delivery PBCONFDIR dev tag
1705# | | | PBDESTDIR |
1706# --- ------ pbrc PBBUILDDIR -------
1707# | | | | |
1708# 1.1 dev tag 1.0 1.1 PBDIR
1709# |
1710# -------
1711# | |
1712# 1.0 1.1 PBROOTDIR
1713# |
1714# ----------------------------------
1715# | | | |
1716# pkg1 pbproj1.pb pbfilter pbcl
1717# |
1718# -----------------
1719# | | |
1720# rpm deb pbfilter
1721#
1722#
1723# (*) By default, if no relocation in .pbrc, dev dir is taken in the maint pbdefdir (when appropriate)
1724# Names under a pbproj and the corresponding pbconf should be similar
1725#
1726
1727my ($pbdefdir) = pb_conf_get_if("pbdefdir");
1728
1729if (not defined $ENV{'PBDEFDIR'}) {
1730 if ((not defined $pbdefdir) || (not defined $pbdefdir->{$ENV{'PBPROJ'}})) {
1731 pb_log(1,"WARNING: no pbdefdir defined, using /var/cache\n");
1732 pb_log(1," Please create a pbdefdir reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
1733 pb_log(1," if you want to use another directory\n");
1734 $ENV{'PBDEFDIR'} = "/var/cache";
1735 } else {
1736 # That's always the environment variable that will be used
1737 $ENV{'PBDEFDIR'} = $pbdefdir->{$ENV{'PBPROJ'}};
1738 }
1739}
1740# Expand potential env variable in it
1741eval { $ENV{'PBDEFDIR'} =~ s/(\$ENV.+\})/$1/eeg };
1742
1743pb_log(2,"PBDEFDIR: $ENV{'PBDEFDIR'}\n");
1744#
1745# Set delivery directory
1746#
1747$ENV{'PBDESTDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/delivery";
1748
1749pb_log(2,"PBDESTDIR: $ENV{'PBDESTDIR'}\n");
1750#
1751# Removes all directory existing below the delivery dir
1752# as they are temp dir only
1753# Files stay and have to be cleaned up manually if needed
1754# those files serves as communication channels between pb phases
1755# Removing them prevents a following phase to detect what has been done before
1756#
1757if (-d $ENV{'PBDESTDIR'}) {
1758 opendir(DIR,$ENV{'PBDESTDIR'}) || die "Unable to open directory $ENV{'PBDESTDIR'}: $!";
1759 foreach my $d (readdir(DIR)) {
1760 next if ($d =~ /^\./);
1761 next if (-f "$ENV{'PBDESTDIR'}/$d");
1762 pb_rm_rf("$ENV{'PBDESTDIR'}/$d") if (-d "$ENV{'PBDESTDIR'}/$d");
1763 }
1764 closedir(DIR);
1765}
1766if (! -d "$ENV{'PBDESTDIR'}") {
1767 pb_mkdir_p($ENV{'PBDESTDIR'}) || die "Unable to recursively create $ENV{'PBDESTDIR'}";
1768}
1769
1770#
1771# Set build directory
1772#
1773$ENV{'PBBUILDDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/build";
1774if (! -d "$ENV{'PBBUILDDIR'}") {
1775 pb_mkdir_p($ENV{'PBBUILDDIR'}) || die "Unable to recursively create $ENV{'PBBUILDDIR'}";
1776}
1777
1778pb_log(2,"PBBUILDDIR: $ENV{'PBBUILDDIR'}\n");
1779
1780pb_temp_init();
1781pb_log(2,"PBTMP: $ENV{'PBTMP'}\n");
1782
1783#
1784# The following part is only useful when in cms2something of newver
1785# In VMs/VEs we want to skip that by providing good env vars.
1786# return values in that case are useless
1787#
1788if (($action =~ /^cms2/) || ($action =~ /^newver$/)) {
1789
1790 #
1791 # Check pbconf cms compliance
1792 #
1793 pb_cms_compliant("pbconfdir",'PBCONFDIR',"$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/pbconf",$pbconf{$ENV{'PBPROJ'}},$pbinit);
1794
1795 # Check where is our PBROOTDIR (release tag name can't be guessed the first time)
1796 #
1797 if (not defined $ENV{'PBROOTDIR'}) {
1798 if (! -f ("$ENV{'PBDESTDIR'}/pbrc")) {
1799 opendir(DIR,$ENV{'PBCONFDIR'}) || die "Unable to open directory $ENV{'PBCONFDIR'}: $!";
1800 my $maxmtime = 0;
1801 foreach my $d (readdir(DIR)) {
1802 pb_log(3,"Looking at \'$d\'...");
1803 next if ($d =~ /^\./);
1804 next if (! -d "$ENV{'PBCONFDIR'}/$d");
1805 my $s = stat("$ENV{'PBCONFDIR'}/$d");
1806 next if (not defined $s);
1807 pb_log(3,"KEEP\n");
1808 # Keep the most recent
1809 pb_log(2," $s->mtime\n");
1810 if ($s->mtime > $maxmtime) {
1811 $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$d";
1812 $maxmtime = $s->mtime;
1813 }
1814 }
1815 closedir(DIR);
1816 die "No directory found under $ENV{'PBCONFDIR'}" if (not defined $ENV{'PBROOTDIR'});
1817 pb_log(1,"WARNING: no pbroot defined, using $ENV{'PBROOTDIR'}\n");
1818 pb_log(1," Please use -r release if you want to use another release\n");
1819 } else {
1820 my ($pbroot) = pb_conf_read_if("$ENV{'PBDESTDIR'}/pbrc","pbroot");
1821 # That's always the environment variable that will be used
1822 die "Please remove inconsistent $ENV{'PBDESTDIR'}/pbrc" if ((not defined $pbroot) || (not defined $pbroot->{$ENV{'PBPROJ'}}));
1823 $ENV{'PBROOTDIR'} = $pbroot->{$ENV{'PBPROJ'}};
1824 }
1825 } else {
1826 # transform in full path if relative
1827 $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$ENV{'PBROOTDIR'}" if ($ENV{'PBROOTDIR'} !~ /^\//);
1828 pb_mkdir_p($ENV{'PBROOTDIR'}) if (defined $pbinit);
1829 die "$ENV{'PBROOTDIR'} is not a directory" if (not -d $ENV{'PBROOTDIR'});
1830 }
1831
1832 return if ($action =~ /^newver$/);
1833
1834 my %version = ();
1835 my %defpkgdir = ();
1836 my %extpkgdir = ();
1837 my %filteredfiles = ();
1838 my %supfiles = ();
1839
1840 if ((-f "$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") and (not defined $pbinit)) {
1841 # List of pkg to build by default (mandatory)
1842 my ($defpkgdir,$pbpackager, $pkgv, $pkgt) = pb_conf_get("defpkgdir","pbpackager","projver","projtag");
1843 # List of additional pkg to build when all is called (optional)
1844 # Valid version names (optional)
1845 # List of files to filter (optional)
1846 # Project version and tag (optional)
1847 my ($extpkgdir, $version, $filteredfiles, $supfiles) = pb_conf_get_if("extpkgdir","version","filteredfiles","supfiles");
1848 pb_log(2,"DEBUG: defpkgdir: ".Dumper($defpkgdir)."\n");
1849 pb_log(2,"DEBUG: extpkgdir: ".Dumper($extpkgdir)."\n");
1850 pb_log(2,"DEBUG: version: ".Dumper($version)."\n");
1851 pb_log(2,"DEBUG: filteredfiles: ".Dumper($filteredfiles)."\n");
1852 pb_log(2,"DEBUG: supfiles: ".Dumper($supfiles)."\n");
1853 # Global
1854 %defpkgdir = %$defpkgdir;
1855 %extpkgdir = %$extpkgdir if (defined $extpkgdir);
1856 %version = %$version if (defined $version);
1857 %filteredfiles = %$filteredfiles if (defined $filteredfiles);
1858 %supfiles = %$supfiles if (defined $supfiles);
1859 #
1860 # Get global Version/Tag
1861 #
1862 if (not defined $ENV{'PBPROJVER'}) {
1863 if ((defined $pkgv) && (defined $pkgv->{$ENV{'PBPROJ'}})) {
1864 $ENV{'PBPROJVER'}=$pkgv->{$ENV{'PBPROJ'}};
1865 } else {
1866 die "No projver found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1867 }
1868 }
1869 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'}}/));
1870
1871 if (not defined $ENV{'PBPROJTAG'}) {
1872 if ((defined $pkgt) && (defined $pkgt->{$ENV{'PBPROJ'}})) {
1873 $ENV{'PBPROJTAG'}=$pkgt->{$ENV{'PBPROJ'}};
1874 } else {
1875 die "No projtag found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1876 }
1877 }
1878 die "Invalid tag name $ENV{'PBPROJTAG'} in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb" if ($ENV{'PBPROJTAG'} !~ /[0-9.]+/);
1879
1880
1881 if (not defined $ENV{'PBPACKAGER'}) {
1882 if ((defined $pbpackager) && (defined $pbpackager->{$ENV{'PBPROJ'}})) {
1883 $ENV{'PBPACKAGER'}=$pbpackager->{$ENV{'PBPROJ'}};
1884 } else {
1885 die "No pbpackager found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1886 }
1887 }
1888 } else {
1889 if (defined $pbinit) {
1890 my $ptr = pb_get_pkg();
1891 my @pkgs = @$ptr;
1892 @pkgs = ("pkg1") if (not @pkgs);
1893
1894 open(CONF,"> $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") || die "Unable to create $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1895 print CONF << "EOF";
1896#
1897# Project Builder configuration file
1898# For project $ENV{'PBPROJ'}
1899#
1900# \$Id\$
1901#
1902
1903#
1904# What is the project URL
1905#
1906#pburl $ENV{'PBPROJ'} = svn://svn.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1907#pburl $ENV{'PBPROJ'} = svn://svn+ssh.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1908#pburl $ENV{'PBPROJ'} = cvs://cvs.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1909#pburl $ENV{'PBPROJ'} = http://www.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
1910#pburl $ENV{'PBPROJ'} = ftp://ftp.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
1911#pburl $ENV{'PBPROJ'} = file:///src/$ENV{'PBPROJ'}-devel.tar.gz
1912#pburl $ENV{'PBPROJ'} = dir:///src/$ENV{'PBPROJ'}-devel
1913
1914# Check whether project is well formed
1915# (containing already a directory with the project-version name)
1916#pbwf $ENV{'PBPROJ'} = 1
1917
1918#
1919# Packager label
1920#
1921#pbpackager $ENV{'PBPROJ'} = William Porte <bill\@$ENV{'PBPROJ'}.org>
1922#
1923
1924# For delivery to a machine by SSH (potentially the FTP server)
1925# Needs hostname, account and directory
1926#
1927#sshhost $ENV{'PBPROJ'} = www.$ENV{'PBPROJ'}.org
1928#sshlogin $ENV{'PBPROJ'} = bill
1929#sshdir $ENV{'PBPROJ'} = /$ENV{'PBPROJ'}/ftp
1930#sshport $ENV{'PBPROJ'} = 22
1931
1932#
1933# For Virtual machines management
1934# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
1935# followed by '-' and by release number
1936# followed by '-' and by architecture
1937# a .vmtype extension will be added to the resulting string
1938# a QEMU rhel-3-i286 here means that the VM will be named rhel-3-i386.qemu
1939#
1940#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
1941
1942#
1943# Valid values for vmtype are
1944# qemu, (vmware, xen, ... TBD)
1945#vmtype $ENV{'PBPROJ'} = qemu
1946
1947# Hash for VM stuff on vmtype
1948#vmntp default = pool.ntp.org
1949
1950# We suppose we can commmunicate with the VM through SSH
1951#vmhost $ENV{'PBPROJ'} = localhost
1952#vmlogin $ENV{'PBPROJ'} = pb
1953#vmport $ENV{'PBPROJ'} = 2222
1954
1955# Timeout to wait when VM is launched/stopped
1956#vmtmout default = 120
1957
1958# per VMs needed paramaters
1959#vmopt $ENV{'PBPROJ'} = -m 384 -daemonize
1960#vmpath $ENV{'PBPROJ'} = /home/qemu
1961#vmsize $ENV{'PBPROJ'} = 5G
1962
1963#
1964# For Virtual environment management
1965# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
1966# followed by '-' and by release number
1967# followed by '-' and by architecture
1968# a .vetype extension will be added to the resulting string
1969# a chroot rhel-3-i286 here means that the VE will be named rhel-3-i386.chroot
1970#
1971#velist $ENV{'PBPROJ'} = fedora-7-i386
1972
1973# VE params
1974#vetype $ENV{'PBPROJ'} = chroot
1975#ventp default = pool.ntp.org
1976#velogin $ENV{'PBPROJ'} = pb
1977#vepath $ENV{'PBPROJ'} = /var/lib/mock
1978#veconf $ENV{'PBPROJ'} = /etc/mock
1979#verebuild $ENV{'PBPROJ'} = false
1980
1981#
1982# Global version/tag for the project
1983#
1984#projver $ENV{'PBPROJ'} = devel
1985#projtag $ENV{'PBPROJ'} = 1
1986
1987# Hash of valid version names
1988#version $ENV{'PBPROJ'} = devel,stable
1989
1990# Adapt to your needs:
1991# Optional if you need to overwrite the global values above
1992#
1993EOF
1994
1995 foreach my $pp (@pkgs) {
1996 print CONF << "EOF";
1997#pkgver $pp = stable
1998#pkgtag $pp = 3
1999EOF
2000 }
2001 foreach my $pp (@pkgs) {
2002 print CONF << "EOF";
2003# Hash of default package/package directory
2004#defpkgdir $pp = dir-$pp
2005EOF
2006 }
2007
2008 print CONF << "EOF";
2009# Hash of additional package/package directory
2010#extpkgdir minor-pkg = dir-minor-pkg
2011
2012# List of files per pkg on which to apply filters
2013# Files are mentioned relatively to pbroot/defpkgdir
2014EOF
2015 foreach my $pp (@pkgs) {
2016 print CONF << "EOF";
2017#filteredfiles $pp = Makefile.PL,configure.in,install.sh,$pp.8
2018#supfiles $pp = $pp.init
2019EOF
2020 }
2021 close(CONF);
2022 pb_mkdir_p("$ENV{'PBROOTDIR'}/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter";
2023 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/all.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/all.pbf";
2024 print CONF << "EOF";
2025#
2026# \$Id\$
2027#
2028# Filter for all files
2029#
2030# PBSRC is replaced by the source package format
2031#filter PBSRC = ftp://ftp.$ENV{'PBPROJ'}.org/src/%{name}-%{version}.tar.gz
2032
2033# PBVER is replaced by the version (\$pbver in code)
2034filter PBVER = \$pbver
2035
2036# PBDATE is replaced by the date (\$pbdate in code)
2037filter PBDATE = \$pbdate
2038
2039# PBLOG is replaced by the changelog if value is yes
2040#filter PBLOG = yes
2041
2042# PBTAG is replaced by the tag (\$pbtag in code)
2043filter PBTAG = \$pbtag
2044
2045# PBREV is replaced by the revision (\$pbrev in code)
2046filter PBREV = \$pbrev
2047
2048# PBPKG is replaced by the package name (\$pbpkg in code)
2049filter PBPKG = \$pbpkg
2050
2051# PBPACKAGER is replaced by the packager name (\$pbpackager in code)
2052filter PBPACKAGER = \$pbpackager
2053
2054# PBDESC contains the description of the package
2055#filter PBDESC = "Bla-Bla"
2056
2057# PBURL contains the URL of the Web site of the project
2058#filter PBURL = http://www.$ENV{'PBPROJ'}.org
2059EOF
2060 close(CONF);
2061 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf";
2062 print CONF << "EOF";
2063#
2064# \$Id\$
2065#
2066# Filter for rpm build
2067#
2068
2069# PBGRP is replaced by the RPM group of apps
2070# Cf: http://fedoraproject.org/wiki/RPMGroups
2071#filter PBGRP = Applications/Archiving
2072
2073# PBLIC is replaced by the license of the application
2074# Cf: http://fedoraproject.org/wiki/Licensing
2075#filter PBLIC = GPL
2076
2077# PBDEP is replaced by the list of dependencies
2078#filter PBDEP =
2079
2080# PBSUF is replaced by the package suffix (\$pbsuf in code)
2081filter PBSUF = \$pbsuf
2082
2083# PBOBS is replaced by the Obsolete line
2084#filter PBOBS =
2085
2086EOF
2087 close(CONF);
2088 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/deb.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/deb.pbf";
2089 print CONF << "EOF";
2090#
2091# \$Id\$
2092#
2093# Filter for debian build
2094#
2095# PBGRP is replaced by the group of apps
2096filter PBGRP = utils
2097
2098# PBLIC is replaced by the license of the application
2099# Cf:
2100#filter PBLIC = GPL
2101
2102# PBDEP is replaced by the list of dependencies
2103#filter PBDEP =
2104
2105# PBSUG is replaced by the list of suggestions
2106#filter PBSUG =
2107
2108# PBREC is replaced by the list of recommandations
2109#filter PBREC =
2110
2111EOF
2112 close(CONF);
2113 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/md.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/md.pbf";
2114 print CONF << "EOF";
2115# Specific group for Mandriva for $ENV{'PBPROJ'}
2116# Cf: http://wiki.mandriva.com/en/Development/Packaging/Groups
2117#filter PBGRP = Archiving/Backup
2118
2119# PBLIC is replaced by the license of the application
2120# Cf: http://wiki.mandriva.com/en/Development/Packaging/Licenses
2121#filter PBLIC = GPL
2122
2123EOF
2124 close(CONF);
2125 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/novell.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/novell.pbf";
2126 print CONF << "EOF";
2127# Specific group for SuSE for $ENV{'PBPROJ'}
2128# Cf: http://en.opensuse.org/SUSE_Package_Conventions/RPM_Groups
2129#filter PBGRP = Productivity/Archiving/Backup
2130
2131# PBLIC is replaced by the license of the application
2132# Cf: http://en.opensuse.org/Packaging/SUSE_Package_Conventions/RPM_Style#1.6._License_Tag
2133#filter PBLIC = GPL
2134
2135EOF
2136 close(CONF);
2137 foreach my $pp (@pkgs) {
2138 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/deb") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb";
2139 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/control") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/control";
2140 print CONF << "EOF";
2141Source: PBPKG
2142Section: PBGRP
2143Priority: optional
2144Maintainer: PBPACKAGER
2145Build-Depends: debhelper (>= 4.2.20), PBDEP
2146Standards-Version: 3.6.1
2147
2148Package: PBPKG
2149Architecture: amd64 i386 ia64
2150Section: PBGRP
2151Priority: optional
2152Depends: \${shlibs:Depends}, \${misc:Depends}, PBDEP
2153Recommends: PBREC
2154Suggests: PBSUG
2155Description:
2156 PBDESC
2157 .
2158 Homepage: PBURL
2159
2160EOF
2161 close(CONF);
2162 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/copyright") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/copyright";
2163 print CONF << "EOF";
2164This package is debianized by PBPACKAGER
2165`date`
2166
2167The current upstream source was downloaded from
2168ftp://ftp.$ENV{'PBPROJ'}.org/src/.
2169
2170Upstream Authors: Put their name here
2171
2172Copyright:
2173
2174 This package is free software; you can redistribute it and/or modify
2175 it under the terms of the GNU General Public License as published by
2176 the Free Software Foundation; version 2 dated June, 1991.
2177
2178 This package is distributed in the hope that it will be useful,
2179 but WITHOUT ANY WARRANTY; without even the implied warranty of
2180 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2181 GNU General Public License for more details.
2182
2183 You should have received a copy of the GNU General Public License
2184 along with this package; if not, write to the Free Software
2185 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
2186 MA 02110-1301, USA.
2187
2188On Debian systems, the complete text of the GNU General
2189Public License can be found in /usr/share/common-licenses/GPL.
2190
2191EOF
2192 close(CONF);
2193 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/changelog") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/changelog";
2194 print CONF << "EOF";
2195PBLOG
2196EOF
2197 close(CONF);
2198 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/compat") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/compat";
2199 print CONF << "EOF";
22004
2201EOF
2202 close(CONF);
2203 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs";
2204 print CONF << "EOF";
2205EOF
2206 close(CONF);
2207 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs";
2208 print CONF << "EOF";
2209INSTALL
2210COPYING
2211AUTHORS
2212NEWS
2213README
2214EOF
2215 close(CONF);
2216 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/rules") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/rules";
2217 print CONF << 'EOF';
2218#!/usr/bin/make -f
2219# -*- makefile -*-
2220# Sample debian/rules that uses debhelper.
2221# GNU copyright 1997 to 1999 by Joey Hess.
2222#
2223# $Id$
2224#
2225
2226# Uncomment this to turn on verbose mode.
2227#export DH_VERBOSE=1
2228
2229# Define package name variable for a one-stop change.
2230PACKAGE_NAME = PBPKG
2231
2232# These are used for cross-compiling and for saving the configure script
2233# from having to guess our platform (since we know it already)
2234DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
2235DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
2236
2237CFLAGS = -Wall -g
2238
2239ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
2240 CFLAGS += -O0
2241else
2242 CFLAGS += -O2
2243endif
2244ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
2245 INSTALL_PROGRAM += -s
2246endif
2247config.status: configure
2248 dh_testdir
2249
2250 # Configure the package.
2251 CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr
2252 --mandir=\$${prefix}/share/man
2253
2254# Build both architecture dependent and independent
2255build: build-arch build-indep
2256
2257# Build architecture dependent
2258build-arch: build-arch-stamp
2259
2260build-arch-stamp: config.status
2261 dh_testdir
2262
2263 # Compile the package.
2264 $(MAKE)
2265
2266 touch build-stamp
2267
2268# Build architecture independent
2269build-indep: build-indep-stamp
2270
2271build-indep-stamp: config.status
2272 # Nothing to do, the only indep item is the manual which is available as html in original source
2273 touch build-indep-stamp
2274
2275# Clean up
2276clean:
2277 dh_testdir
2278 dh_testroot
2279 rm -f build-arch-stamp build-indep-stamp #CONFIGURE-STAMP#
2280 # Clean temporary document directory
2281 rm -rf debian/doc-temp
2282 # Clean up.
2283 -$(MAKE) distclean
2284 rm -f config.log
2285ifneq "$(wildcard /usr/share/misc/config.sub)" ""
2286 cp -f /usr/share/misc/config.sub config.sub
2287endif
2288ifneq "$(wildcard /usr/share/misc/config.guess)" ""
2289 cp -f /usr/share/misc/config.guess config.guess
2290endif
2291
2292 dh_clean
2293
2294# Install architecture dependent and independent
2295install: install-arch install-indep
2296
2297# Install architecture dependent
2298install-arch: build-arch
2299 dh_testdir
2300 dh_testroot
2301 dh_clean -k -s
2302 dh_installdirs -s
2303
2304 # Install the package files into build directory:
2305 # - start with upstream make install
2306 $(MAKE) install prefix=$(CURDIR)/debian/$(PACKAGE_NAME)/usr mandir=$(CURDIR)/debian/$(PACKAGE_NAME)/us
2307r/share/man
2308 # - copy html manual to temporary location for renaming
2309 mkdir -p debian/doc-temp
2310 dh_install -s
2311
2312# Install architecture independent
2313install-indep: build-indep
2314 dh_testdir
2315 dh_testroot
2316 dh_clean -k -i
2317 dh_installdirs -i
2318 dh_install -i
2319
2320# Must not depend on anything. This is to be called by
2321# binary-arch/binary-indep
2322# in another 'make' thread.
2323binary-common:
2324 dh_testdir
2325 dh_testroot
2326 dh_installchangelogs ChangeLog
2327 dh_installdocs
2328 dh_installman
2329 dh_link
2330 dh_strip
2331 dh_compress
2332 dh_fixperms
2333 dh_installdeb
2334 dh_shlibdeps
2335 dh_gencontrol
2336 dh_md5sums
2337 dh_builddeb
2338
2339# Build architecture independant packages using the common target.
2340binary-indep: build-indep install-indep
2341 $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
2342
2343# Build architecture dependant packages using the common target.
2344binary-arch: build-arch install-arch
2345 $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
2346
2347# Build architecture depdendent and independent packages
2348binary: binary-arch binary-indep
2349.PHONY: clean binary
2350
2351EOF
2352 close(CONF);
2353 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/rpm") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm";
2354 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec";
2355 print CONF << 'EOF';
2356#
2357# $Id$
2358#
2359
2360Summary: bla-bla
2361Summary(fr): french bla-bla
2362
2363Name: PBPKG
2364Version: PBVER
2365Release: PBTAGPBSUF
2366License: PBLIC
2367Group: PBGRP
2368Url: PBURL
2369Source: PBSRC
2370BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -u -n)
2371#Requires: PBDEP
2372
2373%description
2374PBDESC
2375
2376%description -l fr
2377french desc
2378
2379%prep
2380%setup -q
2381
2382%build
2383%configure
2384make %{?_smp_mflags}
2385
2386%install
2387%{__rm} -rf $RPM_BUILD_ROOT
2388make DESTDIR=$RPM_BUILD_ROOT install
2389
2390%clean
2391%{__rm} -rf $RPM_BUILD_ROOT
2392
2393%files
2394%defattr(-,root,root)
2395%doc ChangeLog
2396%doc INSTALL COPYING README AUTHORS NEWS
2397
2398%changelog
2399PBLOG
2400
2401EOF
2402 close(CONF);
2403 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/pbfilter";
2404
2405 pb_log(0,"\nDo not to forget to commit the pbconf directory in your CMS if needed\n");
2406 }
2407 } else {
2408 die "Unable to open $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
2409 }
2410 }
2411 umask 0022;
2412 return(\%filteredfiles, \%supfiles, \%defpkgdir, \%extpkgdir);
2413} else {
2414 # Setup the variables from what has been stored at the end of cms2build
2415 my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbroot");
2416 $ENV{'PBROOTDIR'} = $var->{$ENV{'PBPROJ'}};
2417
2418 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projver");
2419 $ENV{'PBPROJVER'} = $var->{$ENV{'PBPROJ'}};
2420
2421 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projtag");
2422 $ENV{'PBPROJTAG'} = $var->{$ENV{'PBPROJ'}};
2423
2424 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbpackager");
2425 $ENV{'PBPACKAGER'} = $var->{$ENV{'PBPROJ'}};
2426
2427 return;
2428}
2429}
2430
2431#
2432# Return the list of packages we are working on in a non CMS action
2433#
2434sub pb_get_pkg {
2435
2436my @pkgs = ();
2437
2438my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
2439@pkgs = keys %$var;
2440
2441pb_log(0,"Packages: ".join(',',@pkgs)."\n");
2442return(\@pkgs);
2443}
2444
24451;
Note: See TracBrowser for help on using the repository browser.