source: devel/pb/bin/pb @ 416

Last change on this file since 416 was 416, checked in by Bruno Cornec, 12 years ago

move the pb_env_init function to a separate module to allow pbinit usage

  • Property svn:executable set to *
File size: 51.6 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    pb_log(0,"Debug value: $debug\n");
334}
335if (defined $opts{'f'}) {
336    $force=1;
337}
338if (defined $opts{'q'}) {
339    $debug=-1;
340}
341if (defined $opts{'l'}) {
342    open(LOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
343    $LOG = \*LOG;
344    $debug = 0  if ($debug == -1);
345    }
346pb_log_init($debug, $LOG);
347
348# Handle root of the project if defined
349if (defined $opts{'r'}) {
350    $ENV{'PBROOTDIR'} = $opts{'r'};
351}
352# Handle virtual machines if any
353if (defined $opts{'m'}) {
354    $ENV{'PBV'} = $opts{'m'};
355}
356if (defined $opts{'s'}) {
357    $pbscript = $opts{'s'};
358}
359if (defined $opts{'a'}) {
360    $pbaccount = $opts{'a'};
361    die "option -a requires a -s script option" if (not defined $pbscript);
362}
363if (defined $opts{'P'}) {
364    $pbport = $opts{'P'};
365}
366if (defined $opts{'V'}) {
367    $newver = $opts{'V'};
368}
369if (defined $opts{'i'}) {
370    $iso = $opts{'i'};
371}
372
373# Get Action
374$action = shift @ARGV;
375die pb_syntax(-1,1) if (not defined $action);
376
377my ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir);
378my $pbinit = undef;
379$pbinit = 1 if ($action =~ /^newproj$/);
380
381# Handles project name if any
382# And get global params
383($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) = pb_env_init($opts{'p'},$pbinit,$action);
384
385pb_log(0,"Project: $ENV{'PBPROJ'}\n");
386pb_log(0,"Action: $action\n");
387
388# Act depending on action
389if ($action =~ /^cms2build$/) {
390    pb_cms2build();
391} elsif ($action =~ /^build2pkg$/) {
392    pb_build2pkg();
393} elsif ($action =~ /^cms2pkg$/) {
394    pb_cms2build();
395    pb_build2pkg();
396} elsif ($action =~ /^build2ssh$/) {
397    pb_build2ssh();
398} elsif ($action =~ /^cms2ssh$/) {
399    pb_cms2build();
400    pb_build2ssh();
401} elsif ($action =~ /^pkg2ssh$/) {
402    pb_pkg2ssh();
403} elsif ($action =~ /^build2ve$/) {
404    pb_build2v("ve");
405} elsif ($action =~ /^build2vm$/) {
406    pb_build2v("vm");
407} elsif ($action =~ /^cms2ve$/) {
408    pb_cms2build();
409    pb_build2v("ve");
410} elsif ($action =~ /^cms2vm$/) {
411    pb_cms2build();
412    pb_build2v("vm");
413} elsif ($action =~ /^launchvm$/) {
414    pb_launchv("vm",$ENV{'PBV'},0);
415} elsif ($action =~ /^launchve$/) {
416    pb_launchv("ve",$ENV{'PBV'},0);
417} elsif ($action =~ /^script2vm$/) {
418    pb_script2v($pbscript,"vm");
419} elsif ($action =~ /^script2ve$/) {
420    pb_script2v($pbscript,"ve");
421} elsif ($action =~ /^newver$/) {
422    pb_newver();
423} elsif ($action =~ /^newve$/) {
424    pb_launchv("ve",$ENV{'PBV'},1);
425} elsif ($action =~ /^newvm$/) {
426    pb_launchv("vm",$ENV{'PBV'},1);
427} elsif ($action =~ /^setupve$/) {
428    pb_setup_v("ve");
429} elsif ($action =~ /^setupvm$/) {
430    pb_setup_v("vm");
431} elsif ($action =~ /^newproj$/) {
432    # Nothing to do - already done in pb_env_init
433} elsif ($action =~ /^clean$/) {
434} else {
435    pb_log(0,"\'$action\' is not available\n");
436    pb_syntax(-2,1);
437}
438
439sub pb_cms2build {
440
441    my $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
442    my @pkgs = @$pkg;
443    my %pkgs;
444
445    my ($scheme, $uri) = pb_cms_init($pbinit);
446
447    my ($pkgv, $pkgt) = pb_conf_get_if("pkgver","pkgtag");
448
449    # declare packager for filtering
450    my ($tmp) = pb_conf_get("pbpackager");
451    $ENV{'PBPACKAGER'} = $tmp->{$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);
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'});
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'});
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    if (($cmt eq "vm") || ($cmt eq "ve")) {
827        $src="$src $ENV{'PBDESTDIR'}/pbscript $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc";
828        # Adds conf file used for final delivery
829        pb_conf_add("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb");
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
1331EOF
1332    if ($vtype eq "vm") {
1333        print SCRIPT << 'EOF';
1334# Removes duplicate in .ssh/authorized_keys of our key if needed
1335#
1336my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
1337open(PBFILE,$file1) || die "Unable to open $file1";
1338open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
1339my $count = 0;
1340while (<PBFILE>) {
1341EOF
1342        print SCRIPT << "EOF";
1343    if (/ $key /) {
1344        \$count++;
1345    }
1346print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
1347}
1348close(PBFILE);
1349close(PBOUT);
1350rename("\$file1.new",\$file1);
1351chmod 0600,\$file1;
1352EOF
1353    }
1354    print SCRIPT << 'EOF';
1355
1356# Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
1357#
1358my $file="/etc/passwd";
1359open(PBFILE,$file) || die "Unable to open $file";
1360my $found = 0;
1361while (<PBFILE>) {
1362EOF
1363    print SCRIPT << "EOF";
1364    \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
1365EOF
1366    print SCRIPT << 'EOF';
1367}
1368close(PBFILE);
1369
1370if ( $found == 0 ) {
1371    if ( ! -d "/home" ) {
1372        mkdir "/home";
1373    }
1374EOF
1375    print SCRIPT << "EOF";
1376system "groupadd $pbac->{$ENV{'PBPROJ'}}";
1377system "useradd $pbac->{$ENV{'PBPROJ'}} -g $pbac->{$ENV{'PBPROJ'}} -m -d /home/$pbac->{$ENV{'PBPROJ'}}";
1378
1379# allow ssh entry to build
1380#
1381chdir "/home/$pbac->{$ENV{'PBPROJ'}}";
1382mkdir ".ssh",0700;
1383# Allow those accessing root to access the build account
1384copy("\$ENV{'HOME'}/.ssh/authorized_keys",".ssh/authorized_keys");
1385chmod 0600,".ssh/authorized_keys";
1386system 'chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} .ssh';
1387
1388EOF
1389    print SCRIPT << 'EOF';
1390}
1391
1392# No passwd for build account only keys
1393$file="/etc/shadow";
1394open(PBFILE,$file) || die "Unable to open $file";
1395open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1396while (<PBFILE>) {
1397EOF
1398    print SCRIPT << "EOF";
1399    s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
1400    s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
1401EOF
1402    print SCRIPT << 'EOF';
1403    print PBOUT $_;
1404}
1405close(PBFILE);
1406close(PBOUT);
1407rename("$file.new",$file);
1408chmod 0640,$file;
1409
1410# pb has to be added to portage group on gentoo
1411
1412# Adapt sudoers
1413$file="/etc/sudoers";
1414open(PBFILE,$file) || die "Unable to open $file";
1415open(PBOUT,"> $file.new") || die "Unable to open $file.new";
1416while (<PBFILE>) {
1417EOF
1418    print SCRIPT << "EOF";
1419    next if (/^$pbac->{$ENV{'PBPROJ'}}   /);
1420EOF
1421    print SCRIPT << 'EOF';
1422    s/Defaults[ \t]+requiretty//;
1423    print PBOUT $_;
1424}
1425close(PBFILE);
1426EOF
1427    print SCRIPT << "EOF";
1428# This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
1429print PBOUT "$pbac->{$ENV{'PBPROJ'}}   ALL=(ALL) NOPASSWD:ALL\n";
1430EOF
1431    print SCRIPT << 'EOF';
1432close(PBOUT);
1433rename("$file.new",$file);
1434chmod 0440,$file;
1435
1436EOF
1437       
1438    my $SCRIPT = \*SCRIPT;
1439   
1440    pb_install_deps($SCRIPT);
1441   
1442    print SCRIPT << 'EOF';
1443# Suse wants sudoers as 640
1444if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
1445    chmod 0640,$file;
1446}
1447
1448# Sync date
1449#system "/usr/sbin/ntpdate ntp.pool.org";
1450
1451system "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-*";
1452system "pb 2>&1 | head -5";
1453EOF
1454    if ((! $vmexist) && ($vtype eq "vm")) {
1455        print SCRIPT << 'EOF';
1456system "sudo /sbin/halt -p";
1457EOF
1458    }
1459   
1460    # Adds pb_distro_init from ProjectBuilder::Distribution
1461    foreach my $d (@INC) {
1462        my @f = ("$d/ProjectBuilder/Base.pm","$d/ProjectBuilder/Distribution.pm");
1463        foreach my $f (@f) {
1464            if (-f "$f") {
1465                open(PBD,"$f") || die "Unable to open $f";
1466                while (<PBD>) {
1467                    next if (/^package/);
1468                    next if (/^use Exporter/);
1469                    next if (/^use ProjectBuilder::Base/);
1470                    next if (/^our \@/);
1471                    print SCRIPT $_;
1472                }
1473                close(PBD);
1474            }
1475        }
1476    }
1477    close(SCRIPT);
1478    chmod 0755,"$pbscript";
1479
1480    # That build script needs to be run as root
1481    $pbaccount = "root";
1482    pb_script2v($pbscript,$vtype);
1483}
1484return;
1485}
1486
1487sub pb_install_deps {
1488
1489my $SCRIPT = shift;
1490
1491print {$SCRIPT} << 'EOF';
1492# We need to have that pb_distro_init function
1493# Get it from Project-Builder::Distribution
1494my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init(); 
1495print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
1496
1497# Get and install pb
1498my $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*";
1499my $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*";
1500my $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*";
1501my $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*";
1502
1503if ( $ddir eq "fedora" ) {
1504    system "yum clean all";
1505    #system "yum update -y";
1506    my $arch=`uname -m`;
1507    my $opt = "";
1508    chomp($arch);
1509    if ($arch eq "x86_64") {
1510        $opt="--exclude=*.i?86";
1511    }
1512
1513    system "yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker";
1514    if ($dver eq 4) {
1515        system "$insmb";
1516        system "$insfm";
1517        system "$insfb";
1518    }
1519} elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
1520    # Suppose pkg are installed already as no online mirror available
1521    system "rpm -e lsb 2>&1 > /dev/null";
1522    system "$insdm";
1523    system "$insmb";
1524    system "$insfm";
1525    system "$insfb";
1526} elsif ($ddir eq "suse") { 
1527    # New OpenSuSE
1528    system "$insmb";
1529    system "$insfm";
1530    system "$insfb";
1531    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";
1532} elsif ( $dfam eq "md" ) {
1533        system "urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo";
1534        if (($ddir eq "mandrake") && ($dver eq "10.1")) {
1535            system "$insdm";
1536        } else {
1537            system "urpmi --auto perl-DateManip";
1538        }
1539} elsif ( $dfam eq "du" ) {
1540    if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
1541        #system "apt-get update";
1542        system "$insfb";
1543        system "$insfm";
1544        system "apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl";
1545    } else  {
1546        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";
1547    }
1548} elsif ( $dfam eq "gen" ) {
1549        #system "emerge -u system ; emerge wget sudo ntp DateManip File-MimeInfo";
1550        system "emerge wget sudo ntp DateManip File-MimeInfo";
1551} else {
1552    print "No pkg to install\n";
1553}
1554EOF
1555}
1556
1557# Return the SSH key file to use
1558# Potentially create it if needed
1559
1560sub pb_ssh_get {
1561
1562my $create = shift || 0;    # Do not create keys by default
1563
1564# Check the SSH environment
1565my $keyfile = undef;
1566
1567# We have specific keys by default
1568$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
1569if (!(-e $keyfile) && ($create eq 1)) {
1570    pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
1571}
1572
1573$keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
1574$keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
1575$keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
1576die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
1577return($keyfile);
1578}
1579
1580
1581# Returns the pid of a running VM command using a specific VM file
1582sub pb_check_ps {
1583    my $vmcmd = shift;
1584    my $vmm = shift;
1585    my $vmexist = 0;        # FALSE by default
1586
1587    open(PS, "ps auxhww|") || die "Unable to call ps";
1588    while (<PS>) {
1589        next if (! /$vmcmd/);
1590        next if (! /$vmm/);
1591        my ($void1, $void2);
1592        ($void1, $vmexist, $void2) = split(/ +/);
1593        last;
1594    }
1595    return($vmexist);
1596}
1597
1598
1599sub pb_extract_build_files {
1600
1601my $src=shift;
1602my $dir=shift;
1603my $ddir=shift;
1604my @files;
1605
1606if ($src =~ /tar\.gz$/) {
1607    pb_system("tar xfpz $src $dir","Extracting build files");
1608} elsif ($src =~ /tar\.bz2$/) {
1609    pb_system("tar xfpj $src $dir","Extracting build files");
1610} else {
1611    die "Unknown compression algorithm for $src";
1612}
1613opendir(DIR,"$dir") || die "Unable to open directory $dir";
1614foreach my $f (readdir(DIR)) {
1615    next if ($f =~ /^\./);
1616    move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
1617    pb_log(2,"mv $dir/$f $ddir\n");
1618    push @files,"$ddir/$f";
1619}
1620closedir(DIR);
1621# Not enough but still a first cleanup
1622pb_rm_rf("$dir");
1623return(@files);
1624}
1625
1626sub pb_list_bfiles {
1627
1628my $dir = shift;
1629my $pbpkg = shift;
1630my $bfiles = shift;
1631my $pkgfiles = shift;
1632my $supfiles = shift;
1633
1634opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
1635foreach my $f (readdir(BDIR)) {
1636    next if ($f =~ /^\./);
1637    $bfiles->{$f} = "$dir/$f";
1638    $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
1639    if (defined $supfiles->{$pbpkg}) {
1640        $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
1641    }
1642}
1643closedir(BDIR);
1644}
1645
1646
1647#
1648# Return the list of packages we are working on in a non CMS action
1649#
1650sub pb_get_pkg {
1651
1652my @pkgs = ();
1653
1654my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
1655@pkgs = keys %$var;
1656
1657pb_log(0,"Packages: ".join(',',@pkgs)."\n");
1658return(\@pkgs);
1659}
1660
16611;
Note: See TracBrowser for help on using the repository browser.