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

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

Fix an issue of generation on redhat and rhas2.1 where _target_platform in %configure is incorrect

  • Property svn:executable set to *
File size: 56.3 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::Env;
28use ProjectBuilder::Filter;
29
30# Global variables
31my %opts; # CLI Options
32my $action; # action to realize
33my $test = "FALSE"; # Not used
34my $force = 0; # Force VE/VM rebuild
35my $option = ""; # Not used
36my @pkgs; # list of packages
37my $pbtag; # Global Tag variable
38my $pbver; # Global Version variable
39my $pbscript; # Name of the script
40my %pbver; # per package
41my %pbtag; # per package
42my $pbrev; # Global REVISION variable
43my $pbaccount; # Login to use to connect to the VM
44my $pbport; # Port to use to connect to the VM
45my $newver; # New version to create
46my $iso; # ISO image for the VM to create
47
48my @date = pb_get_date();
49my $pbdate = strftime("%Y-%m-%d", @date);
50
51=pod
52
53=head1 NAME
54
55pb, aka project-builder.org - builds packages for your projects
56
57=head1 DESCRIPTION
58
59pb helps you build various packages directly from your project sources.
60Those sources could be handled by a CMS (Configuration Management System)
61such as Subversion, CVS, ... or being a simple reference to a compressed tar file.
62It's based on a set of configuration files, a set of provided macros to help
63you keeping build files as generic as possible. For example, a single .spec
64file should be required to generate for all rpm based distributions, even
65if you could also have multiple .spec files if required.
66
67=head1 SYNOPSIS
68
69pb [-vhq][-r pbroot][-p project][[-s script -a account -P port][-m mach-1[,...]]][-i iso] <action> [<pkg1> ...]
70
71pb [--verbose][--help][--man][--quiet][--revision pbroot][--project project][[--script script --account account --port port][--machine mach-1[,...]]][--iso iso] <action> [<pkg1> ...]
72
73=head1 OPTIONS
74
75=over 4
76
77=item B<-v|--verbose>
78
79Print a brief help message and exits.
80
81=item B<-q|--quiet>
82
83Do not print any output.
84
85=item B<-h|--help>
86
87Print a brief help message and exits.
88
89=item B<--man>
90
91Prints the manual page and exits.
92
93=item B<-m|--machine machine1[,machine2,...]>
94
95Name of the Virtual Machines (VM) or Virtual Environments (VE) you want to build on (coma separated).
96All if none precised (or use the env variable PBV).
97
98=item B<-s|--script script>
99
100Name of the script you want to execute on the related VMs or VEs.
101
102=item B<-i|--iso iso_image>
103
104Name of the ISO image of the distribution you want to install on the related VMs.
105
106=item B<-a|--account account>
107
108Name of the account to use to connect on the related VMs.
109
110=item B<-P|--port port_number>
111
112Port number to use to connect on the related VMs.\n";
113
114=item B<-p|--project project_name>
115
116Name of the project you're working on (or use the env variable PBPROJ)
117
118=item B<-r|--revision revision>
119
120Path Name of the project revision under the CMS (or use the env variable PBROOT)
121
122=item B<-V|--version new_version>
123
124New version of the project to create based on the current one.
125
126=back
127
128=head1 ARGUMENTS
129
130<action> can be:
131
132=over 4
133
134=item B<cms2build>
135
136Create tar files for the project under your CMS.
137CMS supported are SVN and CVS
138parameters are packages to build
139if not using default list
140
141=item B<build2pkg>
142
143Create packages for your running distribution
144
145=item B<cms2pkg>
146
147cms2build + build2pkg
148
149=item B<build2ssh>
150
151Send the tar files to a SSH host
152
153=item B<cms2ssh>
154
155cms2build + build2ssh
156
157=item B<pkg2ssh>
158
159Send the packages built to a SSH host
160
161=item B<build2vm>
162
163Create packages in VMs, launching them if needed
164and send those packages to a SSH host once built
165VM type supported are QEMU
166
167=item B<build2ve>
168
169Create packages in VEs, creating it if needed
170and send those packages to a SSH host once built
171
172=item B<cms2vm>
173
174cms2build + build2vm
175
176=item B<cms2ve>
177
178cms2build + build2ve
179
180=item B<launchvm>
181
182Launch one virtual machine
183
184=item B<launchve>
185
186Launch one virtual environment
187
188=item B<script2vm>
189
190Launch one virtual machine if needed
191and executes a script on it
192
193=item B<script2ve>
194
195Execute a script in a virtual environment
196
197=item B<newvm>
198
199Create a new virtual machine
200
201=item B<newve>
202
203Create a new virtual environment
204
205=item B<setupvm>
206
207Setup a virtual machine for pb usage
208
209=item B<setupve>
210
211Setup a virtual environment for pb usage
212
213=item B<newver>
214
215Create a new version of the project derived
216from the current one
217
218=item B<newproj>
219
220Create a new project and a template set of
221configuration files under pbconf
222
223=back
224
225<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).
226
227=head1 WEB SITES
228
229The 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/>.
230
231=head1 USER MAILING LIST
232
233None exists for the moment.
234
235=head1 CONFIGURATION FILES
236
237Each pb user may have a configuration in F<$HOME/.pbrc>. The values in this file may overwrite any other configuration file value.
238
239Here is an example of such a configuration file:
240
241 #
242 # Define for each project the URL of its pbconf repository
243 # No default option allowed here as they need to be all different
244 #
245 # URL of the pbconf content
246 # This is the format of a classical URL with the extension of additional schema such as
247 # svn+ssh, cvs+ssh, ...
248 #
249 pbconfurl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe/pbconf
250
251 # This is normaly defined in the project's configuration file
252 # Url of the project
253 #
254 pburl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe
255
256 # All these URLs needs to be defined here as the are the entry point
257 # for how to build packages for the project
258 #
259 pbconfurl pb = svn+ssh://svn.project-builder.org/mondo/svn/pb/pbconf
260 pbconfurl mondorescue = svn+ssh://svn.project-builder.org/mondo/svn/project-builder/mondorescue/pbconf
261 pbconfurl collectl = svn+ssh://bruno@svn.mondorescue.org/mondo/svn/project-builder/collectl/pbconf
262 pbconfurl netperf = svn+ssh://svn.mondorescue.org/mondo/svn/project-builder/netperf/pbconf
263
264 # Under that dir will take place everything related to pb
265 # If you want to use VMs/chroot/..., then use $ENV{'HOME'} to make it portable
266 # to your VMs/chroot/...
267 # if not defined then /var/cache
268 pbdefdir default = $ENV{'HOME'}/project-builder
269 pbdefdir pb = $ENV{'HOME'}
270 pbdefdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
271 pbdefdir mondorescue = $ENV{'HOME'}/mondo/svn
272
273 # pbconfdir points to the directory where the CMS content of the pbconfurl is checked out
274 # If not defined, pbconfdir is under pbdefdir/pbproj/pbconf
275 pbconfdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs/pbconf
276 pbconfdir mondorescue = $ENV{'HOME'}/mondo/svn/pbconf
277
278 # pbdir points to the directory where the CMS content of the pburl is checked out
279 # If not defined, pbdir is under pbdefdir/pbproj
280 # Only defined if we have access to the dev of the project
281 pbdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
282 pbdir mondorescue = $ENV{'HOME'}/mondo/svn
283
284 # -daemonize doesn't work with qemu 0.8.2
285 vmopt default = -m 384
286
287=head1 AUTHORS
288
289The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
290
291=head1 COPYRIGHT
292
293Project-Builder.org is distributed under the GPL v2.0 license
294described in the file C<COPYING> included with the distribution.
295
296=cut
297
298# ---------------------------------------------------------------------------
299
300# Old syntax
301#getopts('a:fhi:l:m:P:p:qr:s:vV:',\%opts);
302
303my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
304
305# Initialize the syntax string
306
307pb_syntax_init("pb (aka project-builder.org) Version $projectbuilderver-$projectbuilderrev\n");
308
309GetOptions("help|?|h" => \$opts{'h'},
310 "man" => \$opts{'man'},
311 "verbose|v+" => \$opts{'v'},
312 "quiet|q" => \$opts{'q'},
313 "log-files|l=s" => \$opts{'l'},
314 "force|f" => \$opts{'f'},
315 "account|a=s" => \$opts{'a'},
316 "revision|r=s" => \$opts{'r'},
317 "script|s=s" => \$opts{'s'},
318 "machines|mock|m=s" => \$opts{'m'},
319 "port|P=i" => \$opts{'P'},
320 "project|p=s" => \$opts{'p'},
321 "iso|i=s" => \$opts{'i'},
322 "version|V=s" => \$opts{'V'},
323) || pb_syntax(-1,0);
324
325if (defined $opts{'h'}) {
326 pb_syntax(0,1);
327}
328if (defined $opts{'man'}) {
329 pb_syntax(0,2);
330}
331if (defined $opts{'v'}) {
332 $debug = $opts{'v'};
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 and repo for filtering
449 my ($tmp1, $tmp2) = pb_conf_get("pbpackager","pbrepo");
450 $ENV{'PBPACKAGER'} = $tmp1->{$ENV{'PBPROJ'}};
451 $ENV{'PBREPO'} = $tmp2->{$ENV{'PBPROJ'}};
452
453 foreach my $pbpkg (@pkgs) {
454 $ENV{'PBPKG'} = $pbpkg;
455 if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
456 $pbver = $pkgv->{$pbpkg};
457 } else {
458 $pbver = $ENV{'PBPROJVER'};
459 }
460 if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
461 $pbtag = $pkgt->{$pbpkg};
462 } else {
463 $pbtag = $ENV{'PBPROJTAG'};
464 }
465
466 $pbrev = $ENV{'PBREVISION'};
467 pb_log(0,"\n");
468 pb_log(0,"Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n");
469 die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
470 # Clean up dest if necessary. The export will recreate it
471 my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver";
472 pb_rm_rf($dest) if (-d $dest);
473
474 # Export CMS tree for the concerned package to dest
475 # And generate some additional files
476 $OUTPUT_AUTOFLUSH=1;
477
478 # computes in which dir we have to work
479 my $dir = $defpkgdir->{$pbpkg};
480 $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
481 pb_log(2,"def:".Dumper($defpkgdir)." ext: ".Dumper($extpkgdir)." \n");
482
483 # Exporting from CMS
484 pb_cms_export($uri,"$ENV{'PBDIR'}/$dir",$dest);
485
486 # Generated fake content for test versions to speed up stuff
487 my ($testver) = pb_conf_get_if("testver");
488 my $chglog;
489
490 # Get project info on authors and log file
491 $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
492 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
493 $chglog = undef if (! -f $chglog);
494
495 my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
496 $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
497 $authors = "/dev/null" if (! -f $authors);
498
499 # Extract cms log history and store it
500 if ((defined $chglog) && (! -f "$dest/NEWS")) {
501 pb_log(2,"Generating NEWS file from $chglog\n");
502 copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
503 }
504 pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors,$testver);
505
506 my %build;
507 my @pt;
508 my $tmpl = "";
509
510 @pt = pb_conf_get_if("vmlist","velist");
511 if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
512 $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
513 }
514 if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
515 # the 2 lists needs to be grouped with a ',' separated them
516 if ($tmpl ne "") {
517 $tmpl .= ",";
518 }
519 $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
520 }
521 foreach my $d (split(/,/,$tmpl)) {
522 my ($name,$ver,$arch) = split(/-/,$d);
523 chomp($arch);
524 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
525 pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n");
526 pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
527
528 # Filter build files from the less precise up to the most with overloading
529 # Filter all files found, keeping the name, and generating in dest
530
531 # Find all build files first relatively to PBROOTDIR
532 # Find also all specific files referenced in the .pb conf file
533 my %bfiles = ();
534 my %pkgfiles = ();
535 $build{"$ddir-$dver"} = "yes";
536
537 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dtype") {
538 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dtype",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
539 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dfam") {
540 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
541 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir") {
542 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
543 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver") {
544 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
545 } else {
546 $build{"$ddir-$dver"} = "no";
547 next;
548 }
549 pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
550
551 # Get all filters to apply
552 my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
553
554 # Apply now all the filters on all the files concerned
555 # destination dir depends on the type of file
556 if (defined $ptr) {
557 foreach my $f (values %bfiles,values %pkgfiles) {
558 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,$ENV{'PBPROJ'},$ENV{'PBREPO'});
559 }
560 }
561 }
562 my @found;
563 my @notfound;
564 foreach my $b (keys %build) {
565 push @found,$b if ($build{$b} =~ /yes/);
566 push @notfound,$b if ($build{$b} =~ /no/);
567 }
568 pb_log(0,"Build files generated for ".join(',',sort(@found))."\n");
569 pb_log(0,"No Build files found for ".join(',',sort(@notfound))."\n") if (@notfound);
570 # Get the generic filter (all.pbf) and
571 # apply those to the non-build files including those
572 # generated by pbinit if applicable
573
574 # Get only all.pbf filter
575 my $ptr = pb_get_filters($pbpkg);
576
577 my $liste ="";
578 if (defined $filteredfiles->{$pbpkg}) {
579 foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
580 pb_filter_file_inplace($ptr,"$dest/$f",$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'},$ENV{'PBPROJ'},$ENV{'PBREPO'});
581 $liste = "$f $liste";
582 }
583 }
584 pb_log(2,"Files ".$liste."have been filtered\n");
585
586 # Prepare the dest directory for archive
587 if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
588 pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'},$ENV{'PBPROJ'},$ENV{'PBREPO'});
589 chmod 0755,"$ENV{'PBTMP'}/pbinit";
590 pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit");
591 }
592
593 # Archive dest dir
594 chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
595 # Possibility to look at PBSRC to guess more the filename
596 pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
597 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
598
599 # Keep track of version-tag per pkg
600 $pkgs{$pbpkg} = "$pbver-$pbtag";
601
602 # Final cleanup
603 pb_rm_rf($dest) if (-d $dest);
604 }
605
606 # Keep track of per package version
607 pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
608 open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
609 foreach my $pbpkg (@pkgs) {
610 print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
611 }
612 close(PKG);
613
614 # Keep track of what is generated by default
615 # We need to store the dir and info on version-tag
616 # Base our content on the existing .pb file
617 copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
618 open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
619 print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
620 print LAST "pbprojver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
621 print LAST "pbprojtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
622 print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
623 close(LAST);
624}
625
626sub pb_build2pkg {
627
628 # Get the running distro to build on
629 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
630 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
631
632 # Get list of packages to build
633 # Get content saved in cms2build
634 my $ptr = pb_get_pkg();
635 @pkgs = @$ptr;
636
637 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
638 $pkg = { } if (not defined $pkg);
639
640 chdir "$ENV{'PBBUILDDIR'}";
641 my $made = ""; # pkgs made during build
642 foreach my $pbpkg (@pkgs) {
643 my $vertag = $pkg->{$pbpkg};
644 # get the version of the current package - maybe different
645 ($pbver,$pbtag) = split(/-/,$vertag);
646
647 my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
648 pb_log(2,"Source file: $src\n");
649
650 pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
651 if ($dtype eq "rpm") {
652 foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
653 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
654 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";
655 }
656 }
657
658 # Remove in case a previous link/file was there
659 unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
660 symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
661 # We need to first extract the spec file
662 my @specfile;
663 @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
664
665 pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
666 # set LANGUAGE to check for correct log messages
667 $ENV{'LANGUAGE'}="C";
668 # Older Redhat use _target_platform in %configure incorrectly
669 my $specialdef = "";
670 if (($ddir eq "redhat") || (($ddir eq "rhel") && ($dver eq "2.1"))) {
671 $specialdef = "--define \'_target_platform \"\"\'";
672 }
673 foreach my $f (@specfile) {
674 if ($f =~ /\.spec$/) {
675 pb_system("rpmbuild $specialdef --define \'packager $ENV{'PBPACKAGER'}\' --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
676 last;
677 }
678 }
679 $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
680 if (-f "/usr/bin/rpmlint") {
681 pb_system("rpmlint $made","Checking validity of rpms with rpmlint");
682 }
683 } elsif ($dtype eq "deb") {
684 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
685 pb_system("tar xfz $src","Extracting sources");
686
687 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
688 pb_rm_rf("debian");
689 symlink "pbconf/$ddir-$dver","debian" || die "Unable to symlink to pbconf/$ddir-$dver";
690 chmod 0755,"debian/rules";
691 if ($dver !~ /[0-9]/) {
692 # dpkg-deb doesn't accept non digit versions. removing checks
693 # dpkg-source checks upper case when generating perl modules
694 }
695 pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package");
696 $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
697 if (-f "/usr/bin/lintian") {
698 pb_system("lintian $made","Checking validity of debs with lintian");
699 }
700 } elsif ($dtype eq "ebuild") {
701 my @ebuildfile;
702 # For gentoo we need to take pb as subsystem name
703 # We put every apps here under sys-apps. hope it's correct
704 # We use pb's home dir in order to have a single OVERLAY line
705 my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
706 pb_mkdir_p($tmpd) if (! -d "$tmpd");
707 pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
708
709 # We need to first extract the ebuild file
710 @ebuildfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$tmpd");
711
712 # Prepare the build env for gentoo
713 my $found = 0;
714 my $pbbd = $ENV{'HOME'};
715 $pbbd =~ s|/|\\/|g;
716 if (-r "/etc/make.conf") {
717 open(MAKE,"/etc/make.conf");
718 while (<MAKE>) {
719 $found = 1 if (/$pbbd\/portage/);
720 }
721 close(MAKE);
722 }
723 if ($found == 0) {
724 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
725 }
726 #$found = 0;
727 #if (-r "/etc/portage/package.keywords") {
728 #open(KEYW,"/etc/portage/package.keywords");
729 #while (<KEYW>) {
730 #$found = 1 if (/portage\/pb/);
731 #}
732 #close(KEYW);
733 #}
734 #if ($found == 0) {
735 #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
736 #}
737
738 # Build
739 foreach my $f (@ebuildfile) {
740 if ($f =~ /\.ebuild$/) {
741 move($f,"$tmpd/$pbpkg-$pbver.ebuild");
742 pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package");
743 # Now move it where pb expects it
744 pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
745 move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
746 }
747 }
748
749 $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver.ebuild";
750 } elsif ($dtype eq "tgz") {
751 # Slackware family
752 $made="$made $pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
753
754 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
755 pb_system("tar xfz $src","Extracting sources");
756 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
757 symlink "pbconf/$ddir-$dver","install" || die "Unable to symlink to pbconf/$ddir-$dver";
758 if (-x "install/pbslack") {
759 pb_system("./install/pbslack","Building package");
760 pb_system("sudo /sbin/makepkg -p -l y -c y $pbpkg","Packaging $pbpkg");
761 }
762 } else {
763 die "Unknown dtype format $dtype";
764 }
765 }
766 # Keep track of what is generated so that we can get them back from VMs
767 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
768 print KEEP "$made\n";
769 close(KEEP);
770}
771
772sub pb_build2ssh {
773 pb_send2target("Sources");
774}
775
776sub pb_pkg2ssh {
777 pb_send2target("Packages");
778}
779
780# By default deliver to the the public site hosting the
781# ftp structure (or whatever) or a VM/VE
782sub pb_send2target {
783
784 my $cmt = shift;
785 my $v = shift || undef;
786 my $vmexist = shift || 0; # 0 is FALSE
787 my $vmpid = shift || 0; # 0 is FALSE
788
789 pb_log(2,"DEBUG: pb_send2target($cmt,".Dumper($v).",$vmexist,$vmpid)\n");
790 my $host = "sshhost";
791 my $login = "sshlogin";
792 my $dir = "sshdir";
793 my $port = "sshport";
794 my $conf = "sshconf";
795 my $rebuild = "sshrebuild";
796 my $tmout = "vmtmout";
797 my $path = "vmpath";
798 if (($cmt eq "vm") || ($cmt eq "Script")) {
799 $login = "vmlogin";
800 $dir = "pbdefdir";
801 $tmout = "vmtmout";
802 $rebuild = "vmrebuild";
803 # Specific VM
804 $host = "vmhost";
805 $port = "vmport";
806 } elsif ($cmt eq "ve") {
807 $login = "velogin";
808 $dir = "pbdefdir";
809 $tmout = "vetmout";
810 # Specific VE
811 $path = "vepath";
812 $conf = "veconf";
813 $rebuild = "verebuild";
814 }
815 my $cmd = "";
816
817 my $ptr = pb_get_pkg();
818 @pkgs = @$ptr;
819
820 # Get the running distro to consider
821 my ($odir,$over,$oarch) = (undef, undef, undef);
822 if (defined $v) {
823 ($odir,$over,$oarch) = split(/-/,$v);
824 }
825 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
826 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
827
828 # Get list of packages to build
829 # Get content saved in cms2build
830 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
831 $pkg = { } if (not defined $pkg);
832
833 my $src = "";
834 chdir "$ENV{'PBBUILDDIR'}";
835 foreach my $pbpkg (@pkgs) {
836 my $vertag = $pkg->{$pbpkg};
837 # get the version of the current package - maybe different
838 ($pbver,$pbtag) = split(/-/,$vertag);
839
840 if (($cmt eq "Sources") || ($cmt eq "vm") || ($cmt eq "ve")) {
841 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
842 if ($cmd eq "") {
843 $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
844 } else {
845 $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
846 }
847 }
848 }
849 # Adds conf file for availability of conf elements
850 pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
851
852 if (($cmt eq "vm") || ($cmt eq "ve")) {
853 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc $ENV{'PBDESTDIR'}/pbscript";
854 } elsif ($cmt eq "Script") {
855 $src="$src $ENV{'PBDESTDIR'}/pbscript";
856 } elsif ($cmt eq "Packages") {
857 # Get package list from file made during build2pkg
858 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
859 $src = <KEEP>;
860 chomp($src);
861 close(KEEP);
862 $src="$src $ENV{'PBBUILDDIR'}/pbscript" if ($cmt ne "Sources");
863 }
864 # Remove potential leading spaces (cause problem with basename)
865 $src =~ s/^ *//;
866 my $basesrc = "";
867 foreach my $i (split(/ +/,$src)) {
868 $basesrc .= " ".basename($i);
869 }
870
871 pb_log(0,"Sources handled ($cmt): $src\n");
872 pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf))."\n");
873 my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vepath) = pb_conf_get($host,$login,$dir,$port,$tmout,$path);
874 my ($vrebuild,$veconf) = pb_conf_get_if($rebuild,$conf);
875 pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
876 # Not mandatory
877 my ($testver) = pb_conf_get_if("testver");
878
879 my $mac;
880 # Useless for VE
881 if ($cmt ne "ve") {
882 $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
883 # Overwrite account value if passed as parameter
884 $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
885 pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
886 }
887
888 my $tdir;
889 my $bdir;
890 if (($cmt eq "Sources") || ($cmt eq "Script")) {
891 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
892 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
893 # This is a test pkg => target dir is under test
894 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/test/src";
895 }
896 } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
897 $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
898 $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
899 # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
900 $bdir =~ s|\$ENV.+\}/||;
901 } elsif ($cmt eq "Packages") {
902 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
903
904 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
905 # This is a test pkg => target dir is under test
906 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/test/$ddir/$dver";
907 }
908
909 my $repodir = $tdir;
910 $repodir =~ s|^$sshdir->{$ENV{'PBPROJ'}}/||;
911
912 my ($pbrepo) = pb_conf_get("pbrepo");
913
914 # Repository management
915 open(PBS,"> $ENV{'PBBUILDDIR'}/pbscript") || die "Unable to create $ENV{'PBBUILDDIR'}/pbscript";
916 if ($dtype eq "rpm") {
917 # Also make a pbscript to generate yum/urpmi bases
918 print PBS << "EOF";
919#!/bin/bash
920# Prepare a script to ease yum setup
921cat > $ENV{'PBPROJ'}.repo << EOT
922[$ENV{'PBPROJ'}]
923name=$ddir $dver - $ENV{'PBPROJ'} Vanilla Packages
924baseurl=$pbrepo->{$ENV{'PBPROJ'}}/$repodir
925enabled=1
926gpgcheck=0
927EOT
928chmod 644 $ENV{'PBPROJ'}.repo
929
930# Clean up old repo content
931rm -rf headers/ repodata/
932# Create yum repo
933yum-arch .
934# Create repodata
935createrepo .
936EOF
937 if ($dfam eq "md") {
938 # For Mandriva add urpmi management
939 print PBS << "EOF";
940# Prepare a script to ease urpmi setup
941cat > $ENV{'PBPROJ'}.addmedia << EOT
942urpmi.addmedia $ENV{'PBPROJ'} $pbrepo->{$ENV{'PBPROJ'}}/$repodir with hdlist.cz
943EOT
944chmod 755 $ENV{'PBPROJ'}.addmedia
945
946# Clean up old repo content
947rm -f hdlist.cz synthesis.hdlist.cz
948# Create urpmi repo
949genhdlist .
950EOF
951 }
952 } elsif ($dtype eq "deb") {
953 # Also make a pbscript to generate apt bases
954 }
955 close(PBS);
956 chmod 0755,"$ENV{'PBBUILDDIR'}/pbscript";
957
958 } else {
959 return;
960 }
961
962 # Useless for VE
963 my $nport;
964 if ($cmt ne "ve") {
965 $nport = $sshport->{$ENV{'PBPROJ'}};
966 $nport = "$pbport" if (defined $pbport);
967 }
968
969 # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
970 $tdir =~ s|\$ENV.+\}/||;
971
972 my $tm = $vtmout->{$ENV{'PBPROJ'}};
973
974 # ssh communication if not VE
975 # should use a hash instead...
976 my ($shcmd,$cpcmd,$cptarget,$cp2target);
977 if ($cmt ne "ve") {
978 my $keyfile = pb_ssh_get(0);
979 $shcmd = "ssh -i $keyfile -q -o UserKnownHostsFile=/dev/null -p $nport $mac";
980 $cpcmd = "scp -i $keyfile -p -o UserKnownHostsFile=/dev/null -P $nport";
981 $cptarget = "$mac:$tdir";
982 if ($cmt eq "vm") {
983 $cp2target = "$mac:$bdir";
984 }
985 } else {
986 my $tp = $vepath->{$ENV{'PBPROJ'}};
987 $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
988 $cpcmd = "cp -a ";
989 $cptarget = "$tp/$tdir";
990 $cp2target = "$tp/$bdir";
991 }
992
993 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");
994 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
995
996 # For VE we need to change the owner manually - To be tested if needed
997 #if ($cmt eq "ve") {
998 #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
999 #}
1000 pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi ; rm -f ./pbscript\' | bash\"","Executing pbscript on $cptarget if needed");
1001 if (($cmt eq "vm") || ($cmt eq "ve")) {
1002 # Get back info on pkg produced, compute their name and get them from the VM
1003 pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
1004 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
1005 my $src = <KEEP>;
1006 chomp($src);
1007 close(KEEP);
1008 $src =~ s/^ *//;
1009 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
1010 # Change pgben to make the next send2target happy
1011 my $made = "";
1012 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
1013 foreach my $p (split(/ +/,$src)) {
1014 my $j = basename($p);
1015 pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
1016 $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
1017 }
1018 print KEEP "$made\n";
1019 close(KEEP);
1020 pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
1021
1022 # We want to send them to the ssh account so overwrite what has been done before
1023 undef $pbaccount;
1024 pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
1025 pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
1026 pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
1027 }
1028 pb_log(2,"Before halt, vmexist: $vmexist, vmpid: $vmpid\n");
1029 if ((! $vmexist) && (($cmt eq "vm") || ($cmt eq "Script"))) {
1030 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)");
1031 }
1032}
1033
1034sub pb_script2v {
1035 my $pbscript=shift;
1036 my $vtype=shift;
1037 my $force=shift || 0; # Force stop of VM. Default not
1038 my $vm1=shift || undef; # Only that VM to treat
1039 my $vm;
1040 my $all;
1041
1042 pb_log(2,"DEBUG: pb_script2v($pbscript,$vtype,$force,$vm1)\n");
1043 # Prepare the script to be executed on the VM
1044 # in $ENV{'PBDESTDIR'}/pbscript
1045 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
1046 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1047 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1048 }
1049
1050 if (not defined $vm1) {
1051 ($vm,$all) = pb_get_v($vtype);
1052 } else {
1053 @$vm = ($vm1);
1054 }
1055 my ($vmexist,$vmpid) = (undef,undef);
1056
1057 foreach my $v (@$vm) {
1058 # Launch the VM/VE
1059 if ($vtype eq "vm") {
1060 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1061 pb_log(2,"DEBUG: After pb_launchv, vmexist: $vmexist, vmpid: $vmpid\n");
1062
1063 # Skip that VM if something went wrong
1064 next if (($vmpid == 0) && ($vmexist == 0));
1065
1066 # If force stopping the VM then reset vmexist
1067 if ($force == 1) {
1068 $vmpid = $vmexist;
1069 $vmexist = 0;
1070 }
1071 }
1072
1073 # Gather all required files to send them to the VM
1074 # and launch the build through pbscript
1075 pb_log(2,"DEBUG: Before send2target, vmexist: $vmexist, vmpid: $vmpid\n");
1076 pb_send2target("Script","$v",$vmexist,$vmpid);
1077
1078 }
1079}
1080
1081sub pb_launchv {
1082 my $vtype = shift;
1083 my $v = shift;
1084 my $create = shift || 0; # By default do not create a VM
1085
1086 pb_log(2,"DEBUG: pb_launchv($vtype,$v,$create)\n");
1087 die "No VM/VE defined, unable to launch" if (not defined $v);
1088 # Keep only the first VM in case many were given
1089 $v =~ s/,.*//;
1090
1091 # Which is our local arch ? (standardize on i386 for those platforms)
1092 my $arch = `uname -m`;
1093 chomp($arch);
1094 $arch =~ s/i.86/i386/;
1095
1096 # Launch the VMs/VEs
1097 if ($vtype eq "vm") {
1098 die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
1099
1100 my ($ptr,$vmopt,$vmpath,$vmport,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmpath","vmport","vmtmout","vmsize");
1101
1102 my $vmtype = $ptr->{$ENV{'PBPROJ'}};
1103 if (not defined $ENV{'PBVMOPT'}) {
1104 $ENV{'PBVMOPT'} = "";
1105 }
1106 if (defined $vmopt->{$ENV{'PBPROJ'}}) {
1107 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
1108 }
1109 my $nport = $vmport->{$ENV{'PBPROJ'}};
1110 $nport = "$pbport" if (defined $pbport);
1111
1112 my $cmd;
1113 my $vmcmd; # has to be used for pb_check_ps
1114 my $vmm; # has to be used for pb_check_ps
1115 if ($vmtype eq "qemu") {
1116 my $qemucmd32;
1117 my $qemucmd64;
1118 if ($arch eq "x86_64") {
1119 $qemucmd32 = "/usr/bin/qemu-system-i386";
1120 $qemucmd64 = "/usr/bin/qemu";
1121 } else {
1122 $qemucmd32 = "/usr/bin/qemu";
1123 $qemucmd64 = "/usr/bin/qemu-system-x86_64";
1124 }
1125 if ($v =~ /x86_64/) {
1126 $vmcmd = "$qemucmd64 -no-kqemu";
1127 } else {
1128 $vmcmd = "$qemucmd32";
1129 }
1130 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
1131 if ($create != 0) {
1132 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
1133 }
1134 $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
1135 } elsif ($vmtype eq "xen") {
1136 } elsif ($vmtype eq "vmware") {
1137 } else {
1138 die "VM of type $vmtype not supported. Report to the dev team";
1139 }
1140 my ($tmpcmd,$void) = split(/ +/,$cmd);
1141 my $vmexist = pb_check_ps($tmpcmd,$vmm);
1142 my $vmpid = 0;
1143 if (! $vmexist) {
1144 if ($create != 0) {
1145 if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
1146 pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
1147 } elsif ($vmtype eq "vmware") {
1148 } else {
1149 }
1150 }
1151 if (! -f "$vmm") {
1152 pb_log(0,"Unable to find VM $vmm\n");
1153 } else {
1154 pb_system("$cmd &","Launching the VM $vmm");
1155 pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
1156 $vmpid = pb_check_ps($tmpcmd,$vmm);
1157 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
1158 }
1159 } else {
1160 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
1161 }
1162 pb_log(2,"DEBUG: pb_launchv returns ($vmexist,$vmpid)\n");
1163 return($vmexist,$vmpid);
1164 # VE here
1165 } else {
1166 # Get VE context
1167 my ($ptr,$vetmout,$vepath,$verebuild,$veconf) = pb_conf_get("vetype","vetmout","vepath","verebuild","veconf");
1168 my $vetype = $ptr->{$ENV{'PBPROJ'}};
1169
1170 # Get distro context
1171 my ($name,$ver,$darch) = split(/-/,$v);
1172 chomp($darch);
1173 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
1174
1175 if ($vetype eq "chroot") {
1176 # Architecture consistency
1177 if ($arch ne $darch) {
1178 die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
1179 }
1180
1181 if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
1182 # We have to rebuild the chroot
1183 if ($dtype eq "rpm") {
1184 pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1185 # Once setup we need to install some packages, the pb account, ...
1186 pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
1187 #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1188 } elsif ($dtype eq "deb") {
1189 pb_system("","Creating the pbuilder VE");
1190 } elsif ($dtype eq "ebuild") {
1191 die "Please teach the dev team how to build gentoo chroot";
1192 } else {
1193 die "Unknown distribution type $dtype. Report to dev team";
1194 }
1195 }
1196 # Nothing more to do for VE. No real launch
1197 } else {
1198 die "VE of type $vetype not supported. Report to the dev team";
1199 }
1200 }
1201}
1202
1203sub pb_build2v {
1204
1205my $vtype = shift;
1206
1207# Prepare the script to be executed on the VM/VE
1208# in $ENV{'PBDESTDIR'}/pbscript
1209#my ($ntp) = pb_conf_get($vtype."ntp");
1210#my $vntp = $ntp->{$ENV{'PBPROJ'}};
1211
1212open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1213print SCRIPT "#!/bin/bash\n";
1214print SCRIPT "echo ... Execution needed\n";
1215print SCRIPT "# This is in directory delivery\n";
1216print SCRIPT "# Setup the variables required for building\n";
1217print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
1218print SCRIPT "# Preparation for pb\n";
1219print SCRIPT "mv .pbrc \$HOME\n";
1220print SCRIPT "cd ..\n";
1221# Force new date to be in the future compared to the date of the tar file by adding 1 minute
1222my @date=pb_get_date();
1223$date[1]++;
1224my $upddate = strftime("%m%d%H%M%Y", @date);
1225#print SCRIPT "echo Setting up date on $vntp...\n";
1226# Or use ntpdate if available TBC
1227print SCRIPT "sudo date $upddate\n";
1228# Get list of packages to build and get some ENV vars as well
1229my $ptr = pb_get_pkg();
1230@pkgs = @$ptr;
1231my $p = join(' ',@pkgs) if (@pkgs);
1232print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
1233print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
1234print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
1235print SCRIPT "# Build\n";
1236print SCRIPT "echo Building packages on $vtype...\n";
1237print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
1238close(SCRIPT);
1239chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1240
1241my ($v,$all) = pb_get_v($vtype);
1242
1243# Send tar files when we do a global generation
1244pb_build2ssh() if ($all == 1);
1245
1246my ($vmexist,$vmpid) = (undef,undef);
1247
1248foreach my $v (@$v) {
1249 if ($vtype eq "vm") {
1250 # Launch the VM
1251 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1252
1253 # Skip that VM if it something went wrong
1254 next if (($vmpid == 0) && ($vmexist == 0));
1255 }
1256 # Gather all required files to send them to the VM/VE
1257 # and launch the build through pbscript
1258 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
1259 pb_send2target($vtype,"$v",$vmexist,$vmpid);
1260}
1261}
1262
1263
1264sub pb_newver {
1265
1266 die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
1267
1268 # Need this call for PBDIR
1269 my ($scheme2,$uri) = pb_cms_init($pbinit);
1270
1271 my ($pbconf) = pb_conf_get("pbconfurl");
1272 $uri = $pbconf->{$ENV{'PBPROJ'}};
1273 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1274
1275 # Checking CMS repositories status
1276 my ($pburl) = pb_conf_get("pburl");
1277 ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
1278
1279 if ($scheme !~ /^svn/) {
1280 die "Only SVN is supported at the moment";
1281 }
1282 my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
1283 die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
1284
1285 $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
1286 die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
1287
1288 # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
1289 # we want to get for the root of the new URL
1290
1291 my $tmp = $ENV{'PBROOTDIR'};
1292 $tmp =~ s|^$ENV{'PBCONFDIR'}||;
1293
1294 my $newurl = "$uri/".dirname($tmp)."/$newver";
1295 # Should probably use projver in the old file
1296 my $oldver= basename($tmp);
1297
1298 # Checking pbcl files
1299 foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
1300 open(PBCL,$f) || die "Unable to open $f";
1301 my $foundnew = 0;
1302 while (<PBCL>) {
1303 $foundnew = 1 if (/^$newver \(/);
1304 }
1305 close(PBCL);
1306 die "ERROR: version $newver not found in $f" if ($foundnew == 0);
1307 }
1308
1309 # Duplicate and extract project-builder part
1310 pb_log(2,"Copying $uri/$tmp to $newurl\n");
1311 pb_cms_copy($scheme,"$uri/$tmp",$newurl);
1312 pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
1313 pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
1314
1315 # Duplicate and extract project
1316 my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
1317
1318 pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
1319 pb_cms_copy($scheme,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
1320 pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
1321 pb_cms_up($scheme,"$ENV{'PBDIR'}/..");
1322
1323 # Update the .pb file
1324 open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
1325 open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
1326 while(<FILE>) {
1327 s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
1328 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/);
1329 s/^testver/#testver/;
1330 pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
1331 print OUT $_;
1332 }
1333 close(FILE);
1334 close(OUT);
1335 rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
1336
1337 pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
1338 pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver",undef);
1339}
1340
1341#
1342# Return the list of VMs/VEs we are working on
1343# $all is a flag to know if we return all of them
1344# or only some (if all we publish also tar files in addition to pkgs
1345#
1346sub pb_get_v {
1347
1348my $vtype = shift;
1349my @v;
1350my $all = 0;
1351my $vlist;
1352my $pbv = 'PBV';
1353
1354if ($vtype eq "vm") {
1355 $vlist = "vmlist";
1356} elsif ($vtype eq "ve") {
1357 $vlist = "velist";
1358}
1359# Get VM/VE list
1360if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
1361 my ($ptr) = pb_conf_get($vlist);
1362 $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
1363 $all = 1;
1364}
1365pb_log(2,"$vtype: $ENV{$pbv}\n");
1366@v = split(/,/,$ENV{$pbv});
1367return(\@v,$all);
1368}
1369
1370# Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
1371# Needs to use root account to connect to the VM/VE
1372# pb will take your local public SSH key to access
1373# the pb account in the VM later on if needed
1374sub pb_setup_v {
1375
1376my $vtype = shift;
1377
1378my ($vm,$all) = pb_get_v($vtype);
1379
1380# Script generated
1381my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
1382
1383foreach my $v (@$vm) {
1384 # Name of the account to deal with for VM/VE
1385 # Do not use the one passed potentially with -a
1386 my ($pbac) = pb_conf_get($vtype."login");
1387 my ($key,$zero0,$zero1,$zero2);
1388 my ($vmexist,$vmpid);
1389
1390 if ($vtype eq "vm") {
1391 # Prepare the key to be used and transfered remotely
1392 my $keyfile = pb_ssh_get(1);
1393
1394 my ($vmhost,$vmport) = pb_conf_get("vmhost","vmport");
1395 my $nport = $vmport->{$ENV{'PBPROJ'}};
1396 $nport = "$pbport" if (defined $pbport);
1397
1398 # Launch the VM
1399 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1400
1401 # Skip that VM if something went wrong
1402 next if (($vmpid == 0) && ($vmexist == 0));
1403
1404 # Store the pub key part in a variable
1405 open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
1406 ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
1407 close(FILE);
1408
1409 $key = "\Q$zero1";
1410
1411 pb_system("cat $keyfile.pub | ssh -q -o UserKnownHostsFile=/dev/null -p $nport -i $keyfile root\@$vmhost->{$ENV{'PBPROJ'}} \"mkdir -p .ssh ; chmod 700 .ssh ; cat >> .ssh/authorized_keys ; chmod 600 .ssh/authorized_keys\"","Copying local keys to $vtype. This will require the root password");
1412 # once this is done, we can do what we want on the VM remotely
1413 }
1414
1415 # Prepare the script to be executed on the VM/VE
1416 # in $ENV{'PBDESTDIR'}/setupv
1417
1418 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
1419 print SCRIPT << 'EOF';
1420#!/usr/bin/perl -w
1421
1422use strict;
1423use File::Copy;
1424
1425our $debug;
1426our $LOG;
1427our $synmsg = "pbscript";
1428pb_log_init($debug, $LOG);
1429pb_temp_init();
1430
1431EOF
1432 if ($vtype eq "vm") {
1433 print SCRIPT << 'EOF';
1434# Removes duplicate in .ssh/authorized_keys of our key if needed
1435#
1436my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
1437open(PBFILE,$file1) || die "Unable to open $file1";
1438open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
1439my $count = 0;
1440while (<PBFILE>) {
1441EOF
1442 print SCRIPT << "EOF";
1443 if (/ $key /) {
1444 \$count++;
1445 }
1446print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
1447}
1448close(PBFILE);
1449close(PBOUT);
1450rename("\$file1.new",\$file1);
1451chmod 0600,\$file1;
1452EOF
1453 }
1454 print SCRIPT << 'EOF';
1455
1456# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
1457#
1458my $file="/etc/passwd";
1459open(PBFILE,$file) || die "Unable to open $file";
1460my $found = 0;
1461while (<PBFILE>) {
1462EOF
1463 print SCRIPT << "EOF";
1464 \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
1465EOF
1466 print SCRIPT << 'EOF';
1467}
1468close(PBFILE);
1469
1470if ( $found == 0 ) {
1471 if ( ! -d "/home" ) {
1472 pb_mkdir("/home");
1473 }
1474EOF
1475 print SCRIPT << "EOF";
1476pb_system("groupadd $pbac->{$ENV{'PBPROJ'}}","Adding group $pbac->{$ENV{'PBPROJ'}}");
1477pb_system("useradd $pbac->{$ENV{'PBPROJ'}} -g $pbac->{$ENV{'PBPROJ'}} -m -d /home/$pbac->{$ENV{'PBPROJ'}}","Adding user $pbac->{$ENV{'PBPROJ'}} (group $pbac->{$ENV{'PBPROJ'}} - home /home/$pbac->{$ENV{'PBPROJ'}}");
1478}
1479
1480# allow ssh entry to build
1481#
1482mkdir "/home/$pbac->{$ENV{'PBPROJ'}}/.ssh",0700;
1483# Allow those accessing root to access the build account
1484copy("\$ENV{'HOME'}/.ssh/authorized_keys","/home/$pbac->{$ENV{'PBPROJ'}}/.ssh/authorized_keys");
1485chmod 0600,".ssh/authorized_keys";
1486pb_system("chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} /home/$pbac->{$ENV{'PBPROJ'}}/.ssh","Finish setting up the SSH env for $pbac->{$ENV{'PBPROJ'}}");
1487
1488EOF
1489 print SCRIPT << 'EOF';
1490# No passwd for build account only keys
1491$file="/etc/shadow";
1492open(PBFILE,$file) || die "Unable to open $file";
1493open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1494while (<PBFILE>) {
1495EOF
1496 print SCRIPT << "EOF";
1497 s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
1498 s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
1499EOF
1500 print SCRIPT << 'EOF';
1501 print PBOUT $_;
1502}
1503close(PBFILE);
1504close(PBOUT);
1505rename("$file.new",$file);
1506chmod 0640,$file;
1507
1508# Keep the VM in text mode
1509$file="/etc/inittab";
1510if (-f $file) {
1511 open(PBFILE,$file) || die "Unable to open $file";
1512 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1513 while (<PBFILE>) {
1514 s/^(..):5:initdefault:$/$1:3:initdefault:/;
1515 print PBOUT $_;
1516 }
1517 close(PBFILE);
1518 close(PBOUT);
1519 rename("$file.new",$file);
1520 chmod 0640,$file;
1521}
1522
1523# pb has to be added to portage group on gentoo
1524
1525# Adapt sudoers
1526$file="/etc/sudoers";
1527open(PBFILE,$file) || die "Unable to open $file";
1528open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1529while (<PBFILE>) {
1530EOF
1531 print SCRIPT << "EOF";
1532 next if (/^$pbac->{$ENV{'PBPROJ'}} /);
1533EOF
1534 print SCRIPT << 'EOF';
1535 s/Defaults[ \t]+requiretty//;
1536 print PBOUT $_;
1537}
1538close(PBFILE);
1539EOF
1540 print SCRIPT << "EOF";
1541# This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
1542print PBOUT "$pbac->{$ENV{'PBPROJ'}} ALL=(ALL) NOPASSWD:ALL\n";
1543EOF
1544 print SCRIPT << 'EOF';
1545close(PBOUT);
1546rename("$file.new",$file);
1547chmod 0440,$file;
1548
1549EOF
1550
1551 my $SCRIPT = \*SCRIPT;
1552
1553 pb_install_deps($SCRIPT);
1554
1555 print SCRIPT << 'EOF';
1556# Suse wants sudoers as 640
1557if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
1558 chmod 0640,$file;
1559}
1560
1561# Sync date
1562#system "/usr/sbin/ntpdate ntp.pool.org";
1563
1564pb_system("rm -rf perl-ProjectBuilder-* ; wget --passive-ftp ftp://ftp.mondorescue.org/src/perl-ProjectBuilder-latest.tar.gz ; tar xvfz perl-ProjectBuilder-latest.tar.gz ; cd perl-ProjectBuilder-* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf perl-ProjectBuilder-* ; rm -rf project-builder-* ; wget --passive-ftp ftp://ftp.mondorescue.org/src/project-builder-latest.tar.gz ; tar xvfz project-builder-latest.tar.gz ; cd project-builder-* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf project-builder-* ;","Building Project-Builder");
1565system "pb 2>&1 | head -5";
1566EOF
1567 # Adds pb_distro_init from ProjectBuilder::Distribution
1568 foreach my $d (@INC) {
1569 my @f = ("$d/ProjectBuilder/Base.pm","$d/ProjectBuilder/Distribution.pm");
1570 foreach my $f (@f) {
1571 if (-f "$f") {
1572 open(PBD,"$f") || die "Unable to open $f";
1573 while (<PBD>) {
1574 next if (/^package/);
1575 next if (/^use Exporter/);
1576 next if (/^use ProjectBuilder::/);
1577 next if (/^our /);
1578 print SCRIPT $_;
1579 }
1580 close(PBD);
1581 }
1582 }
1583 }
1584 close(SCRIPT);
1585 chmod 0755,"$pbscript";
1586
1587 # That build script needs to be run as root and force stop of VM at end
1588 $pbaccount = "root";
1589
1590 # Force shutdown of VM exept if it was already launched
1591 my $force = 0;
1592 if ((! $vmexist) && ($vtype eq "vm")) {
1593 $force = 1;
1594 }
1595
1596 pb_script2v($pbscript,$vtype,$force,$v);
1597}
1598return;
1599}
1600
1601sub pb_install_deps {
1602
1603my $SCRIPT = shift;
1604
1605print {$SCRIPT} << 'EOF';
1606# We need to have that pb_distro_init function
1607# Get it from Project-Builder::Distribution
1608my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
1609print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
1610
1611# Get and install pb
1612my $insdm = "rm -rf Date-Manip* ; wget http://search.cpan.org/CPAN/authors/id/S/SB/SBECK/Date-Manip-5.54.tar.gz ; tar xvfz Date-Manip-5.54.tar.gz ; cd Date-Manip* ; perl Makefile.PL ; make ; make install ; cd .. ; rm -rf Date-Manip*";
1613my $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*";
1614my $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*";
1615my $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*";
1616my $cmtdm = "Installing Date-Manip perl module";
1617my $cmtmb = "Installing Module-Build perl module";
1618my $cmtfm = "Installing File-MimeInfo perl module";
1619my $cmtfb = "Installing File-Basedir perl module";
1620my $cmtall = "Installing required modules";
1621
1622if ( $ddir eq "fedora" ) {
1623 pb_system("yum clean all","Cleaning yum env");
1624 #system "yum update -y";
1625 my $arch=`uname -m`;
1626 my $opt = "";
1627 chomp($arch);
1628 if ($arch eq "x86_64") {
1629 $opt="--exclude=*.i?86";
1630 }
1631
1632 pb_system("yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker",$cmtall);
1633 if ($dver eq 4) {
1634 pb_system("$insmb","$cmtmb");
1635 pb_system("$insfm","$cmtfm");
1636 pb_system("$insfb","$cmtfb");
1637 }
1638} elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
1639 # Suppose pkg are installed already as no online mirror available
1640 pb_system("rpm -e lsb 2>&1 > /dev/null","Removing lsb package");
1641 pb_system("$insdm","$cmtdm");
1642 pb_system("$insmb","$cmtmb");
1643 pb_system("$insfm","$cmtfm");
1644 pb_system("$insfb","$cmtfb");
1645} elsif ($ddir eq "suse") {
1646 # New OpenSuSE
1647 pb_system("$insmb","$cmtmb");
1648 pb_system("$insfm","$cmtfm");
1649 pb_system("$insfb","$cmtfb");
1650 pb_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","$cmtall");
1651} elsif ( $dfam eq "md" ) {
1652 pb_system("urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo","$cmtall");
1653 if (($ddir eq "mandrake") && ($dver eq "10.1")) {
1654 pb_system("$insdm","$cmtdm");
1655 } else {
1656 pb_system("urpmi --auto perl-DateManip","$cmtdm");
1657 }
1658} elsif ( $dfam eq "du" ) {
1659 if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
1660 #system "apt-get update";
1661 pb_system("$insfb","$cmtfb");
1662 pb_system("$insfm","$cmtfm");
1663 pb_system("apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl","$cmtall");
1664 } else {
1665 pb_system("apt-get update; apt-get -y install wget patch openssh-server dpkg-dev sudo debian-builder dh-make fakeroot ntpdate libfile-mimeinfo-perl libmodule-build-perl libdate-manip-perl","$cmtall");
1666 }
1667} elsif ( $dfam eq "gen" ) {
1668 #system "emerge -u system";
1669 pb_system("emerge wget sudo ntp DateManip File-MimeInfo","$cmtall");
1670} else {
1671 print "No pkg to install\n";
1672}
1673EOF
1674}
1675
1676# Return the SSH key file to use
1677# Potentially create it if needed
1678
1679sub pb_ssh_get {
1680
1681my $create = shift || 0; # Do not create keys by default
1682
1683# Check the SSH environment
1684my $keyfile = undef;
1685
1686# We have specific keys by default
1687$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
1688if (!(-e $keyfile) && ($create eq 1)) {
1689 pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
1690}
1691
1692$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
1693$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
1694$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
1695die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
1696return($keyfile);
1697}
1698
1699
1700# Returns the pid of a running VM command using a specific VM file
1701sub pb_check_ps {
1702 my $vmcmd = shift;
1703 my $vmm = shift;
1704 my $vmexist = 0; # FALSE by default
1705
1706 open(PS, "ps auxhww|") || die "Unable to call ps";
1707 while (<PS>) {
1708 next if (! /$vmcmd/);
1709 next if (! /$vmm/);
1710 my ($void1, $void2);
1711 ($void1, $vmexist, $void2) = split(/ +/);
1712 last;
1713 }
1714 return($vmexist);
1715}
1716
1717
1718sub pb_extract_build_files {
1719
1720my $src=shift;
1721my $dir=shift;
1722my $ddir=shift;
1723my @files;
1724
1725if ($src =~ /tar\.gz$/) {
1726 pb_system("tar xfpz $src $dir","Extracting build files");
1727} elsif ($src =~ /tar\.bz2$/) {
1728 pb_system("tar xfpj $src $dir","Extracting build files");
1729} else {
1730 die "Unknown compression algorithm for $src";
1731}
1732opendir(DIR,"$dir") || die "Unable to open directory $dir";
1733foreach my $f (readdir(DIR)) {
1734 next if ($f =~ /^\./);
1735 move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
1736 pb_log(2,"mv $dir/$f $ddir\n");
1737 push @files,"$ddir/$f";
1738}
1739closedir(DIR);
1740# Not enough but still a first cleanup
1741pb_rm_rf("$dir");
1742return(@files);
1743}
1744
1745sub pb_list_bfiles {
1746
1747my $dir = shift;
1748my $pbpkg = shift;
1749my $bfiles = shift;
1750my $pkgfiles = shift;
1751my $supfiles = shift;
1752
1753opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
1754foreach my $f (readdir(BDIR)) {
1755 next if ($f =~ /^\./);
1756 $bfiles->{$f} = "$dir/$f";
1757 $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
1758 if (defined $supfiles->{$pbpkg}) {
1759 $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
1760 }
1761}
1762closedir(BDIR);
1763}
1764
1765
1766#
1767# Return the list of packages we are working on in a non CMS action
1768#
1769sub pb_get_pkg {
1770
1771my @pkgs = ();
1772
1773my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
1774@pkgs = keys %$var;
1775
1776pb_log(0,"Packages: ".join(',',@pkgs)."\n");
1777return(\@pkgs);
1778}
1779
17801;
Note: See TracBrowser for help on using the repository browser.