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

Last change on this file since 429 was 429, checked in by Bruno Cornec, 16 years ago
  • Change filtering interface to add pbrepo keyword support and PBREPO macro
  • Add repository generation support + conf files to pb for rpm
  • Adapt pb and mondorecue spec files to new interfaces
  • Property svn:executable set to *
File size: 53.8 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 # Get project info on authors and log file
487 my $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
488 $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
489 $chglog = undef if (! -f $chglog);
490
491 my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
492 $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
493 $authors = "/dev/null" if (! -f $authors);
494
495 # Extract cms log history and store it
496 if ((defined $chglog) && (! -f "$dest/NEWS")) {
497 pb_log(2,"Generating NEWS file from $chglog\n");
498 copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
499 }
500 pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors);
501
502 my %build;
503
504 my @pt;
505 @pt = pb_conf_get_if("vmlist","velist");
506 my $tmpl = "";
507 if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
508 $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
509 }
510 if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
511 # the 2 lists needs to be grouped with a ',' separated them
512 if ($tmpl ne "") {
513 $tmpl .= ",";
514 }
515 $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
516 }
517 foreach my $d (split(/,/,$tmpl)) {
518 my ($name,$ver,$arch) = split(/-/,$d);
519 chomp($arch);
520 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
521 pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n");
522 pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
523
524 # Filter build files from the less precise up to the most with overloading
525 # Filter all files found, keeping the name, and generating in dest
526
527 # Find all build files first relatively to PBROOTDIR
528 # Find also all specific files referenced in the .pb conf file
529 my %bfiles = ();
530 my %pkgfiles = ();
531 $build{"$ddir-$dver"} = "yes";
532
533 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dtype") {
534 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dtype",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
535 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dfam") {
536 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
537 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir") {
538 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
539 } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver") {
540 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
541 } else {
542 $build{"$ddir-$dver"} = "no";
543 next;
544 }
545 pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
546
547 # Get all filters to apply
548 my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
549
550 # Apply now all the filters on all the files concerned
551 # destination dir depends on the type of file
552 if (defined $ptr) {
553 foreach my $f (values %bfiles,values %pkgfiles) {
554 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'});
555 }
556 }
557 }
558 my @found;
559 my @notfound;
560 foreach my $b (keys %build) {
561 push @found,$b if ($build{$b} =~ /yes/);
562 push @notfound,$b if ($build{$b} =~ /no/);
563 }
564 pb_log(0,"Build files generated for ".join(',',@found)."\n");
565 pb_log(0,"No Build files found for ".join(',',@notfound)."\n") if (@notfound);
566 # Get the generic filter (all.pbf) and
567 # apply those to the non-build files including those
568 # generated by pbinit if applicable
569
570 # Get only all.pbf filter
571 my $ptr = pb_get_filters($pbpkg);
572
573 my $liste ="";
574 if (defined $filteredfiles->{$pbpkg}) {
575 foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
576 pb_filter_file_inplace($ptr,"$dest/$f",$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'},$ENV{'PBPROJ'},$ENV{'PBREPO'});
577 $liste = "$f $liste";
578 }
579 }
580 pb_log(2,"Files ".$liste."have been filtered\n");
581
582 # Prepare the dest directory for archive
583 if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
584 pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'},$ENV{'PBPROJ'},$ENV{'PBREPO'});
585 chmod 0755,"$ENV{'PBTMP'}/pbinit";
586 pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit");
587 }
588
589 # Archive dest dir
590 chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
591 # Possibility to look at PBSRC to guess more the filename
592 pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
593 pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
594
595 # Keep track of version-tag per pkg
596 $pkgs{$pbpkg} = "$pbver-$pbtag";
597
598 # Final cleanup
599 pb_rm_rf($dest) if (-d $dest);
600 }
601
602 # Keep track of per package version
603 pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
604 open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
605 foreach my $pbpkg (@pkgs) {
606 print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
607 }
608 close(PKG);
609
610 # Keep track of what is generated by default
611 # We need to store the dir and info on version-tag
612 # Base our content on the existing .pb file
613 copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
614 open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
615 print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
616 print LAST "pbprojver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
617 print LAST "pbprojtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
618 print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
619 close(LAST);
620}
621
622sub pb_build2pkg {
623
624 # Get the running distro to build on
625 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
626 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
627
628 # Get list of packages to build
629 # Get content saved in cms2build
630 my $ptr = pb_get_pkg();
631 @pkgs = @$ptr;
632
633 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
634 $pkg = { } if (not defined $pkg);
635
636 chdir "$ENV{'PBBUILDDIR'}";
637 my $made = ""; # pkgs made during build
638 foreach my $pbpkg (@pkgs) {
639 my $vertag = $pkg->{$pbpkg};
640 # get the version of the current package - maybe different
641 ($pbver,$pbtag) = split(/-/,$vertag);
642
643 my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
644 pb_log(2,"Source file: $src\n");
645
646 pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
647 if ($dtype eq "rpm") {
648 foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
649 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
650 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";
651 }
652 }
653
654 # Remove in case a previous link/file was there
655 unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
656 symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
657 # We need to first extract the spec file
658 my @specfile;
659 @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
660
661 pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
662 # set LANGUAGE to check for correct log messages
663 $ENV{'LANGUAGE'}="C";
664 foreach my $f (@specfile) {
665 if ($f =~ /\.spec$/) {
666 pb_system("rpmbuild --define \'packager $ENV{'PBPACKAGER'}\' --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
667 last;
668 }
669 }
670 $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
671 if (-f "/usr/bin/rpmlint") {
672 pb_system("rpmlint $made","Checking validity of rpms with rpmlint");
673 }
674 } elsif ($dtype eq "deb") {
675 chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
676 pb_system("tar xfz $src","Extracting sources");
677
678 chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
679 pb_rm_rf("debian");
680 symlink "pbconf/$ddir-$dver","debian" || die "Unable to symlink to pbconf/$ddir-$dver";
681 chmod 0755,"debian/rules";
682 pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package");
683 $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
684 if (-f "/usr/bin/lintian") {
685 pb_system("lintian $made","Checking validity of debs with lintian");
686 }
687 } elsif ($dtype eq "ebuild") {
688 my @ebuildfile;
689 # For gentoo we need to take pb as subsystem name
690 # We put every apps here under sys-apps. hope it's correct
691 # We use pb's home dir in order o have a single OVERLAY line
692 my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
693 pb_mkdir_p($tmpd) if (! -d "$tmpd");
694 pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
695
696 # We need to first extract the ebuild file
697 @ebuildfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$tmpd");
698
699 # Prepare the build env for gentoo
700 my $found = 0;
701 my $pbbd = $ENV{'HOME'};
702 $pbbd =~ s|/|\\/|g;
703 if (-r "/etc/make.conf") {
704 open(MAKE,"/etc/make.conf");
705 while (<MAKE>) {
706 $found = 1 if (/$pbbd\/portage/);
707 }
708 close(MAKE);
709 }
710 if ($found == 0) {
711 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
712 }
713 #$found = 0;
714 #if (-r "/etc/portage/package.keywords") {
715 #open(KEYW,"/etc/portage/package.keywords");
716 #while (<KEYW>) {
717 #$found = 1 if (/portage\/pb/);
718 #}
719 #close(KEYW);
720 #}
721 #if ($found == 0) {
722 #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
723 #}
724
725 # Build
726 foreach my $f (@ebuildfile) {
727 if ($f =~ /\.ebuild$/) {
728 move($f,"$tmpd/$pbpkg-$pbver.ebuild");
729 pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package");
730 # Now move it where pb expects it
731 pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
732 move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
733 }
734 }
735
736 $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver.ebuild";
737 } elsif ($dtype eq "slackware") {
738 $made="$made build-$pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
739 pb_mkdir_p("$ENV{'PBBUILDDIR'}/install") if (! -d "$ENV{'PBBUILDDIR'}/install");
740 } else {
741 die "Unknown dtype format $dtype";
742 }
743 }
744 # Keep track of what is generated so that we can get them back from VMs
745 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
746 print KEEP "$made\n";
747 close(KEEP);
748}
749
750sub pb_build2ssh {
751 pb_send2target("Sources");
752}
753
754sub pb_pkg2ssh {
755 pb_send2target("Packages");
756}
757
758# By default deliver to the the public site hosting the
759# ftp structure (or whatever) or a VM/VE
760sub pb_send2target {
761
762 my $cmt = shift;
763 my $v = shift || undef;
764 my $vmexist = shift || 0; # 0 is FALSE
765 my $vmpid = shift || 0; # 0 is FALSE
766
767 my $host = "sshhost";
768 my $login = "sshlogin";
769 my $dir = "sshdir";
770 my $port = "sshport";
771 my $conf = "sshconf";
772 my $rebuild = "sshrebuild";
773 my $tmout = "vmtmout";
774 my $path = "vmpath";
775 if (($cmt eq "vm") || ($cmt eq "Script")) {
776 $login = "vmlogin";
777 $dir = "pbdefdir";
778 $tmout = "vmtmout";
779 $rebuild = "vmrebuild";
780 # Specific VM
781 $host = "vmhost";
782 $port = "vmport";
783 } elsif ($cmt eq "ve") {
784 $login = "velogin";
785 $dir = "pbdefdir";
786 $tmout = "vetmout";
787 # Specific VE
788 $path = "vepath";
789 $conf = "veconf";
790 $rebuild = "verebuild";
791 }
792 my $cmd = "";
793
794 my $ptr = pb_get_pkg();
795 @pkgs = @$ptr;
796
797 # Get the running distro to consider
798 my ($odir,$over,$oarch) = (undef, undef, undef);
799 if (defined $v) {
800 ($odir,$over,$oarch) = split(/-/,$v);
801 }
802 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
803 pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
804
805 # Get list of packages to build
806 # Get content saved in cms2build
807 my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
808 $pkg = { } if (not defined $pkg);
809
810 my $src = "";
811 chdir "$ENV{'PBBUILDDIR'}";
812 foreach my $pbpkg (@pkgs) {
813 my $vertag = $pkg->{$pbpkg};
814 # get the version of the current package - maybe different
815 ($pbver,$pbtag) = split(/-/,$vertag);
816
817 if (($cmt eq "Sources") || ($cmt eq "vm") || ($cmt eq "ve")) {
818 $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
819 if ($cmd eq "") {
820 $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
821 } else {
822 $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
823 }
824 }
825 }
826 # Adds conf file for availability of conf elements
827 pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
828
829 if (($cmt eq "vm") || ($cmt eq "ve")) {
830 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc";
831 } elsif ($cmt eq "Script") {
832 # Nothing special to do
833 } elsif ($cmt eq "Packages") {
834 # Get package list from file made during build2pkg
835 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
836 $src = <KEEP>;
837 chomp($src);
838 close(KEEP);
839
840 }
841 # Systematically adds the pbscript
842 $src="$src $ENV{'PBDESTDIR'}/pbscript";
843 # Remove potential leading spaces (cause problem with basename)
844 $src =~ s/^ *//;
845 my $basesrc = "";
846 foreach my $i (split(/ +/,$src)) {
847 $basesrc .= " ".basename($i);
848 }
849
850 pb_log(0,"Sources handled ($cmt): $src\n");
851 pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf))."\n");
852 my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vepath) = pb_conf_get($host,$login,$dir,$port,$tmout,$path);
853 my ($vrebuild,$veconf) = pb_conf_get_if($rebuild,$conf);
854 pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
855 # Not mandatory
856 my ($testver) = pb_conf_get_if("testver");
857
858 my $mac;
859 # Useless for VE
860 if ($cmt ne "ve") {
861 $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
862 # Overwrite account value if passed as parameter
863 $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
864 pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
865 }
866
867 my $tdir;
868 my $bdir;
869 if (($cmt eq "Sources") || ($cmt eq "Script")) {
870 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
871 } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
872 $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
873 $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
874 # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
875 $bdir =~ s|\$ENV.+\}/||;
876 } elsif ($cmt eq "Packages") {
877 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
878
879 if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
880 # This is a test pkg => target dir is under test
881 $tdir = "$sshdir->{$ENV{'PBPROJ'}}/test/$ddir/$dver";
882 }
883
884 my $repodir = $tdir;
885 $repodir =~ s|^$sshdir->{$ENV{'PBPROJ'}}/||;
886
887 my ($pbrepo) = pb_conf_get("pbrepo");
888
889 # Repository management
890 open(PBS,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
891 if ($dtype eq "rpm") {
892 # Also make a pbscript to generate yum/urpmi bases
893 print PBS << "EOF";
894# Prepare a script to ease yum setup
895cat > $ENV{'PBPROJ'}.repo << EOT
896[$ENV{'PBPROJ'}]
897name=$ddir $dver - $ENV{'PBPROJ'} Vanilla Packages
898baseurl=$pbrepo->{'PBPROJ'}/$repodir
899enabled=1
900gpgcheck=0
901EOT
902chmod 644 $ENV{'PBPROJ'}.repo
903
904# Clean up old repo content
905rm -rf headers/ repodata/
906# Create yum repo
907yum-arch .
908# Create repodata
909createrepo .
910EOF
911 if ($dfam eq "md") {
912 # For Mandriva add urpmi management
913 print PBS << "EOF";
914# Prepare a script to ease urpmi setup
915cat > $ENV{'PBPROJ'}.addmedia << EOT
916urpmi.addmedia $ENV{'PBPROJ'} $pbrepo->{'PBPROJ'}/$repodir with hdlist.cz
917EOT
918chmod 755 $ENV{'PBPROJ'}.addmedia
919
920# Clean up old repo content
921rm -f hdlist.cz
922# Create urpmi repo
923genhdlist .
924EOF
925 }
926 } elsif ($dtype eq "deb") {
927 # Also make a pbscript to generate apt bases
928 }
929 close(PBS);
930
931 } else {
932 return;
933 }
934
935 # Useless for VE
936 my $nport;
937 if ($cmt ne "ve") {
938 $nport = $sshport->{$ENV{'PBPROJ'}};
939 $nport = "$pbport" if (defined $pbport);
940 }
941
942 # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
943 $tdir =~ s|\$ENV.+\}/||;
944
945 my $tm = $vtmout->{$ENV{'PBPROJ'}};
946
947 # ssh communication if not VE
948 # should use a hash instead...
949 my ($shcmd,$cpcmd,$cptarget,$cp2target);
950 if ($cmt ne "ve") {
951 my $keyfile = pb_ssh_get(0);
952 $shcmd = "ssh -i $keyfile -q -p $nport $mac";
953 $cpcmd = "scp -i $keyfile -p -P $nport";
954 $cptarget = "$mac:$tdir";
955 if ($cmt eq "vm") {
956 $cp2target = "$mac:$bdir";
957 }
958 } else {
959 my $tp = $vepath->{$ENV{'PBPROJ'}};
960 $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
961 $cpcmd = "cp -a ";
962 $cptarget = "$tp/$tdir";
963 $cp2target = "$tp/$bdir";
964 }
965
966 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");
967 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
968 # For VE we need to change the owner manually - To be tested if needed
969 #if ($cmt eq "ve") {
970 #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
971 #}
972 pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi\' | bash\"","Executing pbscript on $cptarget if needed");
973 if (($cmt eq "vm") || ($cmt eq "ve")) {
974 # Get back info on pkg produced, compute their name and get them from the VM
975 pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
976 open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
977 my $src = <KEEP>;
978 chomp($src);
979 close(KEEP);
980 $src =~ s/^ *//;
981 pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
982 # Change pgben to make the next send2target happy
983 my $made = "";
984 open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
985 foreach my $p (split(/ +/,$src)) {
986 my $j = basename($p);
987 pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
988 $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
989 }
990 print KEEP "$made\n";
991 close(KEEP);
992 pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
993
994 # We want to send them to the ssh account so overwrite what has been done before
995 undef $pbaccount;
996 pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
997 pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
998 if ((! $vmexist) && ($cmt eq "vm")) {
999 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)");
1000 }
1001 pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
1002 }
1003}
1004
1005sub pb_script2v {
1006 my $pbscript=shift;
1007 my $vtype=shift;
1008
1009 # Prepare the script to be executed on the VM
1010 # in $ENV{'PBDESTDIR'}/pbscript
1011 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
1012 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1013 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1014 }
1015
1016 my ($vm,$all) = pb_get_v($vtype);
1017 my ($vmexist,$vmpid) = (undef,undef);
1018
1019 foreach my $v (@$vm) {
1020 # Launch the VM/VE
1021 if ($vtype eq "vm") {
1022 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1023
1024 # Skip that VM if something went wrong
1025 next if (($vmpid == 0) && ($vmexist ==0));
1026 }
1027
1028 # Gather all required files to send them to the VM
1029 # and launch the build through pbscript
1030 pb_send2target("Script","$v",$vmexist,$vmpid);
1031
1032 }
1033}
1034
1035sub pb_launchv {
1036 my $vtype = shift;
1037 my $v = shift;
1038 my $create = shift || 0; # By default do not create a VM
1039
1040 die "No VM/VE defined, unable to launch" if (not defined $v);
1041 # Keep only the first VM in case many were given
1042 $v =~ s/,.*//;
1043
1044 # Which is our local arch ? (standardize on i386 for those platforms)
1045 my $arch = `uname -m`;
1046 chomp($arch);
1047 $arch =~ s/i.86/i386/;
1048
1049 # Launch the VMs/VEs
1050 if ($vtype eq "vm") {
1051 die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
1052
1053 my ($ptr,$vmopt,$vmpath,$vmport,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmpath","vmport","vmtmout","vmsize");
1054
1055 my $vmtype = $ptr->{$ENV{'PBPROJ'}};
1056 if (not defined $ENV{'PBVMOPT'}) {
1057 $ENV{'PBVMOPT'} = "";
1058 }
1059 if (defined $vmopt->{$ENV{'PBPROJ'}}) {
1060 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
1061 }
1062 my $nport = $vmport->{$ENV{'PBPROJ'}};
1063 $nport = "$pbport" if (defined $pbport);
1064
1065 my $cmd;
1066 my $vmcmd; # has to be used for pb_check_ps
1067 my $vmm; # has to be used for pb_check_ps
1068 if ($vmtype eq "qemu") {
1069 my $qemucmd32;
1070 my $qemucmd64;
1071 if ($arch eq "x86_64") {
1072 $qemucmd32 = "/usr/bin/qemu-system-i386";
1073 $qemucmd64 = "/usr/bin/qemu";
1074 } else {
1075 $qemucmd32 = "/usr/bin/qemu";
1076 $qemucmd64 = "/usr/bin/qemu-system-x86_64";
1077 }
1078 if ($v =~ /x86_64/) {
1079 $vmcmd = "$qemucmd64 -no-kqemu";
1080 } else {
1081 $vmcmd = "$qemucmd32";
1082 }
1083 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
1084 if ($create != 0) {
1085 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
1086 }
1087 $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
1088 } elsif ($vmtype eq "xen") {
1089 } elsif ($vmtype eq "vmware") {
1090 } else {
1091 die "VM of type $vmtype not supported. Report to the dev team";
1092 }
1093 my ($tmpcmd,$void) = split(/ +/,$cmd);
1094 my $vmexist = pb_check_ps($tmpcmd,$vmm);
1095 my $vmpid = 0;
1096 if (! $vmexist) {
1097 if ($create != 0) {
1098 if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
1099 pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
1100 } elsif ($vmtype eq "vmware") {
1101 } else {
1102 }
1103 }
1104 if (! -f "$vmm") {
1105 pb_log(0,"Unable to find VM $vmm\n");
1106 } else {
1107 pb_system("$cmd &","Launching the VM $vmm");
1108 pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
1109 $vmpid = pb_check_ps($tmpcmd,$vmm);
1110 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
1111 }
1112 } else {
1113 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
1114 }
1115 return($vmexist,$vmpid);
1116 # VE here
1117 } else {
1118 # Get VE context
1119 my ($ptr,$vetmout,$vepath,$verebuild,$veconf) = pb_conf_get("vetype","vetmout","vepath","verebuild","veconf");
1120 my $vetype = $ptr->{$ENV{'PBPROJ'}};
1121
1122 # Get distro context
1123 my ($name,$ver,$darch) = split(/-/,$v);
1124 chomp($darch);
1125 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
1126
1127 if ($vetype eq "chroot") {
1128 # Architecture consistency
1129 if ($arch ne $darch) {
1130 die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
1131 }
1132
1133 if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
1134 # We have to rebuild the chroot
1135 if ($dtype eq "rpm") {
1136 pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1137 # Once setup we need to install some packages, the pb account, ...
1138 pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
1139 #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
1140 } elsif ($dtype eq "deb") {
1141 pb_system("","Creating the pbuilder VE");
1142 } elsif ($dtype eq "ebuild") {
1143 die "Please teach the dev team how to build gentoo chroot";
1144 } else {
1145 die "Unknown distribution type $dtype. Report to dev team";
1146 }
1147 }
1148 # Nothing more to do for VE. No real launch
1149 } else {
1150 die "VE of type $vetype not supported. Report to the dev team";
1151 }
1152 }
1153}
1154
1155sub pb_build2v {
1156
1157my $vtype = shift;
1158
1159# Prepare the script to be executed on the VM/VE
1160# in $ENV{'PBDESTDIR'}/pbscript
1161#my ($ntp) = pb_conf_get($vtype."ntp");
1162#my $vntp = $ntp->{$ENV{'PBPROJ'}};
1163
1164open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
1165print SCRIPT "#!/bin/bash\n";
1166print SCRIPT "echo ... Execution needed\n";
1167print SCRIPT "# This is in directory delivery\n";
1168print SCRIPT "# Setup the variables required for building\n";
1169print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
1170print SCRIPT "# Preparation for pb\n";
1171print SCRIPT "mv .pbrc \$HOME\n";
1172print SCRIPT "cd ..\n";
1173# Force new date to be in the future compared to the date of the tar file by adding 1 minute
1174my @date=pb_get_date();
1175$date[1]++;
1176my $upddate = strftime("%m%d%H%M%Y", @date);
1177#print SCRIPT "echo Setting up date on $vntp...\n";
1178# Or use ntpdate if available TBC
1179print SCRIPT "sudo date $upddate\n";
1180# Get list of packages to build and get some ENV vars as well
1181my $ptr = pb_get_pkg();
1182@pkgs = @$ptr;
1183my $p = join(' ',@pkgs) if (@pkgs);
1184print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
1185print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
1186print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
1187print SCRIPT "# Build\n";
1188print SCRIPT "echo Building packages on $vtype...\n";
1189print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
1190close(SCRIPT);
1191chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
1192
1193my ($v,$all) = pb_get_v($vtype);
1194
1195# Send tar files when we do a global generation
1196pb_build2ssh() if ($all == 1);
1197
1198my ($vmexist,$vmpid) = (undef,undef);
1199
1200foreach my $v (@$v) {
1201 if ($vtype eq "vm") {
1202 # Launch the VM
1203 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1204
1205 # Skip that VM if it something went wrong
1206 next if (($vmpid == 0) && ($vmexist == 0));
1207 }
1208 # Gather all required files to send them to the VM/VE
1209 # and launch the build through pbscript
1210 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
1211 pb_send2target($vtype,"$v",$vmexist,$vmpid);
1212}
1213}
1214
1215
1216sub pb_newver {
1217
1218 die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
1219
1220 # Need this call for PBDIR
1221 my ($scheme2,$uri) = pb_cms_init($pbinit);
1222
1223 my ($pbconf) = pb_conf_get("pbconfurl");
1224 $uri = $pbconf->{$ENV{'PBPROJ'}};
1225 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1226
1227 # Checking CMS repositories status
1228 my ($pburl) = pb_conf_get("pburl");
1229 ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
1230
1231 if ($scheme !~ /^svn/) {
1232 die "Only SVN is supported at the moment";
1233 }
1234 my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
1235 die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
1236
1237 $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
1238 die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
1239
1240 # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
1241 # we want to get for the root of the new URL
1242
1243 my $tmp = $ENV{'PBROOTDIR'};
1244 $tmp =~ s|^$ENV{'PBCONFDIR'}||;
1245
1246 my $newurl = "$uri/".dirname($tmp)."/$newver";
1247 # Should probably use projver in the old file
1248 my $oldver= basename($tmp);
1249
1250 # Checking pbcl files
1251 foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
1252 open(PBCL,$f) || die "Unable to open $f";
1253 my $foundnew = 0;
1254 while (<PBCL>) {
1255 $foundnew = 1 if (/^$newver \(/);
1256 }
1257 close(PBCL);
1258 die "ERROR: version $newver not found in $f" if ($foundnew == 0);
1259 }
1260
1261 # Duplicate and extract project-builder part
1262 pb_log(2,"Copying $uri/$tmp to $newurl\n");
1263 pb_cms_copy($scheme,"$uri/$tmp",$newurl);
1264 pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
1265 pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
1266
1267 # Duplicate and extract project
1268 my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
1269
1270 pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
1271 pb_cms_copy($scheme,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
1272 pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
1273 pb_cms_up($scheme,"$ENV{'PBDIR'}/..");
1274
1275 # Update the .pb file
1276 open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
1277 open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
1278 while(<FILE>) {
1279 s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
1280 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/);
1281 s/^testver/#testver/;
1282 pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
1283 print OUT $_;
1284 }
1285 close(FILE);
1286 close(OUT);
1287 rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
1288
1289 pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
1290 pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver");
1291}
1292
1293#
1294# Return the list of VMs/VEs we are working on
1295# $all is a flag to know if we return all of them
1296# or only some (if all we publish also tar files in addition to pkgs
1297#
1298sub pb_get_v {
1299
1300my $vtype = shift;
1301my @v;
1302my $all = 0;
1303my $vlist;
1304my $pbv = 'PBV';
1305
1306if ($vtype eq "vm") {
1307 $vlist = "vmlist";
1308} elsif ($vtype eq "ve") {
1309 $vlist = "velist";
1310}
1311# Get VM/VE list
1312if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
1313 my ($ptr) = pb_conf_get($vlist);
1314 $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
1315 $all = 1;
1316}
1317pb_log(2,"$vtype: $ENV{$pbv}\n");
1318@v = split(/,/,$ENV{$pbv});
1319return(\@v,$all);
1320}
1321
1322# Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
1323# Needs to use root account to connect to the VM/VE
1324# pb will take your local public SSH key to access
1325# the pb account in the VM later on if needed
1326sub pb_setup_v {
1327
1328my $vtype = shift;
1329
1330my ($vm,$all) = pb_get_v($vtype);
1331
1332# Script generated
1333my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
1334
1335foreach my $v (@$vm) {
1336 # Name of the account to deal with for VM/VE
1337 # Do not use the one passed potentially with -a
1338 my ($pbac) = pb_conf_get($vtype."login");
1339 my ($key,$zero0,$zero1,$zero2);
1340 my ($vmexist,$vmpid);
1341
1342 if ($vtype eq "vm") {
1343 # Prepare the key to be used and transfered remotely
1344 my $keyfile = pb_ssh_get(1);
1345
1346 my ($vmhost,$vmport) = pb_conf_get("vmhost","vmport");
1347 my $nport = $vmport->{$ENV{'PBPROJ'}};
1348 $nport = "$pbport" if (defined $pbport);
1349
1350 # Launch the VM
1351 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
1352
1353 # Skip that VM if something went wrong
1354 return if (($vmpid == 0) && ($vmexist == 0));
1355
1356 # Store the pub key part in a variable
1357 open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
1358 ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
1359 close(FILE);
1360
1361 $key = "\Q$zero1";
1362
1363 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");
1364 # once this is done, we can do what we want on the VM remotely
1365 }
1366
1367 # Prepare the script to be executed on the VM/VE
1368 # in $ENV{'PBDESTDIR'}/setupv
1369
1370 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
1371 print SCRIPT << 'EOF';
1372#!/usr/bin/perl -w
1373
1374use strict;
1375use File::Copy;
1376
1377our $debug;
1378our $LOG;
1379our $synmsg = "pbscript";
1380pb_log_init($debug, $LOG);
1381pb_temp_init();
1382
1383EOF
1384 if ($vtype eq "vm") {
1385 print SCRIPT << 'EOF';
1386# Removes duplicate in .ssh/authorized_keys of our key if needed
1387#
1388my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
1389open(PBFILE,$file1) || die "Unable to open $file1";
1390open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
1391my $count = 0;
1392while (<PBFILE>) {
1393EOF
1394 print SCRIPT << "EOF";
1395 if (/ $key /) {
1396 \$count++;
1397 }
1398print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
1399}
1400close(PBFILE);
1401close(PBOUT);
1402rename("\$file1.new",\$file1);
1403chmod 0600,\$file1;
1404EOF
1405 }
1406 print SCRIPT << 'EOF';
1407
1408# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
1409#
1410my $file="/etc/passwd";
1411open(PBFILE,$file) || die "Unable to open $file";
1412my $found = 0;
1413while (<PBFILE>) {
1414EOF
1415 print SCRIPT << "EOF";
1416 \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
1417EOF
1418 print SCRIPT << 'EOF';
1419}
1420close(PBFILE);
1421
1422if ( $found == 0 ) {
1423 if ( ! -d "/home" ) {
1424 pb_mkdir("/home");
1425 }
1426EOF
1427 print SCRIPT << "EOF";
1428pb_system("groupadd $pbac->{$ENV{'PBPROJ'}}","Adding group $pbac->{$ENV{'PBPROJ'}}");
1429pb_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'}}");
1430}
1431
1432# allow ssh entry to build
1433#
1434mkdir "/home/$pbac->{$ENV{'PBPROJ'}}/.ssh",0700;
1435# Allow those accessing root to access the build account
1436copy("\$ENV{'HOME'}/.ssh/authorized_keys","/home/$pbac->{$ENV{'PBPROJ'}}/.ssh/authorized_keys");
1437chmod 0600,".ssh/authorized_keys";
1438pb_system("chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} /home/$pbac->{$ENV{'PBPROJ'}}/.ssh","Finish setting up the SSH env for $pbac->{$ENV{'PBPROJ'}}");
1439
1440EOF
1441 print SCRIPT << 'EOF';
1442# No passwd for build account only keys
1443$file="/etc/shadow";
1444open(PBFILE,$file) || die "Unable to open $file";
1445open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1446while (<PBFILE>) {
1447EOF
1448 print SCRIPT << "EOF";
1449 s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
1450 s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
1451EOF
1452 print SCRIPT << 'EOF';
1453 print PBOUT $_;
1454}
1455close(PBFILE);
1456close(PBOUT);
1457rename("$file.new",$file);
1458chmod 0640,$file;
1459
1460# pb has to be added to portage group on gentoo
1461
1462# Adapt sudoers
1463$file="/etc/sudoers";
1464open(PBFILE,$file) || die "Unable to open $file";
1465open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1466while (<PBFILE>) {
1467EOF
1468 print SCRIPT << "EOF";
1469 next if (/^$pbac->{$ENV{'PBPROJ'}} /);
1470EOF
1471 print SCRIPT << 'EOF';
1472 s/Defaults[ \t]+requiretty//;
1473 print PBOUT $_;
1474}
1475close(PBFILE);
1476EOF
1477 print SCRIPT << "EOF";
1478# This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
1479print PBOUT "$pbac->{$ENV{'PBPROJ'}} ALL=(ALL) NOPASSWD:ALL\n";
1480EOF
1481 print SCRIPT << 'EOF';
1482close(PBOUT);
1483rename("$file.new",$file);
1484chmod 0440,$file;
1485
1486EOF
1487
1488 my $SCRIPT = \*SCRIPT;
1489
1490 pb_install_deps($SCRIPT);
1491
1492 print SCRIPT << 'EOF';
1493# Suse wants sudoers as 640
1494if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
1495 chmod 0640,$file;
1496}
1497
1498# Sync date
1499#system "/usr/sbin/ntpdate ntp.pool.org";
1500
1501pb_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");
1502system "pb 2>&1 | head -5";
1503EOF
1504 if ((! $vmexist) && ($vtype eq "vm")) {
1505 print SCRIPT << 'EOF';
1506pb_system("sudo /sbin/halt -p","Halting the $vtype");
1507EOF
1508 }
1509
1510 # Adds pb_distro_init from ProjectBuilder::Distribution
1511 foreach my $d (@INC) {
1512 my @f = ("$d/ProjectBuilder/Base.pm","$d/ProjectBuilder/Distribution.pm");
1513 foreach my $f (@f) {
1514 if (-f "$f") {
1515 open(PBD,"$f") || die "Unable to open $f";
1516 while (<PBD>) {
1517 next if (/^package/);
1518 next if (/^use Exporter/);
1519 next if (/^use ProjectBuilder::/);
1520 next if (/^our /);
1521 print SCRIPT $_;
1522 }
1523 close(PBD);
1524 }
1525 }
1526 }
1527 close(SCRIPT);
1528 chmod 0755,"$pbscript";
1529
1530 # That build script needs to be run as root
1531 $pbaccount = "root";
1532 pb_script2v($pbscript,$vtype);
1533}
1534return;
1535}
1536
1537sub pb_install_deps {
1538
1539my $SCRIPT = shift;
1540
1541print {$SCRIPT} << 'EOF';
1542# We need to have that pb_distro_init function
1543# Get it from Project-Builder::Distribution
1544my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
1545print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
1546
1547# Get and install pb
1548my $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*";
1549my $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*";
1550my $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*";
1551my $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*";
1552my $cmtdm = "Installing Date-Manip perl module";
1553my $cmtmb = "Installing Module-Build perl module";
1554my $cmtfm = "Installing File-MimeInfo perl module";
1555my $cmtfb = "Installing File-Basedir perl module";
1556my $cmtall = "Installing required modules";
1557
1558if ( $ddir eq "fedora" ) {
1559 pb_system("yum clean all","Cleaning yum env");
1560 #system "yum update -y";
1561 my $arch=`uname -m`;
1562 my $opt = "";
1563 chomp($arch);
1564 if ($arch eq "x86_64") {
1565 $opt="--exclude=*.i?86";
1566 }
1567
1568 pb_system("yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker",$cmtall);
1569 if ($dver eq 4) {
1570 pb_system("$insmb","$cmtmb");
1571 pb_system("$insfm","$cmtfm");
1572 pb_system("$insfb","$cmtfb");
1573 }
1574} elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
1575 # Suppose pkg are installed already as no online mirror available
1576 pb_system("rpm -e lsb 2>&1 > /dev/null","Removing lsb package");
1577 pb_system("$insdm","$cmtdm");
1578 pb_system("$insmb","$cmtmb");
1579 pb_system("$insfm","$cmtfm");
1580 pb_system("$insfb","$cmtfb");
1581} elsif ($ddir eq "suse") {
1582 # New OpenSuSE
1583 pb_system("$insmb","$cmtmb");
1584 pb_system("$insfm","$cmtfm");
1585 pb_system("$insfb","$cmtfb");
1586 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");
1587} elsif ( $dfam eq "md" ) {
1588 pb_system("urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo","$cmtall");
1589 if (($ddir eq "mandrake") && ($dver eq "10.1")) {
1590 pb_system("$insdm","$cmtdm");
1591 } else {
1592 pb_system("urpmi --auto perl-DateManip","$cmtdm");
1593 }
1594} elsif ( $dfam eq "du" ) {
1595 if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
1596 #system "apt-get update";
1597 pb_system("$insfb","$cmtfb");
1598 pb_system("$insfm","$cmtfm");
1599 pb_system("apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl","$cmtall");
1600 } else {
1601 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");
1602 }
1603} elsif ( $dfam eq "gen" ) {
1604 #system "emerge -u system";
1605 pb_system("emerge wget sudo ntp DateManip File-MimeInfo","$cmtall");
1606} else {
1607 print "No pkg to install\n";
1608}
1609EOF
1610}
1611
1612# Return the SSH key file to use
1613# Potentially create it if needed
1614
1615sub pb_ssh_get {
1616
1617my $create = shift || 0; # Do not create keys by default
1618
1619# Check the SSH environment
1620my $keyfile = undef;
1621
1622# We have specific keys by default
1623$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
1624if (!(-e $keyfile) && ($create eq 1)) {
1625 pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
1626}
1627
1628$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
1629$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
1630$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
1631die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
1632return($keyfile);
1633}
1634
1635
1636# Returns the pid of a running VM command using a specific VM file
1637sub pb_check_ps {
1638 my $vmcmd = shift;
1639 my $vmm = shift;
1640 my $vmexist = 0; # FALSE by default
1641
1642 open(PS, "ps auxhww|") || die "Unable to call ps";
1643 while (<PS>) {
1644 next if (! /$vmcmd/);
1645 next if (! /$vmm/);
1646 my ($void1, $void2);
1647 ($void1, $vmexist, $void2) = split(/ +/);
1648 last;
1649 }
1650 return($vmexist);
1651}
1652
1653
1654sub pb_extract_build_files {
1655
1656my $src=shift;
1657my $dir=shift;
1658my $ddir=shift;
1659my @files;
1660
1661if ($src =~ /tar\.gz$/) {
1662 pb_system("tar xfpz $src $dir","Extracting build files");
1663} elsif ($src =~ /tar\.bz2$/) {
1664 pb_system("tar xfpj $src $dir","Extracting build files");
1665} else {
1666 die "Unknown compression algorithm for $src";
1667}
1668opendir(DIR,"$dir") || die "Unable to open directory $dir";
1669foreach my $f (readdir(DIR)) {
1670 next if ($f =~ /^\./);
1671 move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
1672 pb_log(2,"mv $dir/$f $ddir\n");
1673 push @files,"$ddir/$f";
1674}
1675closedir(DIR);
1676# Not enough but still a first cleanup
1677pb_rm_rf("$dir");
1678return(@files);
1679}
1680
1681sub pb_list_bfiles {
1682
1683my $dir = shift;
1684my $pbpkg = shift;
1685my $bfiles = shift;
1686my $pkgfiles = shift;
1687my $supfiles = shift;
1688
1689opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
1690foreach my $f (readdir(BDIR)) {
1691 next if ($f =~ /^\./);
1692 $bfiles->{$f} = "$dir/$f";
1693 $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
1694 if (defined $supfiles->{$pbpkg}) {
1695 $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
1696 }
1697}
1698closedir(BDIR);
1699}
1700
1701
1702#
1703# Return the list of packages we are working on in a non CMS action
1704#
1705sub pb_get_pkg {
1706
1707my @pkgs = ();
1708
1709my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
1710@pkgs = keys %$var;
1711
1712pb_log(0,"Packages: ".join(',',@pkgs)."\n");
1713return(\@pkgs);
1714}
1715
17161;
Note: See TracBrowser for help on using the repository browser.