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

Last change on this file since 409 was 409, checked in by Bruno Cornec, 16 years ago
  • Document all reusable functions in pb
  • remove the useless pbproj parameter from pb_filter functions
  • Addition and use of pb_conf_init and pb_conf_add in pb
  • Addition and use of pb_conf_fromfile_if in Conf.pm
  • preparation for 0.9.1
  • Update of pbinit files for mondo to support the new interface of pb_filter functions
  • Property svn:executable set to *
File size: 76.1 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,$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",$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",$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# We only have one configuration file for now.
1653pb_conf_init("$ENV{'PBETC'}");
1654
1655#
1656# Check project name
1657# Could be with env var PBPROJ
1658# or option -p
1659# if not define take the first in conf file
1660#
1661if ((defined $ENV{'PBPROJ'}) &&
1662 (not (defined $proj))) {
1663 $proj = $ENV{'PBPROJ'};
1664}
1665
1666#
1667# We get the pbconf file for that project
1668# and use its content
1669#
1670my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
1671pb_log(2,"DEBUG pbconfurl: ".Dumper($pbconf)."\n");
1672
1673my %pbconf = %$pbconf;
1674if (not defined $proj) {
1675 # Take the first as the default project
1676 $proj = (keys %pbconf)[0];
1677 if (defined $proj) {
1678 pb_log(1,"WARNING: using $proj as default project as none has been specified\n");
1679 pb_log(1," Please either create a pbconfurl reference for project $proj in $ENV{'PBETC'}\n");
1680 pb_log(1," or call pb with the -p project option or use the env var PBPROJ\n");
1681 pb_log(1," if you want to use another project\n");
1682 }
1683}
1684die "No project defined - use env var PBPROJ or -p proj or a pbconfurl entry in $ENV{'PBETC'}" if (not (defined $proj));
1685
1686# That's always the environment variable that will be used
1687$ENV{'PBPROJ'} = $proj;
1688pb_log(2,"PBPROJ: $ENV{'PBPROJ'}\n");
1689
1690if (not defined ($pbconf{$ENV{'PBPROJ'}})) {
1691 die "Please create a pbconfurl reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n";
1692}
1693
1694#
1695# Detect the root dir for hosting all the content generated with pb
1696#
1697# Tree will look like this:
1698#
1699# maint pbdefdir PBDEFDIR dev dir (optional)
1700# | |
1701# ------------------------ --------------------
1702# | | | |
1703# pbproj1 pbproj2 PBPROJ pbproj1 pbproj2 PBPROJDIR
1704# | |
1705# --------------------------------------------- ----------
1706# * * * | | | * *
1707# tag dev pbconf ... build delivery PBCONFDIR dev tag
1708# | | | PBDESTDIR |
1709# --- ------ pbrc PBBUILDDIR -------
1710# | | | | |
1711# 1.1 dev tag 1.0 1.1 PBDIR
1712# |
1713# -------
1714# | |
1715# 1.0 1.1 PBROOTDIR
1716# |
1717# ----------------------------------
1718# | | | |
1719# pkg1 pbproj1.pb pbfilter pbcl
1720# |
1721# -----------------
1722# | | |
1723# rpm deb pbfilter
1724#
1725#
1726# (*) By default, if no relocation in .pbrc, dev dir is taken in the maint pbdefdir (when appropriate)
1727# Names under a pbproj and the corresponding pbconf should be similar
1728#
1729
1730my ($pbdefdir) = pb_conf_get_if("pbdefdir");
1731
1732if (not defined $ENV{'PBDEFDIR'}) {
1733 if ((not defined $pbdefdir) || (not defined $pbdefdir->{$ENV{'PBPROJ'}})) {
1734 pb_log(1,"WARNING: no pbdefdir defined, using /var/cache\n");
1735 pb_log(1," Please create a pbdefdir reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
1736 pb_log(1," if you want to use another directory\n");
1737 $ENV{'PBDEFDIR'} = "/var/cache";
1738 } else {
1739 # That's always the environment variable that will be used
1740 $ENV{'PBDEFDIR'} = $pbdefdir->{$ENV{'PBPROJ'}};
1741 }
1742}
1743# Expand potential env variable in it
1744eval { $ENV{'PBDEFDIR'} =~ s/(\$ENV.+\})/$1/eeg };
1745
1746pb_log(2,"PBDEFDIR: $ENV{'PBDEFDIR'}\n");
1747#
1748# Set delivery directory
1749#
1750$ENV{'PBDESTDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/delivery";
1751
1752pb_log(2,"PBDESTDIR: $ENV{'PBDESTDIR'}\n");
1753#
1754# Removes all directory existing below the delivery dir
1755# as they are temp dir only
1756# Files stay and have to be cleaned up manually if needed
1757# those files serves as communication channels between pb phases
1758# Removing them prevents a following phase to detect what has been done before
1759#
1760if (-d $ENV{'PBDESTDIR'}) {
1761 opendir(DIR,$ENV{'PBDESTDIR'}) || die "Unable to open directory $ENV{'PBDESTDIR'}: $!";
1762 foreach my $d (readdir(DIR)) {
1763 next if ($d =~ /^\./);
1764 next if (-f "$ENV{'PBDESTDIR'}/$d");
1765 pb_rm_rf("$ENV{'PBDESTDIR'}/$d") if (-d "$ENV{'PBDESTDIR'}/$d");
1766 }
1767 closedir(DIR);
1768}
1769if (! -d "$ENV{'PBDESTDIR'}") {
1770 pb_mkdir_p($ENV{'PBDESTDIR'}) || die "Unable to recursively create $ENV{'PBDESTDIR'}";
1771}
1772
1773#
1774# Set build directory
1775#
1776$ENV{'PBBUILDDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/build";
1777if (! -d "$ENV{'PBBUILDDIR'}") {
1778 pb_mkdir_p($ENV{'PBBUILDDIR'}) || die "Unable to recursively create $ENV{'PBBUILDDIR'}";
1779}
1780
1781pb_log(2,"PBBUILDDIR: $ENV{'PBBUILDDIR'}\n");
1782
1783pb_temp_init();
1784pb_log(2,"PBTMP: $ENV{'PBTMP'}\n");
1785
1786#
1787# The following part is only useful when in cms2something of newver
1788# In VMs/VEs we want to skip that by providing good env vars.
1789# return values in that case are useless
1790#
1791if (($action =~ /^cms2/) || ($action =~ /^newver$/)) {
1792
1793 #
1794 # Check pbconf cms compliance
1795 #
1796 pb_cms_compliant("pbconfdir",'PBCONFDIR',"$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/pbconf",$pbconf{$ENV{'PBPROJ'}},$pbinit);
1797
1798 # Check where is our PBROOTDIR (release tag name can't be guessed the first time)
1799 #
1800 if (not defined $ENV{'PBROOTDIR'}) {
1801 if (! -f ("$ENV{'PBDESTDIR'}/pbrc")) {
1802 opendir(DIR,$ENV{'PBCONFDIR'}) || die "Unable to open directory $ENV{'PBCONFDIR'}: $!";
1803 my $maxmtime = 0;
1804 foreach my $d (readdir(DIR)) {
1805 pb_log(3,"Looking at \'$d\'...");
1806 next if ($d =~ /^\./);
1807 next if (! -d "$ENV{'PBCONFDIR'}/$d");
1808 my $s = stat("$ENV{'PBCONFDIR'}/$d");
1809 next if (not defined $s);
1810 pb_log(3,"KEEP\n");
1811 # Keep the most recent
1812 pb_log(2," $s->mtime\n");
1813 if ($s->mtime > $maxmtime) {
1814 $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$d";
1815 $maxmtime = $s->mtime;
1816 }
1817 }
1818 closedir(DIR);
1819 die "No directory found under $ENV{'PBCONFDIR'}" if (not defined $ENV{'PBROOTDIR'});
1820 pb_log(1,"WARNING: no pbroot defined, using $ENV{'PBROOTDIR'}\n");
1821 pb_log(1," Please use -r release if you want to use another release\n");
1822 } else {
1823 my ($pbroot) = pb_conf_read_if("$ENV{'PBDESTDIR'}/pbrc","pbroot");
1824 # That's always the environment variable that will be used
1825 die "Please remove inconsistent $ENV{'PBDESTDIR'}/pbrc" if ((not defined $pbroot) || (not defined $pbroot->{$ENV{'PBPROJ'}}));
1826 $ENV{'PBROOTDIR'} = $pbroot->{$ENV{'PBPROJ'}};
1827 }
1828 } else {
1829 # transform in full path if relative
1830 $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$ENV{'PBROOTDIR'}" if ($ENV{'PBROOTDIR'} !~ /^\//);
1831 pb_mkdir_p($ENV{'PBROOTDIR'}) if (defined $pbinit);
1832 die "$ENV{'PBROOTDIR'} is not a directory" if (not -d $ENV{'PBROOTDIR'});
1833 }
1834
1835 # Adds that conf file to the list to consider
1836 pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") if (-f "$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
1837
1838 return if ($action =~ /^newver$/);
1839
1840 my %version = ();
1841 my %defpkgdir = ();
1842 my %extpkgdir = ();
1843 my %filteredfiles = ();
1844 my %supfiles = ();
1845
1846 if ((-f "$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") and (not defined $pbinit)) {
1847
1848 # List of pkg to build by default (mandatory)
1849 my ($defpkgdir,$pbpackager, $pkgv, $pkgt) = pb_conf_get("defpkgdir","pbpackager","projver","projtag");
1850 # List of additional pkg to build when all is called (optional)
1851 # Valid version names (optional)
1852 # List of files to filter (optional)
1853 # Project version and tag (optional)
1854 my ($extpkgdir, $version, $filteredfiles, $supfiles) = pb_conf_get_if("extpkgdir","version","filteredfiles","supfiles");
1855 pb_log(2,"DEBUG: defpkgdir: ".Dumper($defpkgdir)."\n");
1856 pb_log(2,"DEBUG: extpkgdir: ".Dumper($extpkgdir)."\n");
1857 pb_log(2,"DEBUG: version: ".Dumper($version)."\n");
1858 pb_log(2,"DEBUG: filteredfiles: ".Dumper($filteredfiles)."\n");
1859 pb_log(2,"DEBUG: supfiles: ".Dumper($supfiles)."\n");
1860 # Global
1861 %defpkgdir = %$defpkgdir;
1862 %extpkgdir = %$extpkgdir if (defined $extpkgdir);
1863 %version = %$version if (defined $version);
1864 %filteredfiles = %$filteredfiles if (defined $filteredfiles);
1865 %supfiles = %$supfiles if (defined $supfiles);
1866 #
1867 # Get global Version/Tag
1868 #
1869 if (not defined $ENV{'PBPROJVER'}) {
1870 if ((defined $pkgv) && (defined $pkgv->{$ENV{'PBPROJ'}})) {
1871 $ENV{'PBPROJVER'}=$pkgv->{$ENV{'PBPROJ'}};
1872 } else {
1873 die "No projver found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1874 }
1875 }
1876 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'}}/));
1877
1878 if (not defined $ENV{'PBPROJTAG'}) {
1879 if ((defined $pkgt) && (defined $pkgt->{$ENV{'PBPROJ'}})) {
1880 $ENV{'PBPROJTAG'}=$pkgt->{$ENV{'PBPROJ'}};
1881 } else {
1882 die "No projtag found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1883 }
1884 }
1885 die "Invalid tag name $ENV{'PBPROJTAG'} in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb" if ($ENV{'PBPROJTAG'} !~ /[0-9.]+/);
1886
1887
1888 if (not defined $ENV{'PBPACKAGER'}) {
1889 if ((defined $pbpackager) && (defined $pbpackager->{$ENV{'PBPROJ'}})) {
1890 $ENV{'PBPACKAGER'}=$pbpackager->{$ENV{'PBPROJ'}};
1891 } else {
1892 die "No pbpackager found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1893 }
1894 }
1895 } else {
1896 if (defined $pbinit) {
1897 my $ptr = pb_get_pkg();
1898 my @pkgs = @$ptr;
1899 @pkgs = ("pkg1") if (not @pkgs);
1900
1901 open(CONF,"> $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") || die "Unable to create $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1902 print CONF << "EOF";
1903#
1904# Project Builder configuration file
1905# For project $ENV{'PBPROJ'}
1906#
1907# \$Id\$
1908#
1909
1910#
1911# What is the project URL
1912#
1913#pburl $ENV{'PBPROJ'} = svn://svn.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1914#pburl $ENV{'PBPROJ'} = svn://svn+ssh.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1915#pburl $ENV{'PBPROJ'} = cvs://cvs.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1916#pburl $ENV{'PBPROJ'} = http://www.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
1917#pburl $ENV{'PBPROJ'} = ftp://ftp.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
1918#pburl $ENV{'PBPROJ'} = file:///src/$ENV{'PBPROJ'}-devel.tar.gz
1919#pburl $ENV{'PBPROJ'} = dir:///src/$ENV{'PBPROJ'}-devel
1920
1921# Check whether project is well formed
1922# (containing already a directory with the project-version name)
1923#pbwf $ENV{'PBPROJ'} = 1
1924
1925#
1926# Packager label
1927#
1928#pbpackager $ENV{'PBPROJ'} = William Porte <bill\@$ENV{'PBPROJ'}.org>
1929#
1930
1931# For delivery to a machine by SSH (potentially the FTP server)
1932# Needs hostname, account and directory
1933#
1934#sshhost $ENV{'PBPROJ'} = www.$ENV{'PBPROJ'}.org
1935#sshlogin $ENV{'PBPROJ'} = bill
1936#sshdir $ENV{'PBPROJ'} = /$ENV{'PBPROJ'}/ftp
1937#sshport $ENV{'PBPROJ'} = 22
1938
1939#
1940# For Virtual machines management
1941# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
1942# followed by '-' and by release number
1943# followed by '-' and by architecture
1944# a .vmtype extension will be added to the resulting string
1945# a QEMU rhel-3-i286 here means that the VM will be named rhel-3-i386.qemu
1946#
1947#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
1948
1949#
1950# Valid values for vmtype are
1951# qemu, (vmware, xen, ... TBD)
1952#vmtype $ENV{'PBPROJ'} = qemu
1953
1954# Hash for VM stuff on vmtype
1955#vmntp default = pool.ntp.org
1956
1957# We suppose we can commmunicate with the VM through SSH
1958#vmhost $ENV{'PBPROJ'} = localhost
1959#vmlogin $ENV{'PBPROJ'} = pb
1960#vmport $ENV{'PBPROJ'} = 2222
1961
1962# Timeout to wait when VM is launched/stopped
1963#vmtmout default = 120
1964
1965# per VMs needed paramaters
1966#vmopt $ENV{'PBPROJ'} = -m 384 -daemonize
1967#vmpath $ENV{'PBPROJ'} = /home/qemu
1968#vmsize $ENV{'PBPROJ'} = 5G
1969
1970#
1971# For Virtual environment management
1972# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
1973# followed by '-' and by release number
1974# followed by '-' and by architecture
1975# a .vetype extension will be added to the resulting string
1976# a chroot rhel-3-i286 here means that the VE will be named rhel-3-i386.chroot
1977#
1978#velist $ENV{'PBPROJ'} = fedora-7-i386
1979
1980# VE params
1981#vetype $ENV{'PBPROJ'} = chroot
1982#ventp default = pool.ntp.org
1983#velogin $ENV{'PBPROJ'} = pb
1984#vepath $ENV{'PBPROJ'} = /var/lib/mock
1985#veconf $ENV{'PBPROJ'} = /etc/mock
1986#verebuild $ENV{'PBPROJ'} = false
1987
1988#
1989# Global version/tag for the project
1990#
1991#projver $ENV{'PBPROJ'} = devel
1992#projtag $ENV{'PBPROJ'} = 1
1993
1994# Hash of valid version names
1995#version $ENV{'PBPROJ'} = devel,stable
1996
1997# Adapt to your needs:
1998# Optional if you need to overwrite the global values above
1999#
2000EOF
2001
2002 foreach my $pp (@pkgs) {
2003 print CONF << "EOF";
2004#pkgver $pp = stable
2005#pkgtag $pp = 3
2006EOF
2007 }
2008 foreach my $pp (@pkgs) {
2009 print CONF << "EOF";
2010# Hash of default package/package directory
2011#defpkgdir $pp = dir-$pp
2012EOF
2013 }
2014
2015 print CONF << "EOF";
2016# Hash of additional package/package directory
2017#extpkgdir minor-pkg = dir-minor-pkg
2018
2019# List of files per pkg on which to apply filters
2020# Files are mentioned relatively to pbroot/defpkgdir
2021EOF
2022 foreach my $pp (@pkgs) {
2023 print CONF << "EOF";
2024#filteredfiles $pp = Makefile.PL,configure.in,install.sh,$pp.8
2025#supfiles $pp = $pp.init
2026EOF
2027 }
2028 close(CONF);
2029 pb_mkdir_p("$ENV{'PBROOTDIR'}/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter";
2030 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/all.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/all.pbf";
2031 print CONF << "EOF";
2032#
2033# \$Id\$
2034#
2035# Filter for all files
2036#
2037# PBSRC is replaced by the source package format
2038#filter PBSRC = ftp://ftp.$ENV{'PBPROJ'}.org/src/%{name}-%{version}.tar.gz
2039
2040# PBVER is replaced by the version (\$pbver in code)
2041filter PBVER = \$pbver
2042
2043# PBDATE is replaced by the date (\$pbdate in code)
2044filter PBDATE = \$pbdate
2045
2046# PBLOG is replaced by the changelog if value is yes
2047#filter PBLOG = yes
2048
2049# PBTAG is replaced by the tag (\$pbtag in code)
2050filter PBTAG = \$pbtag
2051
2052# PBREV is replaced by the revision (\$pbrev in code)
2053filter PBREV = \$pbrev
2054
2055# PBPKG is replaced by the package name (\$pbpkg in code)
2056filter PBPKG = \$pbpkg
2057
2058# PBPACKAGER is replaced by the packager name (\$pbpackager in code)
2059filter PBPACKAGER = \$pbpackager
2060
2061# PBDESC contains the description of the package
2062#filter PBDESC = "Bla-Bla"
2063
2064# PBURL contains the URL of the Web site of the project
2065#filter PBURL = http://www.$ENV{'PBPROJ'}.org
2066EOF
2067 close(CONF);
2068 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf";
2069 print CONF << "EOF";
2070#
2071# \$Id\$
2072#
2073# Filter for rpm build
2074#
2075
2076# PBGRP is replaced by the RPM group of apps
2077# Cf: http://fedoraproject.org/wiki/RPMGroups
2078#filter PBGRP = Applications/Archiving
2079
2080# PBLIC is replaced by the license of the application
2081# Cf: http://fedoraproject.org/wiki/Licensing
2082#filter PBLIC = GPL
2083
2084# PBDEP is replaced by the list of dependencies
2085#filter PBDEP =
2086
2087# PBSUF is replaced by the package suffix (\$pbsuf in code)
2088filter PBSUF = \$pbsuf
2089
2090# PBOBS is replaced by the Obsolete line
2091#filter PBOBS =
2092
2093EOF
2094 close(CONF);
2095 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/deb.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/deb.pbf";
2096 print CONF << "EOF";
2097#
2098# \$Id\$
2099#
2100# Filter for debian build
2101#
2102# PBGRP is replaced by the group of apps
2103filter PBGRP = utils
2104
2105# PBLIC is replaced by the license of the application
2106# Cf:
2107#filter PBLIC = GPL
2108
2109# PBDEP is replaced by the list of dependencies
2110#filter PBDEP =
2111
2112# PBSUG is replaced by the list of suggestions
2113#filter PBSUG =
2114
2115# PBREC is replaced by the list of recommandations
2116#filter PBREC =
2117
2118EOF
2119 close(CONF);
2120 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/md.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/md.pbf";
2121 print CONF << "EOF";
2122# Specific group for Mandriva for $ENV{'PBPROJ'}
2123# Cf: http://wiki.mandriva.com/en/Development/Packaging/Groups
2124#filter PBGRP = Archiving/Backup
2125
2126# PBLIC is replaced by the license of the application
2127# Cf: http://wiki.mandriva.com/en/Development/Packaging/Licenses
2128#filter PBLIC = GPL
2129
2130EOF
2131 close(CONF);
2132 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/novell.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/novell.pbf";
2133 print CONF << "EOF";
2134# Specific group for SuSE for $ENV{'PBPROJ'}
2135# Cf: http://en.opensuse.org/SUSE_Package_Conventions/RPM_Groups
2136#filter PBGRP = Productivity/Archiving/Backup
2137
2138# PBLIC is replaced by the license of the application
2139# Cf: http://en.opensuse.org/Packaging/SUSE_Package_Conventions/RPM_Style#1.6._License_Tag
2140#filter PBLIC = GPL
2141
2142EOF
2143 close(CONF);
2144 foreach my $pp (@pkgs) {
2145 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/deb") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb";
2146 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/control") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/control";
2147 print CONF << "EOF";
2148Source: PBPKG
2149Section: PBGRP
2150Priority: optional
2151Maintainer: PBPACKAGER
2152Build-Depends: debhelper (>= 4.2.20), PBDEP
2153Standards-Version: 3.6.1
2154
2155Package: PBPKG
2156Architecture: amd64 i386 ia64
2157Section: PBGRP
2158Priority: optional
2159Depends: \${shlibs:Depends}, \${misc:Depends}, PBDEP
2160Recommends: PBREC
2161Suggests: PBSUG
2162Description:
2163 PBDESC
2164 .
2165 Homepage: PBURL
2166
2167EOF
2168 close(CONF);
2169 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/copyright") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/copyright";
2170 print CONF << "EOF";
2171This package is debianized by PBPACKAGER
2172`date`
2173
2174The current upstream source was downloaded from
2175ftp://ftp.$ENV{'PBPROJ'}.org/src/.
2176
2177Upstream Authors: Put their name here
2178
2179Copyright:
2180
2181 This package is free software; you can redistribute it and/or modify
2182 it under the terms of the GNU General Public License as published by
2183 the Free Software Foundation; version 2 dated June, 1991.
2184
2185 This package is distributed in the hope that it will be useful,
2186 but WITHOUT ANY WARRANTY; without even the implied warranty of
2187 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2188 GNU General Public License for more details.
2189
2190 You should have received a copy of the GNU General Public License
2191 along with this package; if not, write to the Free Software
2192 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
2193 MA 02110-1301, USA.
2194
2195On Debian systems, the complete text of the GNU General
2196Public License can be found in /usr/share/common-licenses/GPL.
2197
2198EOF
2199 close(CONF);
2200 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/changelog") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/changelog";
2201 print CONF << "EOF";
2202PBLOG
2203EOF
2204 close(CONF);
2205 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/compat") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/compat";
2206 print CONF << "EOF";
22074
2208EOF
2209 close(CONF);
2210 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs";
2211 print CONF << "EOF";
2212EOF
2213 close(CONF);
2214 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs";
2215 print CONF << "EOF";
2216INSTALL
2217COPYING
2218AUTHORS
2219NEWS
2220README
2221EOF
2222 close(CONF);
2223 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/rules") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/rules";
2224 print CONF << 'EOF';
2225#!/usr/bin/make -f
2226# -*- makefile -*-
2227# Sample debian/rules that uses debhelper.
2228# GNU copyright 1997 to 1999 by Joey Hess.
2229#
2230# $Id$
2231#
2232
2233# Uncomment this to turn on verbose mode.
2234#export DH_VERBOSE=1
2235
2236# Define package name variable for a one-stop change.
2237PACKAGE_NAME = PBPKG
2238
2239# These are used for cross-compiling and for saving the configure script
2240# from having to guess our platform (since we know it already)
2241DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
2242DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
2243
2244CFLAGS = -Wall -g
2245
2246ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
2247 CFLAGS += -O0
2248else
2249 CFLAGS += -O2
2250endif
2251ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
2252 INSTALL_PROGRAM += -s
2253endif
2254config.status: configure
2255 dh_testdir
2256
2257 # Configure the package.
2258 CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr
2259 --mandir=\$${prefix}/share/man
2260
2261# Build both architecture dependent and independent
2262build: build-arch build-indep
2263
2264# Build architecture dependent
2265build-arch: build-arch-stamp
2266
2267build-arch-stamp: config.status
2268 dh_testdir
2269
2270 # Compile the package.
2271 $(MAKE)
2272
2273 touch build-stamp
2274
2275# Build architecture independent
2276build-indep: build-indep-stamp
2277
2278build-indep-stamp: config.status
2279 # Nothing to do, the only indep item is the manual which is available as html in original source
2280 touch build-indep-stamp
2281
2282# Clean up
2283clean:
2284 dh_testdir
2285 dh_testroot
2286 rm -f build-arch-stamp build-indep-stamp #CONFIGURE-STAMP#
2287 # Clean temporary document directory
2288 rm -rf debian/doc-temp
2289 # Clean up.
2290 -$(MAKE) distclean
2291 rm -f config.log
2292ifneq "$(wildcard /usr/share/misc/config.sub)" ""
2293 cp -f /usr/share/misc/config.sub config.sub
2294endif
2295ifneq "$(wildcard /usr/share/misc/config.guess)" ""
2296 cp -f /usr/share/misc/config.guess config.guess
2297endif
2298
2299 dh_clean
2300
2301# Install architecture dependent and independent
2302install: install-arch install-indep
2303
2304# Install architecture dependent
2305install-arch: build-arch
2306 dh_testdir
2307 dh_testroot
2308 dh_clean -k -s
2309 dh_installdirs -s
2310
2311 # Install the package files into build directory:
2312 # - start with upstream make install
2313 $(MAKE) install prefix=$(CURDIR)/debian/$(PACKAGE_NAME)/usr mandir=$(CURDIR)/debian/$(PACKAGE_NAME)/us
2314r/share/man
2315 # - copy html manual to temporary location for renaming
2316 mkdir -p debian/doc-temp
2317 dh_install -s
2318
2319# Install architecture independent
2320install-indep: build-indep
2321 dh_testdir
2322 dh_testroot
2323 dh_clean -k -i
2324 dh_installdirs -i
2325 dh_install -i
2326
2327# Must not depend on anything. This is to be called by
2328# binary-arch/binary-indep
2329# in another 'make' thread.
2330binary-common:
2331 dh_testdir
2332 dh_testroot
2333 dh_installchangelogs ChangeLog
2334 dh_installdocs
2335 dh_installman
2336 dh_link
2337 dh_strip
2338 dh_compress
2339 dh_fixperms
2340 dh_installdeb
2341 dh_shlibdeps
2342 dh_gencontrol
2343 dh_md5sums
2344 dh_builddeb
2345
2346# Build architecture independant packages using the common target.
2347binary-indep: build-indep install-indep
2348 $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
2349
2350# Build architecture dependant packages using the common target.
2351binary-arch: build-arch install-arch
2352 $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
2353
2354# Build architecture depdendent and independent packages
2355binary: binary-arch binary-indep
2356.PHONY: clean binary
2357
2358EOF
2359 close(CONF);
2360 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/rpm") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm";
2361 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec";
2362 print CONF << 'EOF';
2363#
2364# $Id$
2365#
2366
2367Summary: bla-bla
2368Summary(fr): french bla-bla
2369
2370Name: PBPKG
2371Version: PBVER
2372Release: PBTAGPBSUF
2373License: PBLIC
2374Group: PBGRP
2375Url: PBURL
2376Source: PBSRC
2377BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -u -n)
2378#Requires: PBDEP
2379
2380%description
2381PBDESC
2382
2383%description -l fr
2384french desc
2385
2386%prep
2387%setup -q
2388
2389%build
2390%configure
2391make %{?_smp_mflags}
2392
2393%install
2394%{__rm} -rf $RPM_BUILD_ROOT
2395make DESTDIR=$RPM_BUILD_ROOT install
2396
2397%clean
2398%{__rm} -rf $RPM_BUILD_ROOT
2399
2400%files
2401%defattr(-,root,root)
2402%doc ChangeLog
2403%doc INSTALL COPYING README AUTHORS NEWS
2404
2405%changelog
2406PBLOG
2407
2408EOF
2409 close(CONF);
2410 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/pbfilter";
2411
2412 pb_log(0,"\nDo not to forget to commit the pbconf directory in your CMS if needed\n");
2413 }
2414 } else {
2415 die "Unable to open $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
2416 }
2417 }
2418 umask 0022;
2419 return(\%filteredfiles, \%supfiles, \%defpkgdir, \%extpkgdir);
2420} else {
2421 # Setup the variables from what has been stored at the end of cms2build
2422 my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbroot");
2423 $ENV{'PBROOTDIR'} = $var->{$ENV{'PBPROJ'}};
2424
2425 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projver");
2426 $ENV{'PBPROJVER'} = $var->{$ENV{'PBPROJ'}};
2427
2428 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projtag");
2429 $ENV{'PBPROJTAG'} = $var->{$ENV{'PBPROJ'}};
2430
2431 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbpackager");
2432 $ENV{'PBPACKAGER'} = $var->{$ENV{'PBPROJ'}};
2433
2434 return;
2435}
2436}
2437
2438#
2439# Return the list of packages we are working on in a non CMS action
2440#
2441sub pb_get_pkg {
2442
2443my @pkgs = ();
2444
2445my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
2446@pkgs = keys %$var;
2447
2448pb_log(0,"Packages: ".join(',',@pkgs)."\n");
2449return(\@pkgs);
2450}
2451
24521;
Note: See TracBrowser for help on using the repository browser.