source: devel/pb/bin/pb @ 417

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