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

Last change on this file since 415 was 415, checked in by Bruno Cornec, 16 years ago
  • Adds support for a build system conf file under $vmpath/.pbrc or $vepath/.pbrc
  • Fix .pm modes
  • Property svn:executable set to *
File size: 76.5 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 $conf = "sshconf";
771 my $rebuild = "sshrebuild";
772 my $tmout = "vmtmout";
773 my $path = "vmpath";
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 # Adds conf file used for final delivery
828 pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
829 } elsif ($cmt eq "Script") {
830 $src="$src $ENV{'PBDESTDIR'}/pbscript";
831 } elsif ($cmt eq "Packages") {
832 # Get package list from file made during build2pkg
833 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
834 $src = <KEEP>;
835 chomp($src);
836 close(KEEP);
837 if ($dtype eq "rpm") {
838 # Also make a pbscript to generate yum/urpmi bases
839 # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
840 } elsif ($dtype eq "deb") {
841 # Also make a pbscript to generate apt bases
842 # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
843 }
844 }
845 # Remove potential leading spaces (cause problem with basename)
846 $src =~ s/^ *//;
847 my $basesrc = "";
848 foreach my $i (split(/ +/,$src)) {
849 $basesrc .= " ".basename($i);
850 }
851
852 pb_log(0,"Sources handled ($cmt): $src\n");
853 pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf))."\n");
854 my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vepath) = pb_conf_get($host,$login,$dir,$port,$tmout,$path);
855 my ($vrebuild,$veconf) = pb_conf_get_if($rebuild,$conf);
856 pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
857 # Not mandatory
858 my ($testver) = pb_conf_get_if("testver");
859
860 my $mac;
861 # Useless for VE
862 if ($cmt ne "ve") {
863 $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
864 # Overwrite account value if passed as parameter
865 $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
866 pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
867 }
868
869 my $tdir;
870 my $bdir;
871 if (($cmt eq "Sources") || ($cmt eq "Script")) {
872 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
873 } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
874 $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
875 $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
876 # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
877 $bdir =~ s|\$ENV.+\}/||;
878 } elsif ($cmt eq "Packages") {
879 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
880 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
881 # This is a test pkg => target dir is under test
882 $tdir .= "/test";
883 }
884 } else {
885 return;
886 }
887
888 # Useless for VE
889 my $nport;
890 if ($cmt ne "ve") {
891 $nport = $sshport->{$ENV{'PBPROJ'}};
892 $nport = "$pbport" if (defined $pbport);
893 }
894
895 # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
896 $tdir =~ s|\$ENV.+\}/||;
897
898 my $tm = $vtmout->{$ENV{'PBPROJ'}};
899
900 # ssh communication if not VE
901 # should use a hash instead...
902 my ($shcmd,$cpcmd,$cptarget,$cp2target);
903 if ($cmt ne "ve") {
904 my $keyfile = pb_ssh_get(0);
905 $shcmd = "ssh -i $keyfile -q -p $nport $mac";
906 $cpcmd = "scp -i $keyfile -p -P $nport";
907 $cptarget = "$mac:$tdir";
908 if ($cmt eq "vm") {
909 $cp2target = "$mac:$bdir";
910 }
911 } else {
912 my $tp = $vepath->{$ENV{'PBPROJ'}};
913 $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
914 $cpcmd = "cp -a ";
915 $cptarget = "$tp/$tdir";
916 $cp2target = "$tp/$bdir";
917 }
918
919 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");
920 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
921 # For VE we need to change the owner manually - To be tested if needed
922 #if ($cmt eq "ve") {
923 #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
924 #}
925 pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi\' | bash\"","Executing pbscript on $cptarget if needed");
926 if (($cmt eq "vm") || ($cmt eq "ve")) {
927 # Get back info on pkg produced, compute their name and get them from the VM
928 pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
929 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
930 my $src = <KEEP>;
931 chomp($src);
932 close(KEEP);
933 $src =~ s/^ *//;
934 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
935 # Change pgben to make the next send2target happy
936 my $made = "";
937 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
938 foreach my $p (split(/ +/,$src)) {
939 my $j = basename($p);
940 pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
941 $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
942 }
943 print KEEP "$made\n";
944 close(KEEP);
945 pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
946
947 # We want to send them to the ssh account so overwrite what has been done before
948 undef $pbaccount;
949 pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
950 pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
951 if ((! $vmexist) && ($cmt eq "vm")) {
952 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)");
953 }
954 pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
955 }
956}
957
958sub pb_script2v {
959 my $pbscript=shift;
960 my $vtype=shift;
961
962 # Prepare the script to be executed on the VM
963 # in $ENV{'PBDESTDIR'}/pbscript
964 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
965 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
966 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
967 }
968
969 my ($vm,$all) = pb_get_v($vtype);
970 my ($vmexist,$vmpid) = (undef,undef);
971
972 foreach my $v (@$vm) {
973 # Launch the VM/VE
974 if ($vtype eq "vm") {
975 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
976
977 # Skip that VM if something went wrong
978 next if (($vmpid == 0) && ($vmexist ==0));
979 }
980
981 # Gather all required files to send them to the VM
982 # and launch the build through pbscript
983 pb_send2target("Script","$v",$vmexist,$vmpid);
984
985 }
986}
987
988sub pb_launchv {
989 my $vtype = shift;
990 my $v = shift;
991 my $create = shift || 0; # By default do not create a VM
992
993 die "No VM/VE defined, unable to launch" if (not defined $v);
994 # Keep only the first VM in case many were given
995 $v =~ s/,.*//;
996
997 # Which is our local arch ? (standardize on i386 for those platforms)
998 my $arch = `uname -m`;
999 chomp($arch);
1000 $arch =~ s/i.86/i386/;
1001
1002 # Launch the VMs/VEs
1003 if ($vtype eq "vm") {
1004 die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
1005
1006 my ($ptr,$vmopt,$vmpath,$vmport,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmpath","vmport","vmtmout","vmsize");
1007
1008 my $vmtype = $ptr->{$ENV{'PBPROJ'}};
1009 if (not defined $ENV{'PBVMOPT'}) {
1010 $ENV{'PBVMOPT'} = "";
1011 }
1012 if (defined $vmopt->{$ENV{'PBPROJ'}}) {
1013 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
1014 }
1015 my $nport = $vmport->{$ENV{'PBPROJ'}};
1016 $nport = "$pbport" if (defined $pbport);
1017
1018 my $cmd;
1019 my $vmcmd; # has to be used for pb_check_ps
1020 my $vmm; # has to be used for pb_check_ps
1021 if ($vmtype eq "qemu") {
1022 my $qemucmd32;
1023 my $qemucmd64;
1024 if ($arch eq "x86_64") {
1025 $qemucmd32 = "/usr/bin/qemu-system-i386";
1026 $qemucmd64 = "/usr/bin/qemu";
1027 } else {
1028 $qemucmd32 = "/usr/bin/qemu";
1029 $qemucmd64 = "/usr/bin/qemu-system-x86_64";
1030 }
1031 if ($v =~ /x86_64/) {
1032 $vmcmd = "$qemucmd64 -no-kqemu";
1033 } else {
1034 $vmcmd = "$qemucmd32";
1035 }
1036 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
1037 if ($create != 0) {
1038 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
1039 }
1040 $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
1041 } elsif ($vmtype eq "xen") {
1042 } elsif ($vmtype eq "vmware") {
1043 } else {
1044 die "VM of type $vmtype not supported. Report to the dev team";
1045 }
1046 my ($tmpcmd,$void) = split(/ +/,$cmd);
1047 my $vmexist = pb_check_ps($tmpcmd,$vmm);
1048 my $vmpid = 0;
1049 if (! $vmexist) {
1050 if ($create != 0) {
1051 if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
1052 pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
1053 } elsif ($vmtype eq "vmware") {
1054 } else {
1055 }
1056 }
1057 if (! -f "$vmm") {
1058 pb_log(0,"Unable to find VM $vmm\n");
1059 } else {
1060 pb_system("$cmd &","Launching the VM $vmm");
1061 pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
1062 $vmpid = pb_check_ps($tmpcmd,$vmm);
1063 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
1064 }
1065 } else {
1066 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
1067 }
1068 return($vmexist,$vmpid);
1069 # VE here
1070 } else {
1071 # Get VE context
1072 my ($ptr,$vetmout,$vepath,$verebuild,$veconf) = pb_conf_get("vetype","vetmout","vepath","verebuild","veconf");
1073 my $vetype = $ptr->{$ENV{'PBPROJ'}};
1074
1075 # Get distro context
1076 my ($name,$ver,$darch) = split(/-/,$v);
1077 chomp($darch);
1078 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
1079
1080 if ($vetype eq "chroot") {
1081 # Architecture consistency
1082 if ($arch ne $darch) {
1083 die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
1084 }
1085
1086 if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
1087 # We have to rebuild the chroot
1088 if ($dtype eq "rpm") {
1089 pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1090 # Once setup we need to install some packages, the pb account, ...
1091 pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
1092 #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1093 } elsif ($dtype eq "deb") {
1094 pb_system("","Creating the pbuilder VE");
1095 } elsif ($dtype eq "ebuild") {
1096 die "Please teach the dev team how to build gentoo chroot";
1097 } else {
1098 die "Unknown distribution type $dtype. Report to dev team";
1099 }
1100 }
1101 # Nothing more to do for VE. No real launch
1102 } else {
1103 die "VE of type $vetype not supported. Report to the dev team";
1104 }
1105 }
1106}
1107
1108sub pb_build2v {
1109
1110my $vtype = shift;
1111
1112# Prepare the script to be executed on the VM/VE
1113# in $ENV{'PBDESTDIR'}/pbscript
1114#my ($ntp) = pb_conf_get($vtype."ntp");
1115#my $vntp = $ntp->{$ENV{'PBPROJ'}};
1116
1117open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1118print SCRIPT "#!/bin/bash\n";
1119print SCRIPT "echo ... Execution needed\n";
1120print SCRIPT "# This is in directory delivery\n";
1121print SCRIPT "# Setup the variables required for building\n";
1122print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
1123print SCRIPT "# Preparation for pb\n";
1124print SCRIPT "mv .pbrc \$HOME\n";
1125print SCRIPT "cd ..\n";
1126# Force new date to be in the future compared to the date of the tar file by adding 1 minute
1127my @date=pb_get_date();
1128$date[1]++;
1129my $upddate = strftime("%m%d%H%M%Y", @date);
1130#print SCRIPT "echo Setting up date on $vntp...\n";
1131# Or use ntpdate if available TBC
1132print SCRIPT "sudo date $upddate\n";
1133# Get list of packages to build and get some ENV vars as well
1134my $ptr = pb_get_pkg();
1135@pkgs = @$ptr;
1136my $p = join(' ',@pkgs) if (@pkgs);
1137print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
1138print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
1139print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
1140print SCRIPT "# Build\n";
1141print SCRIPT "echo Building packages on $vtype...\n";
1142print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
1143close(SCRIPT);
1144chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1145
1146my ($v,$all) = pb_get_v($vtype);
1147
1148# Send tar files when we do a global generation
1149pb_build2ssh() if ($all == 1);
1150
1151my ($vmexist,$vmpid) = (undef,undef);
1152
1153foreach my $v (@$v) {
1154 if ($vtype eq "vm") {
1155 # Launch the VM
1156 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1157
1158 # Skip that VM if it something went wrong
1159 next if (($vmpid == 0) && ($vmexist == 0));
1160 }
1161 # Gather all required files to send them to the VM/VE
1162 # and launch the build through pbscript
1163 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
1164 pb_send2target($vtype,"$v",$vmexist,$vmpid);
1165}
1166}
1167
1168
1169sub pb_newver {
1170
1171 die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
1172
1173 # Need this call for PBDIR
1174 my ($scheme2,$uri) = pb_cms_init($pbinit);
1175
1176 my ($pbconf) = pb_conf_get("pbconfurl");
1177 $uri = $pbconf->{$ENV{'PBPROJ'}};
1178 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1179
1180 # Checking CMS repositories status
1181 my ($pburl) = pb_conf_get("pburl");
1182 ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
1183
1184 if ($scheme !~ /^svn/) {
1185 die "Only SVN is supported at the moment";
1186 }
1187 my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
1188 die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
1189
1190 $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
1191 die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
1192
1193 # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
1194 # we want to get for the root of the new URL
1195
1196 my $tmp = $ENV{'PBROOTDIR'};
1197 $tmp =~ s|^$ENV{'PBCONFDIR'}||;
1198
1199 my $newurl = "$uri/".dirname($tmp)."/$newver";
1200 # Should probably use projver in the old file
1201 my $oldver= basename($tmp);
1202
1203 # Checking pbcl files
1204 foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
1205 open(PBCL,$f) || die "Unable to open $f";
1206 my $foundnew = 0;
1207 while (<PBCL>) {
1208 $foundnew = 1 if (/^$newver \(/);
1209 }
1210 close(PBCL);
1211 die "ERROR: version $newver not found in $f" if ($foundnew == 0);
1212 }
1213
1214 # Duplicate and extract project-builder part
1215 pb_log(2,"Copying $uri/$tmp to $newurl\n");
1216 pb_cms_copy($scheme,"$uri/$tmp",$newurl);
1217 pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
1218 pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
1219
1220 # Duplicate and extract project
1221 my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
1222
1223 pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
1224 pb_cms_copy($scheme,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
1225 pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
1226 pb_cms_up($scheme,"$ENV{'PBDIR'}/..");
1227
1228 # Update the .pb file
1229 open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
1230 open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
1231 while(<FILE>) {
1232 s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
1233 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/);
1234 s/^testver/#testver/;
1235 pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
1236 print OUT $_;
1237 }
1238 close(FILE);
1239 close(OUT);
1240 rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
1241
1242 pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
1243 pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver");
1244}
1245
1246#
1247# Return the list of VMs/VEs we are working on
1248# $all is a flag to know if we return all of them
1249# or only some (if all we publish also tar files in addition to pkgs
1250#
1251sub pb_get_v {
1252
1253my $vtype = shift;
1254my @v;
1255my $all = 0;
1256my $vlist;
1257my $pbv = 'PBV';
1258
1259if ($vtype eq "vm") {
1260 $vlist = "vmlist";
1261} elsif ($vtype eq "ve") {
1262 $vlist = "velist";
1263}
1264# Get VM/VE list
1265if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
1266 my ($ptr) = pb_conf_get($vlist);
1267 $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
1268 $all = 1;
1269}
1270pb_log(2,"$vtype: $ENV{$pbv}\n");
1271@v = split(/,/,$ENV{$pbv});
1272return(\@v,$all);
1273}
1274
1275# Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
1276# Needs to use root account to connect to the VM/VE
1277# pb will take your local public SSH key to access
1278# the pb account in the VM later on if needed
1279sub pb_setup_v {
1280
1281my $vtype = shift;
1282
1283my ($vm,$all) = pb_get_v($vtype);
1284
1285# Script generated
1286my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
1287
1288foreach my $v (@$vm) {
1289 # Name of the account to deal with for VM/VE
1290 # Do not use the one passed potentially with -a
1291 my ($pbac) = pb_conf_get($vtype."login");
1292 my ($key,$zero0,$zero1,$zero2);
1293 my ($vmexist,$vmpid);
1294
1295 if ($vtype eq "vm") {
1296 # Prepare the key to be used and transfered remotely
1297 my $keyfile = pb_ssh_get(1);
1298
1299 my ($vmhost,$vmport) = pb_conf_get("vmhost","vmport");
1300 my $nport = $vmport->{$ENV{'PBPROJ'}};
1301 $nport = "$pbport" if (defined $pbport);
1302
1303 # Launch the VM
1304 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1305
1306 # Skip that VM if something went wrong
1307 return if (($vmpid == 0) && ($vmexist == 0));
1308
1309 # Store the pub key part in a variable
1310 open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
1311 ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
1312 close(FILE);
1313
1314 $key = "\Q$zero1";
1315
1316 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");
1317 # once this is done, we can do what we want on the VM remotely
1318 }
1319
1320 # Prepare the script to be executed on the VM/VE
1321 # in $ENV{'PBDESTDIR'}/setupv
1322
1323 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
1324 print SCRIPT << 'EOF';
1325#!/usr/bin/perl -w
1326
1327use strict;
1328use File::Copy;
1329
1330EOF
1331 if ($vtype eq "vm") {
1332 print SCRIPT << 'EOF';
1333# Removes duplicate in .ssh/authorized_keys of our key if needed
1334#
1335my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
1336open(PBFILE,$file1) || die "Unable to open $file1";
1337open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
1338my $count = 0;
1339while (<PBFILE>) {
1340EOF
1341 print SCRIPT << "EOF";
1342 if (/ $key /) {
1343 \$count++;
1344 }
1345print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
1346}
1347close(PBFILE);
1348close(PBOUT);
1349rename("\$file1.new",\$file1);
1350chmod 0600,\$file1;
1351EOF
1352 }
1353 print SCRIPT << 'EOF';
1354
1355# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
1356#
1357my $file="/etc/passwd";
1358open(PBFILE,$file) || die "Unable to open $file";
1359my $found = 0;
1360while (<PBFILE>) {
1361EOF
1362 print SCRIPT << "EOF";
1363 \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
1364EOF
1365 print SCRIPT << 'EOF';
1366}
1367close(PBFILE);
1368
1369if ( $found == 0 ) {
1370 if ( ! -d "/home" ) {
1371 mkdir "/home";
1372 }
1373EOF
1374 print SCRIPT << "EOF";
1375system "groupadd $pbac->{$ENV{'PBPROJ'}}";
1376system "useradd $pbac->{$ENV{'PBPROJ'}} -g $pbac->{$ENV{'PBPROJ'}} -m -d /home/$pbac->{$ENV{'PBPROJ'}}";
1377
1378# allow ssh entry to build
1379#
1380chdir "/home/$pbac->{$ENV{'PBPROJ'}}";
1381mkdir ".ssh",0700;
1382# Allow those accessing root to access the build account
1383copy("\$ENV{'HOME'}/.ssh/authorized_keys",".ssh/authorized_keys");
1384chmod 0600,".ssh/authorized_keys";
1385system 'chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} .ssh';
1386
1387EOF
1388 print SCRIPT << 'EOF';
1389}
1390
1391# No passwd for build account only keys
1392$file="/etc/shadow";
1393open(PBFILE,$file) || die "Unable to open $file";
1394open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1395while (<PBFILE>) {
1396EOF
1397 print SCRIPT << "EOF";
1398 s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
1399 s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
1400EOF
1401 print SCRIPT << 'EOF';
1402 print PBOUT $_;
1403}
1404close(PBFILE);
1405close(PBOUT);
1406rename("$file.new",$file);
1407chmod 0640,$file;
1408
1409# pb has to be added to portage group on gentoo
1410
1411# Adapt sudoers
1412$file="/etc/sudoers";
1413open(PBFILE,$file) || die "Unable to open $file";
1414open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1415while (<PBFILE>) {
1416EOF
1417 print SCRIPT << "EOF";
1418 next if (/^$pbac->{$ENV{'PBPROJ'}} /);
1419EOF
1420 print SCRIPT << 'EOF';
1421 s/Defaults[ \t]+requiretty//;
1422 print PBOUT $_;
1423}
1424close(PBFILE);
1425EOF
1426 print SCRIPT << "EOF";
1427# This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
1428print PBOUT "$pbac->{$ENV{'PBPROJ'}} ALL=(ALL) NOPASSWD:ALL\n";
1429EOF
1430 print SCRIPT << 'EOF';
1431close(PBOUT);
1432rename("$file.new",$file);
1433chmod 0440,$file;
1434
1435EOF
1436
1437 my $SCRIPT = \*SCRIPT;
1438
1439 pb_install_deps($SCRIPT);
1440
1441 print SCRIPT << 'EOF';
1442# Suse wants sudoers as 640
1443if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
1444 chmod 0640,$file;
1445}
1446
1447# Sync date
1448#system "/usr/sbin/ntpdate ntp.pool.org";
1449
1450system "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-*";
1451system "pb 2>&1 | head -5";
1452EOF
1453 if ((! $vmexist) && ($vtype eq "vm")) {
1454 print SCRIPT << 'EOF';
1455system "sudo /sbin/halt -p";
1456EOF
1457 }
1458
1459 # Adds pb_distro_init from ProjectBuilder::Distribution
1460 foreach my $d (@INC) {
1461 my @f = ("$d/ProjectBuilder/Base.pm","$d/ProjectBuilder/Distribution.pm");
1462 foreach my $f (@f) {
1463 if (-f "$f") {
1464 open(PBD,"$f") || die "Unable to open $f";
1465 while (<PBD>) {
1466 next if (/^package/);
1467 next if (/^use Exporter/);
1468 next if (/^use ProjectBuilder::Base/);
1469 next if (/^our \@/);
1470 print SCRIPT $_;
1471 }
1472 close(PBD);
1473 }
1474 }
1475 }
1476 close(SCRIPT);
1477 chmod 0755,"$pbscript";
1478
1479 # That build script needs to be run as root
1480 $pbaccount = "root";
1481 pb_script2v($pbscript,$vtype);
1482}
1483return;
1484}
1485
1486sub pb_install_deps {
1487
1488my $SCRIPT = shift;
1489
1490print {$SCRIPT} << 'EOF';
1491# We need to have that pb_distro_init function
1492# Get it from Project-Builder::Distribution
1493my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
1494print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
1495
1496# Get and install pb
1497my $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*";
1498my $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*";
1499my $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*";
1500my $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*";
1501
1502if ( $ddir eq "fedora" ) {
1503 system "yum clean all";
1504 #system "yum update -y";
1505 my $arch=`uname -m`;
1506 my $opt = "";
1507 chomp($arch);
1508 if ($arch eq "x86_64") {
1509 $opt="--exclude=*.i?86";
1510 }
1511
1512 system "yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker";
1513 if ($dver eq 4) {
1514 system "$insmb";
1515 system "$insfm";
1516 system "$insfb";
1517 }
1518} elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
1519 # Suppose pkg are installed already as no online mirror available
1520 system "rpm -e lsb 2>&1 > /dev/null";
1521 system "$insdm";
1522 system "$insmb";
1523 system "$insfm";
1524 system "$insfb";
1525} elsif ($ddir eq "suse") {
1526 # New OpenSuSE
1527 system "$insmb";
1528 system "$insfm";
1529 system "$insfb";
1530 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";
1531} elsif ( $dfam eq "md" ) {
1532 system "urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo";
1533 if (($ddir eq "mandrake") && ($dver eq "10.1")) {
1534 system "$insdm";
1535 } else {
1536 system "urpmi --auto perl-DateManip";
1537 }
1538} elsif ( $dfam eq "du" ) {
1539 if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
1540 #system "apt-get update";
1541 system "$insfb";
1542 system "$insfm";
1543 system "apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl";
1544 } else {
1545 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";
1546 }
1547} elsif ( $dfam eq "gen" ) {
1548 #system "emerge -u system ; emerge wget sudo ntp DateManip File-MimeInfo";
1549 system "emerge wget sudo ntp DateManip File-MimeInfo";
1550} else {
1551 print "No pkg to install\n";
1552}
1553EOF
1554}
1555
1556# Return the SSH key file to use
1557# Potentially create it if needed
1558
1559sub pb_ssh_get {
1560
1561my $create = shift || 0; # Do not create keys by default
1562
1563# Check the SSH environment
1564my $keyfile = undef;
1565
1566# We have specific keys by default
1567$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
1568if (!(-e $keyfile) && ($create eq 1)) {
1569 pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
1570}
1571
1572$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
1573$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
1574$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
1575die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
1576return($keyfile);
1577}
1578
1579
1580# Returns the pid of a running VM command using a specific VM file
1581sub pb_check_ps {
1582 my $vmcmd = shift;
1583 my $vmm = shift;
1584 my $vmexist = 0; # FALSE by default
1585
1586 open(PS, "ps auxhww|") || die "Unable to call ps";
1587 while (<PS>) {
1588 next if (! /$vmcmd/);
1589 next if (! /$vmm/);
1590 my ($void1, $void2);
1591 ($void1, $vmexist, $void2) = split(/ +/);
1592 last;
1593 }
1594 return($vmexist);
1595}
1596
1597
1598sub pb_extract_build_files {
1599
1600my $src=shift;
1601my $dir=shift;
1602my $ddir=shift;
1603my @files;
1604
1605if ($src =~ /tar\.gz$/) {
1606 pb_system("tar xfpz $src $dir","Extracting build files");
1607} elsif ($src =~ /tar\.bz2$/) {
1608 pb_system("tar xfpj $src $dir","Extracting build files");
1609} else {
1610 die "Unknown compression algorithm for $src";
1611}
1612opendir(DIR,"$dir") || die "Unable to open directory $dir";
1613foreach my $f (readdir(DIR)) {
1614 next if ($f =~ /^\./);
1615 move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
1616 pb_log(2,"mv $dir/$f $ddir\n");
1617 push @files,"$ddir/$f";
1618}
1619closedir(DIR);
1620# Not enough but still a first cleanup
1621pb_rm_rf("$dir");
1622return(@files);
1623}
1624
1625sub pb_list_bfiles {
1626
1627my $dir = shift;
1628my $pbpkg = shift;
1629my $bfiles = shift;
1630my $pkgfiles = shift;
1631my $supfiles = shift;
1632
1633opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
1634foreach my $f (readdir(BDIR)) {
1635 next if ($f =~ /^\./);
1636 $bfiles->{$f} = "$dir/$f";
1637 $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
1638 if (defined $supfiles->{$pbpkg}) {
1639 $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
1640 }
1641}
1642closedir(BDIR);
1643}
1644
1645sub pb_env_init {
1646
1647my $proj=shift || undef;
1648my $pbinit=shift || undef;
1649my $action=shift;
1650my $ver;
1651my $tag;
1652
1653$ENV{'PBETC'} = "$ENV{'HOME'}/.pbrc";
1654
1655# We only have one configuration file for now.
1656pb_conf_init("$ENV{'PBETC'}");
1657
1658#
1659# Check project name
1660# Could be with env var PBPROJ
1661# or option -p
1662# if not define take the first in conf file
1663#
1664if ((defined $ENV{'PBPROJ'}) &&
1665 (not (defined $proj))) {
1666 $proj = $ENV{'PBPROJ'};
1667}
1668
1669#
1670# We get the pbconf file for that project
1671# and use its content
1672#
1673my ($pbconf) = pb_conf_get("pbconfurl");
1674pb_log(2,"DEBUG pbconfurl: ".Dumper($pbconf)."\n");
1675
1676my %pbconf = %$pbconf;
1677if (not defined $proj) {
1678 # Take the first as the default project
1679 $proj = (keys %pbconf)[0];
1680 if (defined $proj) {
1681 pb_log(1,"WARNING: using $proj as default project as none has been specified\n");
1682 pb_log(1," Please either create a pbconfurl reference for project $proj in $ENV{'PBETC'}\n");
1683 pb_log(1," or call pb with the -p project option or use the env var PBPROJ\n");
1684 pb_log(1," if you want to use another project\n");
1685 }
1686}
1687die "No project defined - use env var PBPROJ or -p proj or a pbconfurl entry in $ENV{'PBETC'}" if (not (defined $proj));
1688
1689# That's always the environment variable that will be used
1690$ENV{'PBPROJ'} = $proj;
1691pb_log(2,"PBPROJ: $ENV{'PBPROJ'}\n");
1692
1693if (not defined ($pbconf{$ENV{'PBPROJ'}})) {
1694 die "Please create a pbconfurl reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n";
1695}
1696
1697# Adds a potential conf file now as it's more
1698# important than the project conf file
1699my ($vmpath,$vepath) = pb_conf_get("vmpath","vepath");
1700pb_conf_add("$vmpath->{$ENV{'PBPROJ'}}/.pbrc") if (-f "$vmpath->{$ENV{'PBPROJ'}}/.pbrc");
1701pb_conf_add("$vepath->{$ENV{'PBPROJ'}}/.pbrc") if (-f "$vepath->{$ENV{'PBPROJ'}}/.pbrc");
1702
1703#
1704# Detect the root dir for hosting all the content generated with pb
1705#
1706# Tree will look like this:
1707#
1708# maint pbdefdir PBDEFDIR dev dir (optional)
1709# | |
1710# ------------------------ --------------------
1711# | | | |
1712# pbproj1 pbproj2 PBPROJ pbproj1 pbproj2 PBPROJDIR
1713# | |
1714# --------------------------------------------- ----------
1715# * * * | | | * *
1716# tag dev pbconf ... build delivery PBCONFDIR dev tag
1717# | | | PBDESTDIR |
1718# --- ------ pbrc PBBUILDDIR -------
1719# | | | | |
1720# 1.1 dev tag 1.0 1.1 PBDIR
1721# |
1722# -------
1723# | |
1724# 1.0 1.1 PBROOTDIR
1725# |
1726# ----------------------------------
1727# | | | |
1728# pkg1 pbproj1.pb pbfilter pbcl
1729# |
1730# -----------------
1731# | | |
1732# rpm deb pbfilter
1733#
1734#
1735# (*) By default, if no relocation in .pbrc, dev dir is taken in the maint pbdefdir (when appropriate)
1736# Names under a pbproj and the corresponding pbconf should be similar
1737#
1738
1739my ($pbdefdir) = pb_conf_get_if("pbdefdir");
1740
1741if (not defined $ENV{'PBDEFDIR'}) {
1742 if ((not defined $pbdefdir) || (not defined $pbdefdir->{$ENV{'PBPROJ'}})) {
1743 pb_log(1,"WARNING: no pbdefdir defined, using /var/cache\n");
1744 pb_log(1," Please create a pbdefdir reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
1745 pb_log(1," if you want to use another directory\n");
1746 $ENV{'PBDEFDIR'} = "/var/cache";
1747 } else {
1748 # That's always the environment variable that will be used
1749 $ENV{'PBDEFDIR'} = $pbdefdir->{$ENV{'PBPROJ'}};
1750 }
1751}
1752# Expand potential env variable in it
1753eval { $ENV{'PBDEFDIR'} =~ s/(\$ENV.+\})/$1/eeg };
1754
1755pb_log(2,"PBDEFDIR: $ENV{'PBDEFDIR'}\n");
1756#
1757# Set delivery directory
1758#
1759$ENV{'PBDESTDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/delivery";
1760
1761pb_log(2,"PBDESTDIR: $ENV{'PBDESTDIR'}\n");
1762#
1763# Removes all directory existing below the delivery dir
1764# as they are temp dir only
1765# Files stay and have to be cleaned up manually if needed
1766# those files serves as communication channels between pb phases
1767# Removing them prevents a following phase to detect what has been done before
1768#
1769if (-d $ENV{'PBDESTDIR'}) {
1770 opendir(DIR,$ENV{'PBDESTDIR'}) || die "Unable to open directory $ENV{'PBDESTDIR'}: $!";
1771 foreach my $d (readdir(DIR)) {
1772 next if ($d =~ /^\./);
1773 next if (-f "$ENV{'PBDESTDIR'}/$d");
1774 pb_rm_rf("$ENV{'PBDESTDIR'}/$d") if (-d "$ENV{'PBDESTDIR'}/$d");
1775 }
1776 closedir(DIR);
1777}
1778if (! -d "$ENV{'PBDESTDIR'}") {
1779 pb_mkdir_p($ENV{'PBDESTDIR'}) || die "Unable to recursively create $ENV{'PBDESTDIR'}";
1780}
1781
1782#
1783# Set build directory
1784#
1785$ENV{'PBBUILDDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/build";
1786if (! -d "$ENV{'PBBUILDDIR'}") {
1787 pb_mkdir_p($ENV{'PBBUILDDIR'}) || die "Unable to recursively create $ENV{'PBBUILDDIR'}";
1788}
1789
1790pb_log(2,"PBBUILDDIR: $ENV{'PBBUILDDIR'}\n");
1791
1792pb_temp_init();
1793pb_log(2,"PBTMP: $ENV{'PBTMP'}\n");
1794
1795#
1796# The following part is only useful when in cms2something of newver
1797# In VMs/VEs we want to skip that by providing good env vars.
1798# return values in that case are useless
1799#
1800if (($action =~ /^cms2/) || ($action =~ /^newver$/)) {
1801
1802 #
1803 # Check pbconf cms compliance
1804 #
1805 pb_cms_compliant("pbconfdir",'PBCONFDIR',"$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/pbconf",$pbconf{$ENV{'PBPROJ'}},$pbinit);
1806
1807 # Check where is our PBROOTDIR (release tag name can't be guessed the first time)
1808 #
1809 if (not defined $ENV{'PBROOTDIR'}) {
1810 if (! -f ("$ENV{'PBDESTDIR'}/pbrc")) {
1811 opendir(DIR,$ENV{'PBCONFDIR'}) || die "Unable to open directory $ENV{'PBCONFDIR'}: $!";
1812 my $maxmtime = 0;
1813 foreach my $d (readdir(DIR)) {
1814 pb_log(3,"Looking at \'$d\'...");
1815 next if ($d =~ /^\./);
1816 next if (! -d "$ENV{'PBCONFDIR'}/$d");
1817 my $s = stat("$ENV{'PBCONFDIR'}/$d");
1818 next if (not defined $s);
1819 pb_log(3,"KEEP\n");
1820 # Keep the most recent
1821 pb_log(2," $s->mtime\n");
1822 if ($s->mtime > $maxmtime) {
1823 $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$d";
1824 $maxmtime = $s->mtime;
1825 }
1826 }
1827 closedir(DIR);
1828 die "No directory found under $ENV{'PBCONFDIR'}" if (not defined $ENV{'PBROOTDIR'});
1829 pb_log(1,"WARNING: no pbroot defined, using $ENV{'PBROOTDIR'}\n");
1830 pb_log(1," Please use -r release if you want to use another release\n");
1831 } else {
1832 my ($pbroot) = pb_conf_read_if("$ENV{'PBDESTDIR'}/pbrc","pbroot");
1833 # That's always the environment variable that will be used
1834 die "Please remove inconsistent $ENV{'PBDESTDIR'}/pbrc" if ((not defined $pbroot) || (not defined $pbroot->{$ENV{'PBPROJ'}}));
1835 $ENV{'PBROOTDIR'} = $pbroot->{$ENV{'PBPROJ'}};
1836 }
1837 } else {
1838 # transform in full path if relative
1839 $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$ENV{'PBROOTDIR'}" if ($ENV{'PBROOTDIR'} !~ /^\//);
1840 pb_mkdir_p($ENV{'PBROOTDIR'}) if (defined $pbinit);
1841 die "$ENV{'PBROOTDIR'} is not a directory" if (not -d $ENV{'PBROOTDIR'});
1842 }
1843
1844 # Adds that conf file to the list to consider
1845 pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") if (-f "$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
1846
1847 return if ($action =~ /^newver$/);
1848
1849 my %version = ();
1850 my %defpkgdir = ();
1851 my %extpkgdir = ();
1852 my %filteredfiles = ();
1853 my %supfiles = ();
1854
1855 if ((-f "$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") and (not defined $pbinit)) {
1856
1857 # List of pkg to build by default (mandatory)
1858 my ($defpkgdir,$pbpackager, $pkgv, $pkgt) = pb_conf_get("defpkgdir","pbpackager","projver","projtag");
1859 # List of additional pkg to build when all is called (optional)
1860 # Valid version names (optional)
1861 # List of files to filter (optional)
1862 # Project version and tag (optional)
1863 my ($extpkgdir, $version, $filteredfiles, $supfiles) = pb_conf_get_if("extpkgdir","version","filteredfiles","supfiles");
1864 pb_log(2,"DEBUG: defpkgdir: ".Dumper($defpkgdir)."\n");
1865 pb_log(2,"DEBUG: extpkgdir: ".Dumper($extpkgdir)."\n");
1866 pb_log(2,"DEBUG: version: ".Dumper($version)."\n");
1867 pb_log(2,"DEBUG: filteredfiles: ".Dumper($filteredfiles)."\n");
1868 pb_log(2,"DEBUG: supfiles: ".Dumper($supfiles)."\n");
1869 # Global
1870 %defpkgdir = %$defpkgdir;
1871 %extpkgdir = %$extpkgdir if (defined $extpkgdir);
1872 %version = %$version if (defined $version);
1873 %filteredfiles = %$filteredfiles if (defined $filteredfiles);
1874 %supfiles = %$supfiles if (defined $supfiles);
1875 #
1876 # Get global Version/Tag
1877 #
1878 if (not defined $ENV{'PBPROJVER'}) {
1879 if ((defined $pkgv) && (defined $pkgv->{$ENV{'PBPROJ'}})) {
1880 $ENV{'PBPROJVER'}=$pkgv->{$ENV{'PBPROJ'}};
1881 } else {
1882 die "No projver found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1883 }
1884 }
1885 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'}}/));
1886
1887 if (not defined $ENV{'PBPROJTAG'}) {
1888 if ((defined $pkgt) && (defined $pkgt->{$ENV{'PBPROJ'}})) {
1889 $ENV{'PBPROJTAG'}=$pkgt->{$ENV{'PBPROJ'}};
1890 } else {
1891 die "No projtag found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1892 }
1893 }
1894 die "Invalid tag name $ENV{'PBPROJTAG'} in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb" if ($ENV{'PBPROJTAG'} !~ /[0-9.]+/);
1895
1896
1897 if (not defined $ENV{'PBPACKAGER'}) {
1898 if ((defined $pbpackager) && (defined $pbpackager->{$ENV{'PBPROJ'}})) {
1899 $ENV{'PBPACKAGER'}=$pbpackager->{$ENV{'PBPROJ'}};
1900 } else {
1901 die "No pbpackager found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1902 }
1903 }
1904 } else {
1905 if (defined $pbinit) {
1906 my $ptr = pb_get_pkg();
1907 my @pkgs = @$ptr;
1908 @pkgs = ("pkg1") if (not @pkgs);
1909
1910 open(CONF,"> $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") || die "Unable to create $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
1911 print CONF << "EOF";
1912#
1913# Project Builder configuration file
1914# For project $ENV{'PBPROJ'}
1915#
1916# \$Id\$
1917#
1918
1919#
1920# What is the project URL
1921#
1922#pburl $ENV{'PBPROJ'} = svn://svn.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1923#pburl $ENV{'PBPROJ'} = svn://svn+ssh.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1924#pburl $ENV{'PBPROJ'} = cvs://cvs.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
1925#pburl $ENV{'PBPROJ'} = http://www.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
1926#pburl $ENV{'PBPROJ'} = ftp://ftp.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
1927#pburl $ENV{'PBPROJ'} = file:///src/$ENV{'PBPROJ'}-devel.tar.gz
1928#pburl $ENV{'PBPROJ'} = dir:///src/$ENV{'PBPROJ'}-devel
1929
1930# Check whether project is well formed
1931# (containing already a directory with the project-version name)
1932#pbwf $ENV{'PBPROJ'} = 1
1933
1934#
1935# Packager label
1936#
1937#pbpackager $ENV{'PBPROJ'} = William Porte <bill\@$ENV{'PBPROJ'}.org>
1938#
1939
1940# For delivery to a machine by SSH (potentially the FTP server)
1941# Needs hostname, account and directory
1942#
1943#sshhost $ENV{'PBPROJ'} = www.$ENV{'PBPROJ'}.org
1944#sshlogin $ENV{'PBPROJ'} = bill
1945#sshdir $ENV{'PBPROJ'} = /$ENV{'PBPROJ'}/ftp
1946#sshport $ENV{'PBPROJ'} = 22
1947
1948#
1949# For Virtual machines management
1950# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
1951# followed by '-' and by release number
1952# followed by '-' and by architecture
1953# a .vmtype extension will be added to the resulting string
1954# a QEMU rhel-3-i286 here means that the VM will be named rhel-3-i386.qemu
1955#
1956#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
1957
1958#
1959# Valid values for vmtype are
1960# qemu, (vmware, xen, ... TBD)
1961#vmtype $ENV{'PBPROJ'} = qemu
1962
1963# Hash for VM stuff on vmtype
1964#vmntp default = pool.ntp.org
1965
1966# We suppose we can commmunicate with the VM through SSH
1967#vmhost $ENV{'PBPROJ'} = localhost
1968#vmlogin $ENV{'PBPROJ'} = pb
1969#vmport $ENV{'PBPROJ'} = 2222
1970
1971# Timeout to wait when VM is launched/stopped
1972#vmtmout default = 120
1973
1974# per VMs needed paramaters
1975#vmopt $ENV{'PBPROJ'} = -m 384 -daemonize
1976#vmpath $ENV{'PBPROJ'} = /home/qemu
1977#vmsize $ENV{'PBPROJ'} = 5G
1978
1979#
1980# For Virtual environment management
1981# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
1982# followed by '-' and by release number
1983# followed by '-' and by architecture
1984# a .vetype extension will be added to the resulting string
1985# a chroot rhel-3-i286 here means that the VE will be named rhel-3-i386.chroot
1986#
1987#velist $ENV{'PBPROJ'} = fedora-7-i386
1988
1989# VE params
1990#vetype $ENV{'PBPROJ'} = chroot
1991#ventp default = pool.ntp.org
1992#velogin $ENV{'PBPROJ'} = pb
1993#vepath $ENV{'PBPROJ'} = /var/lib/mock
1994#veconf $ENV{'PBPROJ'} = /etc/mock
1995#verebuild $ENV{'PBPROJ'} = false
1996
1997#
1998# Global version/tag for the project
1999#
2000#projver $ENV{'PBPROJ'} = devel
2001#projtag $ENV{'PBPROJ'} = 1
2002
2003# Hash of valid version names
2004#version $ENV{'PBPROJ'} = devel,stable
2005
2006# Adapt to your needs:
2007# Optional if you need to overwrite the global values above
2008#
2009EOF
2010
2011 foreach my $pp (@pkgs) {
2012 print CONF << "EOF";
2013#pkgver $pp = stable
2014#pkgtag $pp = 3
2015EOF
2016 }
2017 foreach my $pp (@pkgs) {
2018 print CONF << "EOF";
2019# Hash of default package/package directory
2020#defpkgdir $pp = dir-$pp
2021EOF
2022 }
2023
2024 print CONF << "EOF";
2025# Hash of additional package/package directory
2026#extpkgdir minor-pkg = dir-minor-pkg
2027
2028# List of files per pkg on which to apply filters
2029# Files are mentioned relatively to pbroot/defpkgdir
2030EOF
2031 foreach my $pp (@pkgs) {
2032 print CONF << "EOF";
2033#filteredfiles $pp = Makefile.PL,configure.in,install.sh,$pp.8
2034#supfiles $pp = $pp.init
2035EOF
2036 }
2037 close(CONF);
2038 pb_mkdir_p("$ENV{'PBROOTDIR'}/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter";
2039 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/all.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/all.pbf";
2040 print CONF << "EOF";
2041#
2042# \$Id\$
2043#
2044# Filter for all files
2045#
2046# PBSRC is replaced by the source package format
2047#filter PBSRC = ftp://ftp.$ENV{'PBPROJ'}.org/src/%{name}-%{version}.tar.gz
2048
2049# PBVER is replaced by the version (\$pbver in code)
2050filter PBVER = \$pbver
2051
2052# PBDATE is replaced by the date (\$pbdate in code)
2053filter PBDATE = \$pbdate
2054
2055# PBLOG is replaced by the changelog if value is yes
2056#filter PBLOG = yes
2057
2058# PBTAG is replaced by the tag (\$pbtag in code)
2059filter PBTAG = \$pbtag
2060
2061# PBREV is replaced by the revision (\$pbrev in code)
2062filter PBREV = \$pbrev
2063
2064# PBPKG is replaced by the package name (\$pbpkg in code)
2065filter PBPKG = \$pbpkg
2066
2067# PBPACKAGER is replaced by the packager name (\$pbpackager in code)
2068filter PBPACKAGER = \$pbpackager
2069
2070# PBDESC contains the description of the package
2071#filter PBDESC = "Bla-Bla"
2072
2073# PBURL contains the URL of the Web site of the project
2074#filter PBURL = http://www.$ENV{'PBPROJ'}.org
2075EOF
2076 close(CONF);
2077 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf";
2078 print CONF << "EOF";
2079#
2080# \$Id\$
2081#
2082# Filter for rpm build
2083#
2084
2085# PBGRP is replaced by the RPM group of apps
2086# Cf: http://fedoraproject.org/wiki/RPMGroups
2087#filter PBGRP = Applications/Archiving
2088
2089# PBLIC is replaced by the license of the application
2090# Cf: http://fedoraproject.org/wiki/Licensing
2091#filter PBLIC = GPL
2092
2093# PBDEP is replaced by the list of dependencies
2094#filter PBDEP =
2095
2096# PBSUF is replaced by the package suffix (\$pbsuf in code)
2097filter PBSUF = \$pbsuf
2098
2099# PBOBS is replaced by the Obsolete line
2100#filter PBOBS =
2101
2102EOF
2103 close(CONF);
2104 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/deb.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/deb.pbf";
2105 print CONF << "EOF";
2106#
2107# \$Id\$
2108#
2109# Filter for debian build
2110#
2111# PBGRP is replaced by the group of apps
2112filter PBGRP = utils
2113
2114# PBLIC is replaced by the license of the application
2115# Cf:
2116#filter PBLIC = GPL
2117
2118# PBDEP is replaced by the list of dependencies
2119#filter PBDEP =
2120
2121# PBSUG is replaced by the list of suggestions
2122#filter PBSUG =
2123
2124# PBREC is replaced by the list of recommandations
2125#filter PBREC =
2126
2127EOF
2128 close(CONF);
2129 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/md.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/md.pbf";
2130 print CONF << "EOF";
2131# Specific group for Mandriva for $ENV{'PBPROJ'}
2132# Cf: http://wiki.mandriva.com/en/Development/Packaging/Groups
2133#filter PBGRP = Archiving/Backup
2134
2135# PBLIC is replaced by the license of the application
2136# Cf: http://wiki.mandriva.com/en/Development/Packaging/Licenses
2137#filter PBLIC = GPL
2138
2139EOF
2140 close(CONF);
2141 open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/novell.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/novell.pbf";
2142 print CONF << "EOF";
2143# Specific group for SuSE for $ENV{'PBPROJ'}
2144# Cf: http://en.opensuse.org/SUSE_Package_Conventions/RPM_Groups
2145#filter PBGRP = Productivity/Archiving/Backup
2146
2147# PBLIC is replaced by the license of the application
2148# Cf: http://en.opensuse.org/Packaging/SUSE_Package_Conventions/RPM_Style#1.6._License_Tag
2149#filter PBLIC = GPL
2150
2151EOF
2152 close(CONF);
2153 foreach my $pp (@pkgs) {
2154 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/deb") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb";
2155 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/control") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/control";
2156 print CONF << "EOF";
2157Source: PBPKG
2158Section: PBGRP
2159Priority: optional
2160Maintainer: PBPACKAGER
2161Build-Depends: debhelper (>= 4.2.20), PBDEP
2162Standards-Version: 3.6.1
2163
2164Package: PBPKG
2165Architecture: amd64 i386 ia64
2166Section: PBGRP
2167Priority: optional
2168Depends: \${shlibs:Depends}, \${misc:Depends}, PBDEP
2169Recommends: PBREC
2170Suggests: PBSUG
2171Description:
2172 PBDESC
2173 .
2174 Homepage: PBURL
2175
2176EOF
2177 close(CONF);
2178 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/copyright") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/copyright";
2179 print CONF << "EOF";
2180This package is debianized by PBPACKAGER
2181`date`
2182
2183The current upstream source was downloaded from
2184ftp://ftp.$ENV{'PBPROJ'}.org/src/.
2185
2186Upstream Authors: Put their name here
2187
2188Copyright:
2189
2190 This package is free software; you can redistribute it and/or modify
2191 it under the terms of the GNU General Public License as published by
2192 the Free Software Foundation; version 2 dated June, 1991.
2193
2194 This package is distributed in the hope that it will be useful,
2195 but WITHOUT ANY WARRANTY; without even the implied warranty of
2196 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2197 GNU General Public License for more details.
2198
2199 You should have received a copy of the GNU General Public License
2200 along with this package; if not, write to the Free Software
2201 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
2202 MA 02110-1301, USA.
2203
2204On Debian systems, the complete text of the GNU General
2205Public License can be found in /usr/share/common-licenses/GPL.
2206
2207EOF
2208 close(CONF);
2209 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/changelog") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/changelog";
2210 print CONF << "EOF";
2211PBLOG
2212EOF
2213 close(CONF);
2214 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/compat") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/compat";
2215 print CONF << "EOF";
22164
2217EOF
2218 close(CONF);
2219 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs";
2220 print CONF << "EOF";
2221EOF
2222 close(CONF);
2223 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs";
2224 print CONF << "EOF";
2225INSTALL
2226COPYING
2227AUTHORS
2228NEWS
2229README
2230EOF
2231 close(CONF);
2232 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/rules") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/rules";
2233 print CONF << 'EOF';
2234#!/usr/bin/make -f
2235# -*- makefile -*-
2236# Sample debian/rules that uses debhelper.
2237# GNU copyright 1997 to 1999 by Joey Hess.
2238#
2239# $Id$
2240#
2241
2242# Uncomment this to turn on verbose mode.
2243#export DH_VERBOSE=1
2244
2245# Define package name variable for a one-stop change.
2246PACKAGE_NAME = PBPKG
2247
2248# These are used for cross-compiling and for saving the configure script
2249# from having to guess our platform (since we know it already)
2250DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
2251DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
2252
2253CFLAGS = -Wall -g
2254
2255ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
2256 CFLAGS += -O0
2257else
2258 CFLAGS += -O2
2259endif
2260ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
2261 INSTALL_PROGRAM += -s
2262endif
2263config.status: configure
2264 dh_testdir
2265
2266 # Configure the package.
2267 CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr
2268 --mandir=\$${prefix}/share/man
2269
2270# Build both architecture dependent and independent
2271build: build-arch build-indep
2272
2273# Build architecture dependent
2274build-arch: build-arch-stamp
2275
2276build-arch-stamp: config.status
2277 dh_testdir
2278
2279 # Compile the package.
2280 $(MAKE)
2281
2282 touch build-stamp
2283
2284# Build architecture independent
2285build-indep: build-indep-stamp
2286
2287build-indep-stamp: config.status
2288 # Nothing to do, the only indep item is the manual which is available as html in original source
2289 touch build-indep-stamp
2290
2291# Clean up
2292clean:
2293 dh_testdir
2294 dh_testroot
2295 rm -f build-arch-stamp build-indep-stamp #CONFIGURE-STAMP#
2296 # Clean temporary document directory
2297 rm -rf debian/doc-temp
2298 # Clean up.
2299 -$(MAKE) distclean
2300 rm -f config.log
2301ifneq "$(wildcard /usr/share/misc/config.sub)" ""
2302 cp -f /usr/share/misc/config.sub config.sub
2303endif
2304ifneq "$(wildcard /usr/share/misc/config.guess)" ""
2305 cp -f /usr/share/misc/config.guess config.guess
2306endif
2307
2308 dh_clean
2309
2310# Install architecture dependent and independent
2311install: install-arch install-indep
2312
2313# Install architecture dependent
2314install-arch: build-arch
2315 dh_testdir
2316 dh_testroot
2317 dh_clean -k -s
2318 dh_installdirs -s
2319
2320 # Install the package files into build directory:
2321 # - start with upstream make install
2322 $(MAKE) install prefix=$(CURDIR)/debian/$(PACKAGE_NAME)/usr mandir=$(CURDIR)/debian/$(PACKAGE_NAME)/us
2323r/share/man
2324 # - copy html manual to temporary location for renaming
2325 mkdir -p debian/doc-temp
2326 dh_install -s
2327
2328# Install architecture independent
2329install-indep: build-indep
2330 dh_testdir
2331 dh_testroot
2332 dh_clean -k -i
2333 dh_installdirs -i
2334 dh_install -i
2335
2336# Must not depend on anything. This is to be called by
2337# binary-arch/binary-indep
2338# in another 'make' thread.
2339binary-common:
2340 dh_testdir
2341 dh_testroot
2342 dh_installchangelogs ChangeLog
2343 dh_installdocs
2344 dh_installman
2345 dh_link
2346 dh_strip
2347 dh_compress
2348 dh_fixperms
2349 dh_installdeb
2350 dh_shlibdeps
2351 dh_gencontrol
2352 dh_md5sums
2353 dh_builddeb
2354
2355# Build architecture independant packages using the common target.
2356binary-indep: build-indep install-indep
2357 $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
2358
2359# Build architecture dependant packages using the common target.
2360binary-arch: build-arch install-arch
2361 $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
2362
2363# Build architecture depdendent and independent packages
2364binary: binary-arch binary-indep
2365.PHONY: clean binary
2366
2367EOF
2368 close(CONF);
2369 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/rpm") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm";
2370 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec";
2371 print CONF << 'EOF';
2372#
2373# $Id$
2374#
2375
2376Summary: bla-bla
2377Summary(fr): french bla-bla
2378
2379Name: PBPKG
2380Version: PBVER
2381Release: PBTAGPBSUF
2382License: PBLIC
2383Group: PBGRP
2384Url: PBURL
2385Source: PBSRC
2386BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -u -n)
2387#Requires: PBDEP
2388
2389%description
2390PBDESC
2391
2392%description -l fr
2393french desc
2394
2395%prep
2396%setup -q
2397
2398%build
2399%configure
2400make %{?_smp_mflags}
2401
2402%install
2403%{__rm} -rf $RPM_BUILD_ROOT
2404make DESTDIR=$RPM_BUILD_ROOT install
2405
2406%clean
2407%{__rm} -rf $RPM_BUILD_ROOT
2408
2409%files
2410%defattr(-,root,root)
2411%doc ChangeLog
2412%doc INSTALL COPYING README AUTHORS NEWS
2413
2414%changelog
2415PBLOG
2416
2417EOF
2418 close(CONF);
2419 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/pbfilter";
2420
2421 pb_log(0,"\nDo not to forget to commit the pbconf directory in your CMS if needed\n");
2422 }
2423 } else {
2424 die "Unable to open $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
2425 }
2426 }
2427 umask 0022;
2428 return(\%filteredfiles, \%supfiles, \%defpkgdir, \%extpkgdir);
2429} else {
2430 # Setup the variables from what has been stored at the end of cms2build
2431 my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbroot");
2432 $ENV{'PBROOTDIR'} = $var->{$ENV{'PBPROJ'}};
2433
2434 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projver");
2435 $ENV{'PBPROJVER'} = $var->{$ENV{'PBPROJ'}};
2436
2437 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projtag");
2438 $ENV{'PBPROJTAG'} = $var->{$ENV{'PBPROJ'}};
2439
2440 ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbpackager");
2441 $ENV{'PBPACKAGER'} = $var->{$ENV{'PBPROJ'}};
2442
2443 return;
2444}
2445}
2446
2447#
2448# Return the list of packages we are working on in a non CMS action
2449#
2450sub pb_get_pkg {
2451
2452my @pkgs = ();
2453
2454my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
2455@pkgs = keys %$var;
2456
2457pb_log(0,"Packages: ".join(',',@pkgs)."\n");
2458return(\@pkgs);
2459}
2460
24611;
Note: See TracBrowser for help on using the repository browser.