source: devel/pb/bin/pb @ 427

Revision 427, 52.7 KB checked in by bruno, 5 years ago (diff)

Improve setupv to use pb functions and setup the pb account ssh env correctly now when reusing the VMs

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