source: devel/pb/bin/pb @ 442

Last change on this file since 442 was 442, checked in by bruno, 12 years ago

Adds support for multi VM for setupvm command (took way too much time to debug, I'm really tired :-()

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