Changeset 405


Ignore:
Timestamp:
Apr 20, 2008, 1:59:47 PM (11 years ago)
Author:
bruno
Message:

Split again function in modules to allow for usage with pbinit and easier reuse.

Location:
devel
Files:
2 added
4 edited
2 copied

Legend:

Unmodified
Added
Removed
  • devel/pb-modules/Makefile.PL

    r403 r405  
    1818    EXE_FILES     => [ qw( bin/pbdistrocheck ) ],
    1919    MAN3PODS      => {  'lib/ProjectBuilder/Distribution.pm' => '$(INST_MAN3DIR)/ProjectBuilder::Distribution.$(MAN3EXT)',
     20                        'lib/ProjectBuilder/Conf.pm' => '$(INST_MAN3DIR)/ProjectBuilder::Conf.$(MAN3EXT)',
    2021                        'lib/ProjectBuilder/Base.pm' => '$(INST_MAN3DIR)/ProjectBuilder::Base.$(MAN3EXT)', },
    2122);
  • devel/pb-modules/lib/ProjectBuilder/Base.pm

    r402 r405  
    3333
    3434our @ISA = qw(Exporter);
    35 our @EXPORT = qw(pb_conf_read pb_conf_read_if pb_mkdir_p pb_system pb_rm_rf pb_get_date pb_log pb_log_init pb_get_uri pb_get_content pb_display_file pb_syntax_init pb_syntax pb_temp_init $debug $LOG);
     35our @EXPORT = qw(pb_mkdir_p pb_system pb_rm_rf pb_get_date pb_log pb_log_init pb_get_uri pb_get_content pb_display_file pb_syntax_init pb_syntax pb_temp_init $debug $LOG);
    3636
    3737=pod
     
    6363  #
    6464  pb_system("ls -l", "Printing directory content");
    65 
    66   #
    67   # Read hash codes of values from a configuration file and return table of pointers
    68   #
    69   my ($k1, $k2) = pb_conf_read_if("$ENV{'HOME'}/.pbrc","key1","key2");
    70   my ($k) = pb_conf_read("$ENV{'HOME'}/.pbrc","key");
    7165
    7266  #
     
    162156}
    163157
    164 =item B<pb_conf_read_if>
    165 
    166 This function returns a table of pointers on hashes
    167 corresponding to the keys in a configuration file passed in parameter.
    168 If that file doesn't exist, it returns undef.
    169 
    170 The format of the configuration file is as follows:
    171 
    172 key tag = value1,value2,...
    173 
    174 Supposing the file is called "$ENV{'HOME'}/.pbrc", containing the following:
    175 
    176   $ cat $HOME/.pbrc
    177   pbver pb = 3
    178   pbver default = 1
    179   pblist pb = 12,25
    180 
    181 calling it like this:
    182 
    183   my ($k1, $k2) = pb_conf_read_if("$ENV{'HOME'}/.pbrc","pbver","pblist");
    184 
    185 will allow to get the mapping:
    186 
    187   $k1->{'pb'}  contains 3
    188   $ka->{'default'} contains 1
    189   $k2->{'pb'} contains 12,25
    190 
    191 Valid chars for keys and tags are letters, numbers, '-' and '_'.
    192 
    193 =cut
    194 
    195 sub pb_conf_read_if {
    196 
    197 my $conffile = shift;
    198 my @param = @_;
    199 
    200 open(CONF,$conffile) || return((undef));
    201 close(CONF);
    202 return(pb_conf_read($conffile,@param));
    203 }
    204 
    205 =item B<pb_conf_read>
    206 
    207 This function is similar to B<pb_conf_read_if> except that it dies when the file in parameter doesn't exist.
    208 
    209 =cut
    210 
    211 sub pb_conf_read {
    212 
    213 my $conffile = shift;
    214 my @param = @_;
    215 my $trace;
    216 my @ptr;
    217 my %h;
    218 
    219 open(CONF,$conffile) || die "Unable to open $conffile";
    220 while(<CONF>) {
    221     if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
    222         pb_log(3,"DEBUG: 1:$1 2:$2 3:$3\n");
    223         $h{$1}{$2}=$3;
    224     }
    225 }
    226 close(CONF);
    227 
    228 for my $param (@param) {
    229     push @ptr,$h{$param};
    230 }
    231 return(@ptr);
    232 }
    233 
    234158=item B<pb_get_uri>
    235159
  • devel/pb/Makefile.PL

    r403 r405  
    1818    EXE_FILES     => [ qw( bin/pb bin/pbg bin/pbvi ) ],
    1919    MAN1PODS      => { 'bin/pb' => '$(INST_MAN1DIR)/pb.$(MAN1EXT)', },
     20    MAN3PODS      => {  'lib/ProjectBuilder/CMS.pm' => '$(INST_MAN3DIR)/ProjectBuilder::CMS.$(MAN3EXT)',
     21                        'lib/ProjectBuilder/Filter.pm' => '$(INST_MAN3DIR)/ProjectBuilder::Filter.$(MAN3EXT)',
     22                        'lib/ProjectBuilder/Changelog.pm' => '$(INST_MAN3DIR)/ProjectBuilder::Changelog.$(MAN3EXT)', },
    2023);
  • devel/pb/bin/pb

    r397 r405  
    1818use File::stat;
    1919use File::Temp qw(tempdir);
    20 use Date::Manip;
    2120use POSIX qw(strftime);
    2221use lib qw (lib);
    23 use ProjectBuilder::Distribution;
    2422use ProjectBuilder::Version;
    2523use ProjectBuilder::Base;
     24use ProjectBuilder::Conf;
     25use ProjectBuilder::Distribution;
     26use ProjectBuilder::CMS;
     27use ProjectBuilder::Filter;
    2628
    2729# Global variables
     
    14541456    # Adds pb_distro_init from ProjectBuilder::Distribution
    14551457    foreach my $d (@INC) {
    1456         my $f = "$d/ProjectBuilder/Distribution.pm";
    1457         if (-f "$f") {
    1458             open(PBD,"$f") || die "Unable to open $f";
    1459             while (<PBD>) {
    1460                 next if (/^package/);
    1461                 next if (/^use Exporter/);
    1462                 next if (/^\@our /);
    1463                 print SCRIPT $_;
    1464             }
    1465             close(PBD);
    1466             last;
     1458        my @f = ("$d/ProjectBuilder/Base.pm","$d/ProjectBuilder/Distribution.pm");
     1459        foreach my $f (@f) {
     1460            if (-f "$f") {
     1461                open(PBD,"$f") || die "Unable to open $f";
     1462                while (<PBD>) {
     1463                    next if (/^package/);
     1464                    next if (/^use Exporter/);
     1465                    next if (/^use ProjectBuilder::Base/);
     1466                    next if (/^our \@/);
     1467                    print SCRIPT $_;
     1468                }
     1469                close(PBD);
     1470            }
    14671471        }
    14681472    }
     
    24252429}
    24262430
    2427 # Function which returns a pointer on a table
    2428 # corresponding to a set of values queried in the conf file
    2429 # and test the returned vaue as they need to exist in that case
    2430 sub pb_conf_get {
    2431 
    2432 my @param = @_;
    2433 my @return = pb_conf_get_if(@param);
    2434 
    2435 die "No params found for $ENV{'PBPROJ'}" if (not @return);
    2436 
    2437 foreach my $i (0..$#param) {
    2438     die "No $param[$i] defined for $ENV{'PBPROJ'}" if (not defined $return[$i]);
    2439 }
    2440 return(@return);
    2441 }
    2442 
    2443 # Function which returns a pointer on a table
    2444 # corresponding to a set of values queried in the conf file
    2445 # Those value may be undef if they do not exist
    2446 sub pb_conf_get_if {
    2447 
    2448 my @param = @_;
    2449 
    2450 # Everything is returned via ptr1
    2451 my @ptr1 = ();
    2452 my @ptr2 = ();
    2453 @ptr1 = pb_conf_read_if("$ENV{'PBETC'}", @param) if (defined $ENV{'PBETC'});
    2454 @ptr2 = pb_conf_read_if("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb", @param) if ((defined $ENV{'PBROOTDIR'}) and (defined $ENV{'PBPROJ'}));
    2455 
    2456 my $p1;
    2457 my $p2;
    2458 
    2459 pb_log(2,"DEBUG: pb_conf_get param1: ".Dumper(@ptr1)."\n");
    2460 pb_log(2,"DEBUG: pb_conf_get param2: ".Dumper(@ptr2)."\n");
    2461 
    2462 foreach my $i (0..$#param) {
    2463     $p1 = $ptr1[$i];
    2464     $p2 = $ptr2[$i];
    2465     # Always try to take the param from the home dir conf file in priority
    2466     # in order to mask what could be defined under the CMS to allow for overloading
    2467     if (not defined $p2) {
    2468         # No ref in CMS project conf file so use the home dir one.
    2469         $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if ((not defined $p1->{$ENV{'PBPROJ'}}) && (defined $p1->{'default'}));
    2470     } else {
    2471         # Ref found in CMS project conf file
    2472         if (not defined $p1) {
    2473             # No ref in home dir project conf file so use the CMS one.
    2474             $p2->{$ENV{'PBPROJ'}} = $p2->{'default'} if ((not defined $p2->{$ENV{'PBPROJ'}}) && (defined $p2->{'default'}));
    2475             $p1 = $p2;
    2476         } else {
    2477             # Both are defined - handling the overloading
    2478             if (not defined $p1->{'default'}) {
    2479                 if (defined $p2->{'default'}) {
    2480                     $p1->{'default'} = $p2->{'default'};
    2481                 }
    2482             }
    2483 
    2484             if (not defined $p1->{$ENV{'PBPROJ'}}) {
    2485                 if (defined $p2->{$ENV{'PBPROJ'}}) {
    2486                     $p1->{$ENV{'PBPROJ'}} = $p2->{$ENV{'PBPROJ'}} if (defined $p2->{$ENV{'PBPROJ'}});
    2487                 } else {
    2488                     $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if (defined $p1->{'default'});
    2489                 }
    2490             }
    2491             # Now copy back into p1 all p2 content which doesn't exist in p1
    2492             # p1 content (local) always has priority over p2 (project)
    2493             foreach my $k (keys %$p2) {
    2494                 $p1->{$k} = $p2->{$k} if (not defined $p1->{$k});
    2495             }
    2496         }
    2497     }
    2498     $ptr1[$i] = $p1;
    2499 }
    2500 pb_log(2,"DEBUG: pb_conf_get param ptr1: ".Dumper(@ptr1)."\n");
    2501 return(@ptr1);
    2502 }
    2503 
    2504 # Setup environment for CMS system for URL passed
    2505 sub pb_cms_init {
    2506 
    2507 my $pbinit = shift || undef;
    2508 
    2509 my ($pburl) = pb_conf_get("pburl");
    2510 pb_log(2,"DEBUG: Project URL of $ENV{'PBPROJ'}: $pburl->{$ENV{'PBPROJ'}}\n");
    2511 my ($scheme, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
    2512 
    2513 my ($pbprojdir) = pb_conf_get_if("pbprojdir");
    2514 
    2515 if ((defined $pbprojdir) && (defined $pbprojdir->{$ENV{'PBPROJ'}})) {
    2516     $ENV{'PBPROJDIR'} = $pbprojdir->{$ENV{'PBPROJ'}};
    2517 } else {
    2518     $ENV{'PBPROJDIR'} = "$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}";
    2519 }
    2520 
    2521 # Computing the default dir for PBDIR.
    2522 # what we have is PBPROJDIR so work from that.
    2523 # Tree identical between PBCONFDIR and PBROOTDIR on one side and
    2524 # PBPROJDIR and PBDIR on the other side.
    2525 
    2526 my $tmp = $ENV{'PBROOTDIR'};
    2527 $tmp =~ s|^$ENV{'PBCONFDIR'}||;
    2528 
    2529 #
    2530 # Check project cms compliance
    2531 #
    2532 pb_cms_compliant(undef,'PBDIR',"$ENV{'PBPROJDIR'}/$tmp",$pburl->{$ENV{'PBPROJ'}},$pbinit);
    2533 
    2534 if ($scheme =~ /^svn/) {
    2535     # svnversion more precise than svn info
    2536     $tmp = `(cd "$ENV{'PBDIR'}" ; svnversion .)`;
    2537     chomp($tmp);
    2538     $ENV{'PBREVISION'}=$tmp;
    2539     $ENV{'PBCMSLOGFILE'}="svn.log";
    2540 } elsif (($scheme eq "file") || ($scheme eq "ftp") || ($scheme eq "http")) {
    2541     $ENV{'PBREVISION'}="flat";
    2542     $ENV{'PBCMSLOGFILE'}="flat.log";
    2543 } elsif ($scheme =~ /^cvs/) {
    2544     # Way too slow
    2545     #$ENV{'PBREVISION'}=`(cd "$ENV{'PBROOTDIR'}" ; cvs rannotate  -f . 2>&1 | awk '{print \$1}' | grep -E '^[0-9]' | cut -d. -f2 |sort -nu | tail -1)`;
    2546     #chomp($ENV{'PBREVISION'});
    2547     $ENV{'PBREVISION'}="cvs";
    2548     $ENV{'PBCMSLOGFILE'}="cvs.log";
    2549     $ENV{'CVS_RSH'} = "ssh" if ($scheme =~ /ssh/);
    2550 } else {
    2551     die "cms $scheme unknown";
    2552 }
    2553 
    2554 return($scheme,$pburl->{$ENV{'PBPROJ'}});
    2555 }
    2556 
    2557 sub pb_cms_export {
    2558 
    2559 my $uri = shift;
    2560 my $source = shift;
    2561 my $destdir = shift;
    2562 my $tmp;
    2563 my $tmp1;
    2564 
    2565 my @date = pb_get_date();
    2566 # If it's not flat, then we have a real uri as source
    2567 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
    2568 
    2569 if ($scheme =~ /^svn/) {
    2570     if (-d $source) {
    2571         $tmp = $destdir;
    2572     } else {
    2573         $tmp = "$destdir/".basename($source);
    2574     }
    2575     pb_system("svn export $source $tmp","Exporting $source from SVN to $tmp");
    2576 } elsif ($scheme eq "dir") {
    2577     pb_system("cp -a $path $destdir","Copying $uri from DIR to $destdir");
    2578 } elsif (($scheme eq "http") || ($scheme eq "ftp")) {
    2579     my $f = basename($path);
    2580     unlink "$ENV{'PBTMP'}/$f";
    2581     if (-x "/usr/bin/wget") {
    2582         pb_system("/usr/bin/wget -nv -O $ENV{'PBTMP'}/$f $uri"," ");
    2583     } elsif (-x "/usr/bin/curl") {
    2584         pb_system("/usr/bin/curl $uri -o $ENV{'PBTMP'}/$f","Downloading $uri with curl to $ENV{'PBTMP'}/$f\n");
    2585     } else {
    2586         die "Unable to download $uri.\nNo wget/curl available, please install one of those";
    2587     }
    2588     pb_cms_export("file://$ENV{'PBTMP'}/$f",$source,$destdir);
    2589 } elsif ($scheme eq "file") {
    2590     use File::MimeInfo;
    2591     my $mm = mimetype($path);
    2592     pb_log(2,"mimetype: $mm\n");
    2593     pb_mkdir_p($destdir);
    2594 
    2595     # Check whether the file is well formed
    2596     # (containing already a directory with the project-version name)
    2597     my ($pbwf) = pb_conf_get_if("pbwf");
    2598     if ((defined $pbwf) && (defined $pbwf->{$ENV{'PBPROJ'}})) {
    2599         $destdir = dirname($destdir);
    2600     }
    2601 
    2602     if ($mm =~ /\/x-bzip-compressed-tar$/) {
    2603         # tar+bzip2
    2604         pb_system("cd $destdir ; tar xfj $path","Extracting $path in $destdir");
    2605     } elsif ($mm =~ /\/x-lzma-compressed-tar$/) {
    2606         # tar+lzma
    2607         pb_system("cd $destdir ; tar xfY $path","Extracting $path in $destdir");
    2608     } elsif ($mm =~ /\/x-compressed-tar$/) {
    2609         # tar+gzip
    2610         pb_system("cd $destdir ; tar xfz $path","Extracting $path in $destdir");
    2611     } elsif ($mm =~ /\/x-tar$/) {
    2612         # tar
    2613         pb_system("cd $destdir ; tar xf $path","Extracting $path in $destdir");
    2614     } elsif ($mm =~ /\/zip$/) {
    2615         # zip
    2616         pb_system("cd $destdir ; unzip $path","Extracting $path in $destdir");
    2617     }
    2618 } elsif ($scheme =~ /^cvs/) {
    2619     # CVS needs a relative path !
    2620     my $dir=dirname($destdir);
    2621     my $base=basename($destdir);
    2622     # CVS also needs a modules name not a dir
    2623     #if (-d $source) {
    2624         $tmp1 = basename($source);
    2625         #} else {
    2626         #$tmp1 = dirname($source);
    2627         #$tmp1 = basename($tmp1);
    2628         #}
    2629     my $optcvs = "";
    2630 
    2631     # If we're working on the CVS itself
    2632     my $cvstag = basename($ENV{'PBROOTDIR'});
    2633     my $cvsopt = "";
    2634     if ($cvstag eq "cvs") {
    2635         my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
    2636         $cvsopt = "-D \"$pbdate\"";
    2637     } else {
    2638         # we're working on a tag which should be the last part of PBROOTDIR
    2639         $cvsopt = "-r $cvstag";
    2640     }
    2641     pb_system("cd $dir ; cvs -d $account\@$host:$path export $cvsopt -d $base $tmp1","Exporting $tmp1 from $source under CVS to $destdir");
    2642 } else {
    2643     die "cms $scheme unknown";
    2644 }
    2645 }
    2646 
    2647 
    2648 sub pb_create_authors {
    2649 
    2650 my $authors=shift;
    2651 my $dest=shift;
    2652 my $scheme=shift;
    2653 
    2654 return if ($authors eq "/dev/null");
    2655 open(SAUTH,$authors) || die "Unable to open $authors";
    2656 # Save a potentially existing AUTHORS file and write instead toi AUTHORS.pb
    2657 my $ext = "";
    2658 if (-f "$dest/AUTHORS") {
    2659     $ext = ".pb";
    2660 }
    2661 open(DAUTH,"> $dest/AUTHORS$ext") || die "Unable to create $dest/AUTHORS$ext";
    2662 print DAUTH "Authors of the project are:\n";
    2663 print DAUTH "===========================\n";
    2664 while (<SAUTH>) {
    2665     my ($nick,$gcos) = split(/:/);
    2666     chomp($gcos);
    2667     print DAUTH "$gcos";
    2668     if (defined $scheme) {
    2669         # Do not give a scheme for flat types
    2670         my $endstr="";
    2671         if ("$ENV{'PBREVISION'}" ne "flat") {
    2672             $endstr = " under $scheme";
    2673         }
    2674         print DAUTH " ($nick$endstr)\n";
    2675     } else {
    2676         print DAUTH "\n";
    2677     }
    2678 }
    2679 close(DAUTH);
    2680 close(SAUTH);
    2681 }
    2682 
    2683 sub pb_cms_log {
    2684 
    2685 my $scheme = shift;
    2686 my $pkgdir = shift;
    2687 my $dest = shift;
    2688 my $chglog = shift;
    2689 my $authors = shift;
    2690 
    2691 pb_create_authors($authors,$dest,$scheme);
    2692 
    2693 if ($scheme =~ /^svn/) {
    2694     if (! -f "$dest/ChangeLog") {
    2695         if (-x "/usr/bin/svn2cl") {
    2696             # In case we have no network, just create an empty one before to allow correct build
    2697             open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
    2698             close(CL);
    2699             pb_system("/usr/bin/svn2cl --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN with svn2cl");
    2700         } else {
    2701             # To be written from pbcl
    2702             pb_system("svn log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
    2703         }
    2704     }
    2705 } elsif (($scheme eq "file") || ($scheme eq "dir") || ($scheme eq "http") || ($scheme eq "ftp")) {
    2706     if (! -f "$dest/ChangeLog") {
    2707         pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
    2708     }
    2709 } elsif ($scheme =~ /^cvs/) {
    2710     my $tmp=basename($pkgdir);
    2711     # CVS needs a relative path !
    2712     if (! -f "$dest/ChangeLog") {
    2713         if (-x "/usr/bin/cvs2cl") {
    2714             # In case we have no network, just create an empty one before to allow correct build
    2715             open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
    2716             close(CL);
    2717             pb_system("/usr/bin/cvs2cl --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS with cvs2cl");
    2718         } else {
    2719             # To be written from pbcl
    2720             pb_system("cvs log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
    2721         }
    2722     }
    2723 } else {
    2724     die "cms $scheme unknown";
    2725 }
    2726 }
    2727 
    2728 # This function is only called with a real CMS system
    2729 sub pb_cms_get_uri {
    2730 
    2731 my $scheme = shift;
    2732 my $dir = shift;
    2733 
    2734 my $res = "";
    2735 my $void = "";
    2736 
    2737 if ($scheme =~ /^svn/) {
    2738     open(PIPE,"LANGUAGE=C svn info $dir |") || return("");
    2739     while (<PIPE>) {
    2740         ($void,$res) = split(/^URL:/) if (/^URL:/);
    2741     }
    2742     $res =~ s/^\s*//;
    2743     close(PIPE);
    2744     chomp($res);
    2745 } elsif ($scheme =~ /^cvs/) {
    2746     # This path is always the root path of CVS, but we may be below
    2747     open(FILE,"$dir/CVS/Root") || die "$dir isn't CVS controlled";
    2748     $res = <FILE>;
    2749     chomp($res);
    2750     close(FILE);
    2751     # Find where we are in the tree
    2752     my $rdir = $dir;
    2753     while ((! -d "$rdir/CVSROOT") && ($rdir ne "/")) {
    2754         $rdir = dirname($rdir);
    2755     }
    2756     die "Unable to find a CVSROOT dir in the parents of $dir" if (! -d "$rdir/CVSROOT");
    2757     #compute our place under that root dir - should be a relative path
    2758     $dir =~ s|^$rdir||;
    2759     my $suffix = "";
    2760     $suffix = "$dir" if ($dir ne "");
    2761 
    2762     my $prefix = "";
    2763     if ($scheme =~ /ssh/) {
    2764         $prefix = "cvs+ssh://";
    2765     } else {
    2766         $prefix = "cvs://";
    2767     }
    2768     $res = $prefix.$res.$suffix;
    2769 } else {
    2770     die "cms $scheme unknown";
    2771 }
    2772 pb_log(2,"Found CMS info: $res\n");
    2773 return($res);
    2774 }
    2775 
    2776 sub pb_cms_copy {
    2777 my $scheme = shift;
    2778 my $oldurl = shift;
    2779 my $newurl = shift;
    2780 
    2781 if ($scheme =~ /^svn/) {
    2782     pb_system("svn copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
    2783 } elsif ($scheme eq "flat") {
    2784 } elsif ($scheme =~ /^cvs/) {
    2785 } else {
    2786     die "cms $scheme unknown";
    2787 }
    2788 }
    2789 
    2790 sub pb_cms_checkout {
    2791 my $scheme = shift;
    2792 my $url = shift;
    2793 my $destination = shift;
    2794 
    2795 if ($scheme =~ /^svn/) {
    2796     pb_system("svn co $url $destination","Checking out $url to $destination ");
    2797 } elsif (($scheme eq "ftp") || ($scheme eq "http")) {
    2798     return;
    2799 } elsif ($scheme =~ /^cvs/) {
    2800     pb_system("cvs co $url $destination","Checking out $url to $destination ");
    2801 } else {
    2802     die "cms $scheme unknown";
    2803 }
    2804 }
    2805 
    2806 sub pb_cms_up {
    2807 my $scheme = shift;
    2808 my $dir = shift;
    2809 
    2810 if ($scheme =~ /^svn/) {
    2811     pb_system("svn up $dir","Updating $dir");
    2812 } elsif ($scheme eq "flat") {
    2813 } elsif ($scheme =~ /^cvs/) {
    2814 } else {
    2815     die "cms $scheme unknown";
    2816 }
    2817 }
    2818 
    2819 sub pb_cms_checkin {
    2820 my $scheme = shift;
    2821 my $dir = shift;
    2822 
    2823 my $ver = basename($dir);
    2824 if ($scheme =~ /^svn/) {
    2825     pb_system("svn ci -m \"updated to $ver\" $dir","Checking in $dir");
    2826 } elsif ($scheme eq "flat") {
    2827 } elsif ($scheme =~ /^cvs/) {
    2828 } else {
    2829     die "cms $scheme unknown";
    2830 }
    2831 pb_cms_up($scheme,$dir);
    2832 }
    2833 
    2834 sub pb_cms_isdiff {
    2835 my $scheme = shift;
    2836 my $dir =shift;
    2837 
    2838 if ($scheme =~ /^svn/) {
    2839     open(PIPE,"svn diff $dir |") || die "Unable to get svn diff from $dir";
    2840     my $l = 0;
    2841     while (<PIPE>) {
    2842         $l++;
    2843     }
    2844     return($l);
    2845 } elsif ($scheme eq "flat") {
    2846 } elsif ($scheme =~ /^cvs/) {
    2847     open(PIPE,"cvs diff $dir |") || die "Unable to get svn diff from $dir";
    2848     my $l = 0;
    2849     while (<PIPE>) {
    2850         # Skipping normal messages
    2851         next if (/^cvs diff:/);
    2852         $l++;
    2853     }
    2854     return($l);
    2855 } else {
    2856     die "cms $scheme unknown";
    2857 }
    2858 }
    2859 
    2860 # Get all filters to apply
    2861 # They're cumulative from less specific to most specific
    2862 # suffix is .pbf
    2863 
    2864 sub pb_get_filters {
    2865 
    2866 my @ffiles;
    2867 my ($ffile00, $ffile0, $ffile1, $ffile2, $ffile3);
    2868 my ($mfile00, $mfile0, $mfile1, $mfile2, $mfile3);
    2869 my $pbpkg = shift || die "No package specified";
    2870 my $dtype = shift || "";
    2871 my $dfam = shift || "";
    2872 my $ddir = shift || "";
    2873 my $dver = shift || "";
    2874 my $ptr = undef; # returned value pointer on the hash of filters
    2875 my %h;
    2876 
    2877 # Global filter files first, then package specificities
    2878 if (-d "$ENV{'PBROOTDIR'}/pbfilter") {
    2879     $mfile00 = "$ENV{'PBROOTDIR'}/pbfilter/all.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/all.pbf");
    2880     $mfile0 = "$ENV{'PBROOTDIR'}/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$dtype.pbf");
    2881     $mfile1 = "$ENV{'PBROOTDIR'}/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$dfam.pbf");
    2882     $mfile2 = "$ENV{'PBROOTDIR'}/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$ddir.pbf");
    2883     $mfile3 = "$ENV{'PBROOTDIR'}/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$ddir-$dver.pbf");
    2884 
    2885     push @ffiles,$mfile00 if (defined $mfile00);
    2886     push @ffiles,$mfile0 if (defined $mfile0);
    2887     push @ffiles,$mfile1 if (defined $mfile1);
    2888     push @ffiles,$mfile2 if (defined $mfile2);
    2889     push @ffiles,$mfile3 if (defined $mfile3);
    2890 }
    2891 
    2892 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter") {
    2893     $ffile00 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/all.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/all.pbf");
    2894     $ffile0 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dtype.pbf");
    2895     $ffile1 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dfam.pbf");
    2896     $ffile2 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir.pbf");
    2897     $ffile3 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir-$dver.pbf");
    2898 
    2899     push @ffiles,$ffile00 if (defined $ffile00);
    2900     push @ffiles,$ffile0 if (defined $ffile0);
    2901     push @ffiles,$ffile1 if (defined $ffile1);
    2902     push @ffiles,$ffile2 if (defined $ffile2);
    2903     push @ffiles,$ffile3 if (defined $ffile3);
    2904 }
    2905 if (@ffiles) {
    2906     pb_log(2,"DEBUG ffiles: ".Dumper(\@ffiles)."\n");
    2907 
    2908     foreach my $f (@ffiles) {
    2909         open(CONF,$f) || next;
    2910         while(<CONF>)  {
    2911             if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
    2912                 $h{$1}{$2}=$3;
    2913             }
    2914         }
    2915         close(CONF);
    2916 
    2917         $ptr = $h{"filter"};
    2918         pb_log(2,"DEBUG f:".Dumper($ptr)."\n");
    2919     }
    2920 }
    2921 return($ptr);
    2922 }
    2923 
    2924 # Function which applies filter on pb build files
    2925 sub pb_filter_file_pb {
    2926 
    2927 my $f=shift;
    2928 my $ptr=shift;
    2929 my %filter=%$ptr;
    2930 my $destfile=shift;
    2931 my $dtype=shift;
    2932 my $pbsuf=shift;
    2933 my $pbproj=shift;
    2934 my $pbpkg=shift;
    2935 my $pbver=shift;
    2936 my $pbtag=shift;
    2937 my $pbrev=shift;
    2938 my $pbdate=shift;
    2939 my $defpkgdir = shift;
    2940 my $extpkgdir = shift;
    2941 my $pbpackager = shift;
    2942 my $chglog = shift || undef;
    2943 
    2944 pb_log(2,"DEBUG: From $f to $destfile\n");
    2945 pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
    2946 open(DEST,"> $destfile") || die "Unable to create $destfile";
    2947 open(FILE,"$f") || die "Unable to open $f: $!";
    2948 while (<FILE>) {
    2949     my $line = $_;
    2950     foreach my $s (keys %filter) {
    2951         # Process single variables
    2952         pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
    2953         my $tmp = $filter{$s};
    2954         next if (not defined $tmp);
    2955         # Expand variables if any single one found
    2956         pb_log(2,"DEBUG tmp: $tmp\n");
    2957         if ($tmp =~ /\$/) {
    2958             eval { $tmp =~ s/(\$\w+)/$1/eeg };
    2959         # special case for ChangeLog only for pb
    2960         } elsif (($s =~ /^PBLOG$/) && ($line =~ /^PBLOG$/)) {
    2961             my $p = $defpkgdir->{$pbpkg};
    2962             $p = $extpkgdir->{$pbpkg} if (not defined $p);
    2963             pb_changelog($dtype, $pbpkg, $pbver, $pbtag, $pbsuf, $p, \*DEST, $tmp, $chglog);
    2964             $tmp = "";
    2965         }
    2966         $line =~ s|$s|$tmp|;
    2967     }
    2968     print DEST $line;
    2969 }
    2970 close(FILE);
    2971 close(DEST);
    2972 }
    2973 
    2974 # Function which applies filter on files (external call)
    2975 sub pb_filter_file_inplace {
    2976 
    2977 my $ptr=shift;
    2978 my %filter=%$ptr;
    2979 my $destfile=shift;
    2980 my $pbproj=shift;
    2981 my $pbpkg=shift;
    2982 my $pbver=shift;
    2983 my $pbtag=shift;
    2984 my $pbrev=shift;
    2985 my $pbdate=shift;
    2986 my $pbpackager=shift;
    2987 
    2988 my $cp = "$ENV{'PBTMP'}/".basename($destfile);
    2989 copy($destfile,$cp) || die "Unable to create $cp";
    2990 
    2991 pb_filter_file($cp,$ptr,$destfile,$pbproj,$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$pbpackager);
    2992 unlink $cp;
    2993 }
    2994 
    2995 # Function which applies filter on files (external call)
    2996 sub pb_filter_file {
    2997 
    2998 my $f=shift;
    2999 my $ptr=shift;
    3000 my %filter=%$ptr;
    3001 my $destfile=shift;
    3002 my $pbproj=shift;
    3003 my $pbpkg=shift;
    3004 my $pbver=shift;
    3005 my $pbtag=shift;
    3006 my $pbrev=shift;
    3007 my $pbdate=shift;
    3008 my $pbpackager=shift;
    3009 
    3010 pb_log(2,"DEBUG: From $f to $destfile\n");
    3011 pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
    3012 open(DEST,"> $destfile") || die "Unable to create $destfile";
    3013 open(FILE,"$f") || die "Unable to open $f: $!";
    3014 while (<FILE>) {
    3015     my $line = $_;
    3016     foreach my $s (keys %filter) {
    3017         # Process single variables
    3018         pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
    3019         my $tmp = $filter{$s};
    3020         next if (not defined $tmp);
    3021         # Expand variables if any single one found
    3022         if ($tmp =~ /\$/) {
    3023             eval { $tmp =~ s/(\$\w+)/$1/eeg };
    3024         }
    3025         $line =~ s|$s|$tmp|;
    3026     }
    3027     print DEST $line;
    3028 }
    3029 close(FILE);
    3030 close(DEST);
    3031 }
    3032 
    30332431#
    3034 # Return the list of packages we are working on in a CMS action
    3035 #
    3036 sub pb_cms_get_pkg {
     2432# Return the list of packages we are working on in a non CMS action
     2433#
     2434sub pb_get_pkg {
    30372435
    30382436my @pkgs = ();
    3039 my $defpkgdir = shift || undef;
    3040 my $extpkgdir = shift || undef;
    3041 
    3042 # Get packages list
    3043 if (not defined $ARGV[0]) {
    3044     @pkgs = keys %$defpkgdir if (defined $defpkgdir);
    3045 } elsif ($ARGV[0] =~ /^all$/) {
    3046     @pkgs = keys %$defpkgdir if (defined $defpkgdir);
    3047     push(@pkgs, keys %$extpkgdir) if (defined $extpkgdir);
    3048 } else {
    3049     @pkgs = @ARGV;
    3050 }
     2437
     2438my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
     2439@pkgs = keys %$var;
     2440
    30512441pb_log(0,"Packages: ".join(',',@pkgs)."\n");
    30522442return(\@pkgs);
    30532443}
    30542444
    3055 #
    3056 # Return the list of packages we are working on in a non CMS action
    3057 #
    3058 sub pb_get_pkg {
    3059 
    3060 my @pkgs = ();
    3061 
    3062 my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
    3063 @pkgs = keys %$var;
    3064 
    3065 pb_log(0,"Packages: ".join(',',@pkgs)."\n");
    3066 return(\@pkgs);
    3067 }
    3068 
    3069 #
    3070 # Check pbconf/project cms compliance
    3071 #
    3072 sub pb_cms_compliant {
    3073 
    3074 my $param = shift;
    3075 my $envar = shift;
    3076 my $defdir = shift;
    3077 my $uri = shift;
    3078 my $pbinit = shift;
    3079 my %pdir;
    3080 
    3081 my ($pdir) = pb_conf_get_if($param) if (defined $param);
    3082 if (defined $pdir) {
    3083     %pdir = %$pdir;
    3084 }
    3085 
    3086 
    3087 if ((defined $pdir) && (%pdir) && (defined $pdir{$ENV{'PBPROJ'}})) {
    3088     # That's always the environment variable that will be used
    3089     $ENV{$envar} = $pdir{$ENV{'PBPROJ'}};
    3090 } else {
    3091     if (defined $param) {
    3092         pb_log(1,"WARNING: no $param defined, using $defdir\n");
    3093         pb_log(1,"         Please create a $param reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
    3094         pb_log(1,"         if you want to use another directory\n");
    3095     }
    3096     $ENV{$envar} = "$defdir";
    3097 }
    3098 
    3099 # Expand potential env variable in it
    3100 eval { $ENV{$envar} =~ s/(\$ENV.+\})/$1/eeg };
    3101 pb_log(2,"$envar: $ENV{$envar}\n");
    3102 
    3103 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
    3104 
    3105 if ((! -d "$ENV{$envar}") || (defined $pbinit)) {
    3106     if (defined $pbinit) {
    3107         pb_mkdir_p("$ENV{$envar}");
    3108     } else {
    3109         pb_log(1,"Checking out $uri\n");
    3110         pb_cms_checkout($scheme,$uri,$ENV{$envar});
    3111     }
    3112 } elsif (($scheme !~ /^cvs/) || ($scheme !~ /^svn/)) {
    3113     # Do not compare if it's not a real cms
    3114     return;
    3115 } else {
    3116     pb_log(1,"$uri found locally, checking content\n");
    3117     my $cmsurl = pb_cms_get_uri($scheme,$ENV{$envar});
    3118     my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
    3119     if ($cmsurl ne $uri) {
    3120         # The local content doesn't correpond to the repository
    3121         pb_log(0,"ERROR: Inconsistency detected:\n");
    3122         pb_log(0,"       * $ENV{$envar} refers to $cmsurl but\n");
    3123         pb_log(0,"       * $ENV{'PBETC'} refers to $uri\n");
    3124         die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
    3125     } else {
    3126         pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
    3127         # they match - do nothing - there may be local changes
    3128     }
    3129 }
    3130 }
    3131 
    3132 sub pb_changelog {
    3133 
    3134 my $dtype = shift;
    3135 my $pkg = shift;
    3136 my $pbver = shift;
    3137 my $pbtag = shift;
    3138 my $dsuf = shift;
    3139 my $path = shift;
    3140 my $OUTPUT = shift;
    3141 my $doit = shift;
    3142 my $chglog = shift || undef;
    3143 
    3144 my $log = "";
    3145 
    3146 # For date handling
    3147 $ENV{LANG}="C";
    3148 
    3149 if ((not (defined $dtype)) || ($dtype eq "") ||
    3150         (not (defined $pkg)) || ($pkg eq "") ||
    3151         (not (defined $pbver)) || ($pbver eq "") ||
    3152         (not (defined $pbtag)) || ($pbtag eq "") ||
    3153         (not (defined $dsuf)) || ($dsuf eq "") ||
    3154         (not (defined $path)) || ($path eq "") ||
    3155         (not (defined $OUTPUT)) || ($OUTPUT eq "") ||
    3156         (not (defined $doit)) || ($doit eq "")) {
    3157     print $OUTPUT "\n";
    3158     return;
    3159 }
    3160 
    3161 if (((not defined $chglog) || (! -f $chglog)) && ($doit eq "yes")) {
    3162     #pb_log(2,"No ChangeLog file ($chglog) for $pkg\n";
    3163     print $OUTPUT "\n";
    3164     return;
    3165 }
    3166 
    3167 my $date;
    3168 my $ndate;
    3169 my $n2date;
    3170 my $ver;
    3171 my $ver2;
    3172 my ($pbpackager) = pb_conf_get("pbpackager");
    3173 
    3174 if (not defined $pbpackager->{$ENV{'PBPROJ'}}) {
    3175     $pbpackager->{$ENV{'PBPROJ'}} = "undefined\@noproject.noorg";
    3176 }
    3177 
    3178 # If we don't need to do it, or don't have it fake something
    3179 if (((not defined $chglog) || (! -f $chglog)) && ($doit ne "yes")) {
    3180     my @date = pb_get_date();
    3181     $date = strftime("%Y-%m-%d", @date);
    3182     $ndate = UnixDate($date,"%a", "%b", "%d", "%Y");
    3183     $n2date = &UnixDate($date,"%a, %d %b %Y %H:%M:%S %z");
    3184     if (($dtype eq "rpm") || ($dtype eq "fc")) {
    3185         $ver2 = "$pbver-$pbtag$dsuf";
    3186         print $OUTPUT "* $ndate $pbpackager->{$ENV{'PBPROJ'}} $ver2\n";
    3187         print $OUTPUT "- Updated to $pbver\n";
    3188         }
    3189     if ($dtype eq "deb") {
    3190         print $OUTPUT "$pkg ($pbver) unstable; urgency=low\n";
    3191         print $OUTPUT "\n";
    3192         print $OUTPUT " -- $pbpackager->{$ENV{'PBPROJ'}}  $n2date\n\n\n";
    3193         }
    3194     return;
    3195 }
    3196 
    3197 open(INPUT,"$chglog") || die "Unable to open $chglog (read)";
    3198 
    3199 # Skip first 4 lines
    3200 my $tmp = <INPUT>;
    3201 $tmp = <INPUT>;
    3202 $tmp = <INPUT>;
    3203 if ($dtype eq "announce") {
    3204     print $OUTPUT $tmp;
    3205 }
    3206 $tmp = <INPUT>;
    3207 if ($dtype eq "announce") {
    3208     print $OUTPUT $tmp;
    3209 }
    3210 
    3211 my $first=1;
    3212 
    3213 # Handle each block separated by newline
    3214 while (<INPUT>) {
    3215     ($ver, $date) = split(/ /);
    3216     $ver =~ s/^v//;
    3217     chomp($date);
    3218     $date =~ s/\(([0-9-]+)\)/$1/;
    3219     #pb_log(2,"**$date**\n";
    3220     $ndate = UnixDate($date,"%a", "%b", "%d", "%Y");
    3221     $n2date = &UnixDate($date,"%a, %d %b %Y %H:%M:%S %z");
    3222     #pb_log(2,"**$ndate**\n";
    3223 
    3224     if (($dtype eq "rpm") || ($dtype eq "fc")) {
    3225         if ($ver !~ /-/) {
    3226             if ($first eq 1) {
    3227                 $ver2 = "$ver-$pbtag$dsuf";
    3228                 $first=0;
    3229             } else {
    3230                 $ver2 = "$ver-1$dsuf";
    3231             }
    3232         } else {
    3233             $ver2 = "$ver$dsuf";
    3234         }
    3235         print $OUTPUT "* $ndate $pbpackager->{$ENV{'PBPROJ'}} $ver2\n";
    3236         print $OUTPUT "- Updated to $ver\n";
    3237         }
    3238     if ($dtype eq "deb") {
    3239         print $OUTPUT "$pkg ($ver) unstable; urgency=low\n";
    3240         print $OUTPUT "\n";
    3241         }
    3242 
    3243     $tmp = <INPUT>;
    3244     while ($tmp !~ /^$/) {
    3245         if ($dtype eq "deb") {
    3246             $tmp =~ s/^- //;
    3247             print $OUTPUT "  * $tmp";
    3248         } elsif ($dtype eq "rpm") {
    3249             print $OUTPUT "$tmp";
    3250         } else {
    3251             print $OUTPUT "$tmp";
    3252         }
    3253         last if (eof(INPUT));
    3254         $tmp = <INPUT>;
    3255     }
    3256     print $OUTPUT "\n";
    3257 
    3258     if ($dtype eq "deb") {
    3259         # Cf: http://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog
    3260         print $OUTPUT " -- $pbpackager->{$ENV{'PBPROJ'}}  $n2date\n\n\n";
    3261         }
    3262 
    3263     last if (eof(INPUT));
    3264     last if ($dtype eq "announce");
    3265 }
    3266 close(INPUT);
    3267 }
    326824451;
  • devel/pb/lib/ProjectBuilder/CMS.pm

    r404 r405  
    11#!/usr/bin/perl -w
    22#
    3 # Project Builder main application
     3# Project Builder CMS module
     4# CMS subroutines brought by the the Project-Builder project
     5# which can be easily used by pbinit scripts
    46#
    57# $Id$
     
    810# Provided under the GPL v2
    911
    10 # Syntax: see at end
     12package ProjectBuilder::CMS;
    1113
    1214use strict 'vars';
    13 use Getopt::Long qw(:config auto_abbrev no_ignore_case);
    1415use Data::Dumper;
    1516use English;
    1617use File::Basename;
    17 use File::Copy;
    18 use File::stat;
    19 use File::Temp qw(tempdir);
    20 use Date::Manip;
    2118use POSIX qw(strftime);
    2219use lib qw (lib);
    23 use ProjectBuilder::Distribution;
    24 use ProjectBuilder::Version;
    2520use ProjectBuilder::Base;
    26 
    27 # Global variables
    28 my %opts;                   # CLI Options
    29 my $action;                 # action to realize
    30 my $test = "FALSE";         # Not used
    31 my $force = 0;              # Force VE/VM rebuild
    32 my $option = "";            # Not used
    33 my @pkgs;                   # list of packages
    34 my $pbtag;                  # Global Tag variable
    35 my $pbver;                  # Global Version variable
    36 my $pbscript;               # Name of the script
    37 my %pbver;                  # per package
    38 my %pbtag;                  # per package
    39 my $pbrev;                  # Global REVISION variable
    40 my $pbaccount;              # Login to use to connect to the VM
    41 my $pbport;                 # Port to use to connect to the VM
    42 my $newver;                 # New version to create
    43 my $iso;                    # ISO image for the VM to create
    44 
    45 my @date = pb_get_date();
    46 my $pbdate = strftime("%Y-%m-%d", @date);
     21use ProjectBuilder::Conf;
     22
     23# Inherit from the "Exporter" module which handles exporting functions.
     24 
     25use Exporter;
     26 
     27# Export, by default, all the functions into the namespace of
     28# any code which uses this module.
     29 
     30our @ISA = qw(Exporter);
     31our @EXPORT = qw(pb_cms_init pb_cms_export pb_cms_get_uri pb_cms_copy pb_cms_checkout pb_cms_up pb_cms_checkin pb_cms_isdiff pb_cms_get_pkg pb_cms_compliant pb_cms_log pb_cms_create_authors);
    4732
    4833=pod
     
    5035=head1 NAME
    5136
    52 pb, aka project-builder.org - builds packages for your projects
     37ProjectBuilder::CMS, part of the project-builder.org - module dealing with configuration management system functions suitable for pbinit calls.
    5338
    5439=head1 DESCRIPTION
    5540
    56 pb helps you build various packages directly from your project sources.
    57 Those sources could be handled by a CMS (Configuration Management System)
    58 such as Subversion, CVS, ... or being a simple reference to a compressed tar file.
    59 It's based on a set of configuration files, a set of provided macros to help
    60 you keeping build files as generic as possible. For example, a single .spec
    61 file should be required to generate for all rpm based distributions, even
    62 if you could also have multiple .spec files if required.
    63 
    64 =head1 SYNOPSIS
    65 
    66 pb [-vhq][-r pbroot][-p project][[-s script -a account -P port][-m mach-1[,...]]][-i iso] <action> [<pkg1> ...]
    67 
    68 pb [--verbose][--help][--man][--quiet][--revision pbroot][--project project][[--script script --account account --port port][--machine mach-1[,...]]][--iso iso] <action> [<pkg1> ...]
    69 
    70 =head1 OPTIONS
    71 
    72 =over 4
    73 
    74 =item B<-v|--verbose>
    75 
    76 Print a brief help message and exits.
    77 
    78 =item B<-q|--quiet>
    79 
    80 Do not print any output.
    81 
    82 =item B<-h|--help>
    83 
    84 Print a brief help message and exits.
    85 
    86 =item B<--man>
    87 
    88 Prints the manual page and exits.
    89 
    90 =item B<-m|--machine machine1[,machine2,...]>
    91 
    92 Name of the Virtual Machines (VM) or Virtual Environments (VE) you want to build on (coma separated).
    93 All if none precised (or use the env variable PBV).
    94 
    95 =item B<-s|--script script>
    96 
    97 Name of the script you want to execute on the related VMs or VEs.
    98 
    99 =item B<-i|--iso iso_image>
    100 
    101 Name of the ISO image of the distribution you want to install on the related VMs.
    102 
    103 =item B<-a|--account account>
    104 
    105 Name of the account to use to connect on the related VMs.
    106 
    107 =item B<-P|--port port_number>
    108 
    109 Port number to use to connect on the related VMs.\n";
    110 
    111 =item B<-p|--project project_name>
    112 
    113 Name of the project you're working on (or use the env variable PBPROJ)
    114 
    115 =item B<-r|--revision revision>
    116 
    117 Path Name of the project revision under the CMS (or use the env variable PBROOT)
    118 
    119 =item B<-V|--version new_version>
    120 
    121 New version of the project to create based on the current one.
    122 
    123 =back
    124 
    125 =head1 ARGUMENTS
    126 
    127 <action> can be:
    128 
    129 =over 4
    130 
    131 =item B<cms2build>
    132 
    133 Create tar files for the project under your CMS.
    134 CMS supported are SVN and CVS
    135 parameters are packages to build
    136 if not using default list
    137 
    138 =item B<build2pkg>
    139 
    140 Create packages for your running distribution
    141 
    142 =item B<cms2pkg>
    143 
    144 cms2build + build2pkg
    145 
    146 =item B<build2ssh>
    147 
    148 Send the tar files to a SSH host
    149 
    150 =item B<cms2ssh>
    151 
    152 cms2build + build2ssh
    153 
    154 =item B<pkg2ssh>
    155 
    156 Send the packages built to a SSH host
    157 
    158 =item B<build2vm>
    159 
    160 Create packages in VMs, launching them if needed
    161 and send those packages to a SSH host once built
    162 VM type supported are QEMU
    163 
    164 =item B<build2ve>
    165 
    166 Create packages in VEs, creating it if needed
    167 and send those packages to a SSH host once built
    168 
    169 =item B<cms2vm>
    170 
    171 cms2build + build2vm
    172 
    173 =item B<cms2ve>
    174 
    175 cms2build + build2ve
    176 
    177 =item B<launchvm>
    178 
    179 Launch one virtual machine
    180 
    181 =item B<launchve>
    182 
    183 Launch one virtual environment
    184 
    185 =item B<script2vm>
    186 
    187 Launch one virtual machine if needed
    188 and executes a script on it
    189 
    190 =item B<script2ve>
    191 
    192 Execute a script in a virtual environment
    193 
    194 =item B<newvm>
    195 
    196 Create a new virtual machine
    197 
    198 =item B<newve>
    199 
    200 Create a new virtual environment
    201 
    202 =item B<setupvm>
    203 
    204 Setup a virtual machine for pb usage
    205 
    206 =item B<setupve>
    207 
    208 Setup a virtual environment for pb usage
    209 
    210 =item B<newver>
    211 
    212 Create a new version of the project derived
    213 from the current one
    214 
    215 =item B<newproj>
    216 
    217 Create a new project and a template set of
    218 configuration files under pbconf
    219 
    220 =back
    221 
    222 <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).
    223 
    224 =head1 WEB SITES
    225 
    226 The 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/>.
    227 
    228 =head1 USER MAILING LIST
    229 
    230 None exists for the moment.
    231 
    232 =head1 CONFIGURATION FILES
    233 
    234 Each pb user may have a configuration in F<$HOME/.pbrc>. The values in this file may overwrite any other configuration file value.
    235 
    236 Here is an example of such a configuration file:
    237 
    238  #
    239  # Define for each project the URL of its pbconf repository
    240  # No default option allowed here as they need to be all different
    241  #
    242  # URL of the pbconf content
    243  # This is the format of a classical URL with the extension of additional schema such as
    244  # svn+ssh, cvs+ssh, ...
    245  #
    246  pbconfurl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe/pbconf
    247 
    248  # This is normaly defined in the project's configuration file
    249  # Url of the project
    250  #
    251  pburl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe
    252  
    253  # All these URLs needs to be defined here as the are the entry point
    254  # for how to build packages for the project
    255  #
    256  pbconfurl pb = svn+ssh://svn.project-builder.org/mondo/svn/pb/pbconf
    257  pbconfurl mondorescue = svn+ssh://svn.project-builder.org/mondo/svn/project-builder/mondorescue/pbconf
    258  pbconfurl collectl = svn+ssh://bruno@svn.mondorescue.org/mondo/svn/project-builder/collectl/pbconf
    259  pbconfurl netperf = svn+ssh://svn.mondorescue.org/mondo/svn/project-builder/netperf/pbconf
    260  
    261  # Under that dir will take place everything related to pb
    262  # If you want to use VMs/chroot/..., then use $ENV{'HOME'} to make it portable
    263  # to your VMs/chroot/...
    264  # if not defined then /var/cache
    265  pbdefdir default = $ENV{'HOME'}/project-builder
    266  pbdefdir pb = $ENV{'HOME'}
    267  pbdefdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
    268  pbdefdir mondorescue = $ENV{'HOME'}/mondo/svn
    269  
    270  # pbconfdir points to the directory where the CMS content of the pbconfurl is checked out
    271  # If not defined, pbconfdir is under pbdefdir/pbproj/pbconf
    272  pbconfdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs/pbconf
    273  pbconfdir mondorescue = $ENV{'HOME'}/mondo/svn/pbconf
    274  
    275  # pbdir points to the directory where the CMS content of the pburl is checked out
    276  # If not defined, pbdir is under pbdefdir/pbproj
    277  # Only defined if we have access to the dev of the project
    278  pbdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
    279  pbdir mondorescue = $ENV{'HOME'}/mondo/svn
    280  
    281  # -daemonize doesn't work with qemu 0.8.2
    282  vmopt default = -m 384
    283 
    284 =head1 AUTHORS
    285 
    286 The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
    287 
    288 =head1 COPYRIGHT
    289 
    290 Project-Builder.org is distributed under the GPL v2.0 license
    291 described in the file C<COPYING> included with the distribution.
     41This modules provides configuration management system functions suitable for pbinit calls.
    29242
    29343=cut
    294 
    295 # ---------------------------------------------------------------------------
    296 
    297 # Old syntax
    298 #getopts('a:fhi:l:m:P:p:qr:s:vV:',\%opts);
    299 
    300 my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
    301 
    302 # Initialize the syntax string
    303 
    304 pb_syntax_init("pb (aka project-builder.org) Version $projectbuilderver-$projectbuilderrev\n");
    305 
    306 GetOptions("help|?|h" => \$opts{'h'},
    307         "man" => \$opts{'man'},
    308         "verbose|v+" => \$opts{'v'},
    309         "quiet|q" => \$opts{'q'},
    310         "log-files|l=s" => \$opts{'l'},
    311         "force|f" => \$opts{'f'},
    312         "account|a=s" => \$opts{'a'},
    313         "revision|r=s" => \$opts{'r'},
    314         "script|s=s" => \$opts{'s'},
    315         "machines|mock|m=s" => \$opts{'m'},
    316         "port|P=i" => \$opts{'P'},
    317         "project|p=s" => \$opts{'p'},
    318         "iso|i=s" => \$opts{'i'},
    319         "version|V=s" => \$opts{'V'},
    320 ) || pb_syntax(-1,0);
    321 
    322 if (defined $opts{'h'}) {
    323     pb_syntax(0,1);
    324 }
    325 if (defined $opts{'man'}) {
    326     pb_syntax(0,2);
    327 }
    328 if (defined $opts{'v'}) {
    329     $debug = $opts{'v'};
    330     pb_log(0,"Debug value: $debug\n");
    331 }
    332 if (defined $opts{'f'}) {
    333     $force=1;
    334 }
    335 if (defined $opts{'q'}) {
    336     $debug=-1;
    337 }
    338 if (defined $opts{'l'}) {
    339     open(LOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
    340     $LOG = \*LOG;
    341     $debug = 0  if ($debug == -1);
    342     }
    343 pb_log_init($debug, $LOG);
    344 
    345 # Handle root of the project if defined
    346 if (defined $opts{'r'}) {
    347     $ENV{'PBROOTDIR'} = $opts{'r'};
    348 }
    349 # Handle virtual machines if any
    350 if (defined $opts{'m'}) {
    351     $ENV{'PBV'} = $opts{'m'};
    352 }
    353 if (defined $opts{'s'}) {
    354     $pbscript = $opts{'s'};
    355 }
    356 if (defined $opts{'a'}) {
    357     $pbaccount = $opts{'a'};
    358     die "option -a requires a -s script option" if (not defined $pbscript);
    359 }
    360 if (defined $opts{'P'}) {
    361     $pbport = $opts{'P'};
    362 }
    363 if (defined $opts{'V'}) {
    364     $newver = $opts{'V'};
    365 }
    366 if (defined $opts{'i'}) {
    367     $iso = $opts{'i'};
    368 }
    369 
    370 # Get Action
    371 $action = shift @ARGV;
    372 die pb_syntax(-1,1) if (not defined $action);
    373 
    374 my ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir);
    375 my $pbinit = undef;
    376 $pbinit = 1 if ($action =~ /^newproj$/);
    377 
    378 # Handles project name if any
    379 # And get global params
    380 ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) = pb_env_init($opts{'p'},$pbinit,$action);
    381 
    382 pb_log(0,"Project: $ENV{'PBPROJ'}\n");
    383 pb_log(0,"Action: $action\n");
    384 
    385 # Act depending on action
    386 if ($action =~ /^cms2build$/) {
    387     pb_cms2build();
    388 } elsif ($action =~ /^build2pkg$/) {
    389     pb_build2pkg();
    390 } elsif ($action =~ /^cms2pkg$/) {
    391     pb_cms2build();
    392     pb_build2pkg();
    393 } elsif ($action =~ /^build2ssh$/) {
    394     pb_build2ssh();
    395 } elsif ($action =~ /^cms2ssh$/) {
    396     pb_cms2build();
    397     pb_build2ssh();
    398 } elsif ($action =~ /^pkg2ssh$/) {
    399     pb_pkg2ssh();
    400 } elsif ($action =~ /^build2ve$/) {
    401     pb_build2v("ve");
    402 } elsif ($action =~ /^build2vm$/) {
    403     pb_build2v("vm");
    404 } elsif ($action =~ /^cms2ve$/) {
    405     pb_cms2build();
    406     pb_build2v("ve");
    407 } elsif ($action =~ /^cms2vm$/) {
    408     pb_cms2build();
    409     pb_build2v("vm");
    410 } elsif ($action =~ /^launchvm$/) {
    411     pb_launchv("vm",$ENV{'PBV'},0);
    412 } elsif ($action =~ /^launchve$/) {
    413     pb_launchv("ve",$ENV{'PBV'},0);
    414 } elsif ($action =~ /^script2vm$/) {
    415     pb_script2v($pbscript,"vm");
    416 } elsif ($action =~ /^script2ve$/) {
    417     pb_script2v($pbscript,"ve");
    418 } elsif ($action =~ /^newver$/) {
    419     pb_newver();
    420 } elsif ($action =~ /^newve$/) {
    421     pb_launchv("ve",$ENV{'PBV'},1);
    422 } elsif ($action =~ /^newvm$/) {
    423     pb_launchv("vm",$ENV{'PBV'},1);
    424 } elsif ($action =~ /^setupve$/) {
    425     pb_setup_v("ve");
    426 } elsif ($action =~ /^setupvm$/) {
    427     pb_setup_v("vm");
    428 } elsif ($action =~ /^newproj$/) {
    429     # Nothing to do - already done in pb_env_init
    430 } elsif ($action =~ /^clean$/) {
    431 } else {
    432     pb_log(0,"\'$action\' is not available\n");
    433     pb_syntax(-2,1);
    434 }
    435 
    436 sub pb_cms2build {
    437 
    438     my $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
    439     my @pkgs = @$pkg;
    440     my %pkgs;
    441 
    442     my ($scheme, $uri) = pb_cms_init($pbinit);
    443 
    444     my ($pkgv, $pkgt) = pb_conf_get_if("pkgver","pkgtag");
    445 
    446     # declare packager for filtering
    447     my ($tmp) = pb_conf_get("pbpackager");
    448     $ENV{'PBPACKAGER'} = $tmp->{$ENV{'PBPROJ'}};
    449 
    450     foreach my $pbpkg (@pkgs) {
    451         $ENV{'PBPKG'} = $pbpkg;
    452         if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
    453             $pbver = $pkgv->{$pbpkg};
    454         } else {
    455             $pbver = $ENV{'PBPROJVER'};
    456         }
    457         if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
    458             $pbtag = $pkgt->{$pbpkg};
    459         } else {
    460             $pbtag = $ENV{'PBPROJTAG'};
    461         }
    462 
    463         $pbrev = $ENV{'PBREVISION'};
    464         pb_log(0,"\n");
    465         pb_log(0,"Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n");
    466         die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
    467         # Clean up dest if necessary. The export will recreate it
    468         my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver";
    469         pb_rm_rf($dest) if (-d $dest);
    470 
    471         # Export CMS tree for the concerned package to dest
    472         # And generate some additional files
    473         $OUTPUT_AUTOFLUSH=1;
    474 
    475         # computes in which dir we have to work
    476         my $dir = $defpkgdir->{$pbpkg};
    477         $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
    478         pb_log(2,"def:".Dumper($defpkgdir)." ext: ".Dumper($extpkgdir)." \n");
    479 
    480         # Exporting from CMS
    481         pb_cms_export($uri,"$ENV{'PBDIR'}/$dir",$dest);
    482 
    483         # Get project info on authors and log file
    484         my $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
    485         $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
    486         $chglog = undef if (! -f $chglog);
    487 
    488         my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
    489         $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
    490         $authors = "/dev/null" if (! -f $authors);
    491 
    492         # Extract cms log history and store it
    493         if ((defined $chglog) && (! -f "$dest/NEWS")) {
    494             pb_log(2,"Generating NEWS file from $chglog\n");
    495             copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
    496         }
    497         pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors);
    498 
    499         my %build;
    500 
    501         my @pt;
    502         @pt = pb_conf_get_if("vmlist","velist");
    503         my $tmpl = "";
    504         if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
    505             $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
    506         }
    507         if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
    508             # the 2 lists needs to be grouped with a ',' separated them
    509             if ($tmpl ne "") {
    510                 $tmpl .= ",";
    511             }
    512             $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
    513         }
    514         foreach my $d (split(/,/,$tmpl)) {
    515             my ($name,$ver,$arch) = split(/-/,$d);
    516             chomp($arch);
    517             my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
    518             pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n");
    519             pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
    520 
    521             # Filter build files from the less precise up to the most with overloading
    522             # Filter all files found, keeping the name, and generating in dest
    523 
    524             # Find all build files first relatively to PBROOTDIR
    525             # Find also all specific files referenced in the .pb conf file
    526             my %bfiles = ();
    527             my %pkgfiles = ();
    528             $build{"$ddir-$dver"} = "yes";
    529 
    530             if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dtype") {
    531                 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dtype",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
    532             } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dfam") {
    533                 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
    534             } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir") {
    535                 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
    536             } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver") {
    537                 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
    538             } else {
    539                 $build{"$ddir-$dver"} = "no";
    540                 next;
    541             }
    542             pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
    543 
    544             # Get all filters to apply
    545             my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
    546 
    547             # Apply now all the filters on all the files concerned
    548             # destination dir depends on the type of file
    549             if (defined $ptr) {
    550                 foreach my $f (values %bfiles,values %pkgfiles) {
    551                     pb_filter_file_pb("$ENV{'PBROOTDIR'}/$f",$ptr,"$dest/pbconf/$ddir-$dver/".basename($f),$dtype,$pbsuf,$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$defpkgdir,$extpkgdir,$ENV{'PBPACKAGER'},$chglog);
    552                 }
    553             }
    554         }
    555         my @found;
    556         my @notfound;
    557         foreach my $b (keys %build) {
    558             push @found,$b if ($build{$b} =~ /yes/);
    559             push @notfound,$b if ($build{$b} =~ /no/);
    560         }
    561         pb_log(0,"Build files generated for ".join(',',@found)."\n");
    562         pb_log(0,"No Build files found for ".join(',',@notfound)."\n") if (@notfound);
    563         # Get the generic filter (all.pbf) and
    564         # apply those to the non-build files including those
    565         # generated by pbinit if applicable
    566 
    567         # Get only all.pbf filter
    568         my $ptr = pb_get_filters($pbpkg);
    569 
    570         my $liste ="";
    571         if (defined $filteredfiles->{$pbpkg}) {
    572             foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
    573                 pb_filter_file_inplace($ptr,"$dest/$f",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'});
    574                 $liste = "$f $liste";
    575             }
    576         }
    577         pb_log(2,"Files ".$liste."have been filtered\n");
    578 
    579         # Prepare the dest directory for archive
    580         if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
    581             pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'});
    582             chmod 0755,"$ENV{'PBTMP'}/pbinit";
    583             pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit");
    584         }
    585 
    586         # Archive dest dir
    587         chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
    588         # Possibility to look at PBSRC to guess more the filename
    589         pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
    590         pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
    591 
    592         # Keep track of version-tag per pkg
    593         $pkgs{$pbpkg} = "$pbver-$pbtag";
    594 
    595         # Final cleanup
    596         pb_rm_rf($dest) if (-d $dest);
    597     }
    598 
    599     # Keep track of per package version
    600     pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
    601     open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
    602     foreach my $pbpkg (@pkgs) {
    603         print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
    604     }
    605     close(PKG);
    606 
    607     # Keep track of what is generated by default
    608     # We need to store the dir and info on version-tag
    609     # Base our content on the existing .pb file
    610     copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
    611     open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
    612     print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
    613     print LAST "pbprojver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
    614     print LAST "pbprojtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
    615     print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
    616     close(LAST);
    617 }
    618 
    619 sub pb_build2pkg {
    620 
    621     # Get the running distro to build on
    622     my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
    623     pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
    624 
    625     # Get list of packages to build
    626     # Get content saved in cms2build
    627     my $ptr = pb_get_pkg();
    628     @pkgs = @$ptr;
    629 
    630     my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
    631     $pkg = { } if (not defined $pkg);
    632 
    633     chdir "$ENV{'PBBUILDDIR'}";
    634     my $made = ""; # pkgs made during build
    635     foreach my $pbpkg (@pkgs) {
    636         my $vertag = $pkg->{$pbpkg};
    637         # get the version of the current package - maybe different
    638         ($pbver,$pbtag) = split(/-/,$vertag);
    639 
    640         my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
    641         pb_log(2,"Source file: $src\n");
    642 
    643         pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
    644         if ($dtype eq "rpm") {
    645             foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
    646                 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
    647                 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";
    648                 }
    649             }
    650 
    651             # Remove in case a previous link/file was there
    652             unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
    653             symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
    654             # We need to first extract the spec file
    655             my @specfile;
    656             @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
    657 
    658             pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
    659             # set LANGUAGE to check for correct log messages
    660             $ENV{'LANGUAGE'}="C";
    661             foreach my $f (@specfile) {
    662                 if ($f =~ /\.spec$/) {
    663                     pb_system("rpmbuild --define \'packager $ENV{'PBPACKAGER'}\' --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
    664                     last;
    665                 }
    666             }
    667             $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
    668             if (-f "/usr/bin/rpmlint") {
    669                 pb_system("rpmlint $made","Checking validity of rpms with rpmlint");
    670             }
    671         } elsif ($dtype eq "deb") {
    672             chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
    673             pb_system("tar xfz $src","Extracting sources");
    674 
    675             chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
    676             pb_rm_rf("debian");
    677             symlink "pbconf/$ddir-$dver","debian" || die "Unable to symlink to pbconf/$ddir-$dver";
    678             chmod 0755,"debian/rules";
    679             pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package");
    680             $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
    681             if (-f "/usr/bin/lintian") {
    682                 pb_system("lintian $made","Checking validity of debs with lintian");
    683             }
    684         } elsif ($dtype eq "ebuild") {
    685             my @ebuildfile;
    686             # For gentoo we need to take pb as subsystem name
    687             # We put every apps here under sys-apps. hope it's correct
    688             # We use pb's home dir in order o have a single OVERLAY line
    689             my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
    690             pb_mkdir_p($tmpd) if (! -d "$tmpd");
    691             pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
    692 
    693             # We need to first extract the ebuild file
    694             @ebuildfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$tmpd");
    695 
    696             # Prepare the build env for gentoo
    697             my $found = 0;
    698             my $pbbd = $ENV{'HOME'};
    699             $pbbd =~ s|/|\\/|g;
    700             if (-r "/etc/make.conf") {
    701                 open(MAKE,"/etc/make.conf");
    702                 while (<MAKE>) {
    703                     $found = 1 if (/$pbbd\/portage/);
    704                 }
    705                 close(MAKE);
    706             }
    707             if ($found == 0) {
    708                 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
    709             }
    710             #$found = 0;
    711             #if (-r "/etc/portage/package.keywords") {
    712             #open(KEYW,"/etc/portage/package.keywords");
    713             #while (<KEYW>) {
    714             #$found = 1 if (/portage\/pb/);
    715             #}
    716             #close(KEYW);
    717             #}
    718             #if ($found == 0) {
    719             #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
    720             #}
    721 
    722             # Build
    723             foreach my $f (@ebuildfile) {
    724                 if ($f =~ /\.ebuild$/) {
    725                     move($f,"$tmpd/$pbpkg-$pbver.ebuild");
    726                     pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package");
    727                     # Now move it where pb expects it
    728                     pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
    729                     move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
    730                 }
    731             }
    732 
    733             $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver.ebuild";
    734         } elsif ($dtype eq "slackware") {
    735             $made="$made build-$pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
    736             pb_mkdir_p("$ENV{'PBBUILDDIR'}/install") if (! -d "$ENV{'PBBUILDDIR'}/install");
    737         } else {
    738             die "Unknown dtype format $dtype";
    739         }
    740     }
    741     # Keep track of what is generated so that we can get them back from VMs
    742     open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
    743     print KEEP "$made\n";
    744     close(KEEP);
    745 }
    746 
    747 sub pb_build2ssh {
    748     pb_send2target("Sources");
    749 }
    750 
    751 sub pb_pkg2ssh {
    752     pb_send2target("Packages");
    753 }
    754 
    755 # By default deliver to the the public site hosting the
    756 # ftp structure (or whatever) or a VM/VE
    757 sub pb_send2target {
    758 
    759     my $cmt = shift;
    760     my $v = shift || undef;
    761     my $vmexist = shift || 0;           # 0 is FALSE
    762     my $vmpid = shift || 0;             # 0 is FALSE
    763 
    764     my $host = "sshhost";
    765     my $login = "sshlogin";
    766     my $dir = "sshdir";
    767     my $port = "sshport";
    768     my $tmout = "sshtmout";
    769     my $path = "sshpath";
    770     my $conf = "sshconf";
    771     my $rebuild = "sshrebuild";
    772     if (($cmt eq "vm") || ($cmt eq "Script")) {
    773         $login = "vmlogin";
    774         $dir = "pbdefdir";
    775         $tmout = "vmtmout";
    776         $rebuild = "vmrebuild";
    777         # Specific VM
    778         $host = "vmhost";
    779         $port = "vmport";
    780     } elsif ($cmt eq "ve") {
    781         $login = "velogin";
    782         $dir = "pbdefdir";
    783         $tmout = "vetmout";
    784         # Specific VE
    785         $path = "vepath";
    786         $conf = "veconf";
    787         $rebuild = "verebuild";
    788     }
    789     my $cmd = "";
    790 
    791     my $ptr = pb_get_pkg();
    792     @pkgs = @$ptr;
    793 
    794     # Get the running distro to consider
    795     my ($odir,$over,$oarch) = (undef, undef, undef);
    796     if (defined $v) {
    797         ($odir,$over,$oarch) = split(/-/,$v);
    798     }
    799     my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
    800     pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
    801 
    802     # Get list of packages to build
    803     # Get content saved in cms2build
    804     my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
    805     $pkg = { } if (not defined $pkg);
    806 
    807     my $src = "";
    808     chdir "$ENV{'PBBUILDDIR'}";
    809     foreach my $pbpkg (@pkgs) {
    810         my $vertag = $pkg->{$pbpkg};
    811         # get the version of the current package - maybe different
    812         ($pbver,$pbtag) = split(/-/,$vertag);
    813 
    814         if (($cmt eq "Sources") || ($cmt eq "vm") || ($cmt eq "ve")) {
    815             $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
    816             if ($cmd eq "") {
    817                 $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
    818             } else {
    819                 $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
    820             }
    821         }
    822     }
    823     if (($cmt eq "vm") || ($cmt eq "ve")) {
    824         $src="$src $ENV{'PBDESTDIR'}/pbscript $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc";
    825     } elsif ($cmt eq "Script") {
    826         $src="$src $ENV{'PBDESTDIR'}/pbscript";
    827     } elsif ($cmt eq "Packages") {
    828         # Get package list from file made during build2pkg
    829         open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
    830         $src = <KEEP>;
    831         chomp($src);
    832         close(KEEP);
    833         if ($dtype eq "rpm") {
    834             # Also make a pbscript to generate yum/urpmi bases
    835             # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
    836         } elsif ($dtype eq "deb") {
    837             # Also make a pbscript to generate apt bases
    838             # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
    839         }
    840     }
    841     # Remove potential leading spaces (cause problem with basename)
    842     $src =~ s/^ *//;
    843     my $basesrc = "";
    844     foreach my $i (split(/ +/,$src)) {
    845         $basesrc .= " ".basename($i);
    846     }
    847 
    848     pb_log(0,"Sources handled ($cmt): $src\n");
    849     pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf))."\n");
    850     my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf) = pb_conf_get($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf);
    851     pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
    852     # Not mandatory
    853     my ($testver) = pb_conf_get_if("testver");
    854 
    855     my $mac;
    856     # Useless for VE
    857     if ($cmt ne "ve") {
    858         $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
    859         # Overwrite account value if passed as parameter
    860         $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
    861         pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
    862     }
    863 
    864     my $tdir;
    865     my $bdir;
    866     if (($cmt eq "Sources") || ($cmt eq "Script")) {
    867         $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
    868     } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
    869         $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
    870         $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
    871         # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
    872         $bdir =~ s|\$ENV.+\}/||;
    873     } elsif ($cmt eq "Packages") {
    874         $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
    875         if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
    876             # This is a test pkg => target dir is under test
    877             $tdir .= "/test";
    878         }
    879     } else {
    880         return;
    881     }
    882 
    883     # Useless for VE
    884     my $nport;
    885     if ($cmt ne "ve") {
    886         $nport = $sshport->{$ENV{'PBPROJ'}};
    887         $nport = "$pbport" if (defined $pbport);
    888     }
    889 
    890     # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
    891     $tdir =~ s|\$ENV.+\}/||;
    892 
    893     my $tm = $vtmout->{$ENV{'PBPROJ'}};
    894 
    895     # ssh communication if not VE
    896     # should use a hash instead...
    897     my ($shcmd,$cpcmd,$cptarget,$cp2target);
    898     if ($cmt ne "ve") {
    899         my $keyfile = pb_ssh_get(0);
    900         $shcmd = "ssh -i $keyfile -q -p $nport $mac";
    901         $cpcmd = "scp -i $keyfile -p -P $nport";
    902         $cptarget = "$mac:$tdir";
    903         if ($cmt eq "vm") {
    904             $cp2target = "$mac:$bdir";
    905         }
    906     } else {
    907         my $tp = $vepath->{$ENV{'PBPROJ'}};
    908         $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
    909         $cpcmd = "cp -a ";
    910         $cptarget = "$tp/$tdir";
    911         $cp2target = "$tp/$bdir";
    912     }
    913 
    914     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");
    915     pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
    916     # For VE we need to change the owner manually - To be tested if needed
    917     #if ($cmt eq "ve") {
    918     #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
    919     #}
    920     pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi\' | bash\"","Executing pbscript on $cptarget if needed");
    921     if (($cmt eq "vm") || ($cmt eq "ve")) {
    922         # Get back info on pkg produced, compute their name and get them from the VM
    923         pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
    924         open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
    925         my $src = <KEEP>;
    926         chomp($src);
    927         close(KEEP);
    928         $src =~ s/^ *//;
    929         pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
    930         # Change pgben to make the next send2target happy
    931         my $made = "";
    932         open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
    933         foreach my $p (split(/ +/,$src)) {
    934             my $j = basename($p);
    935             pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
    936             $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
    937         }
    938         print KEEP "$made\n";
    939         close(KEEP);
    940         pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
    941 
    942         # We want to send them to the ssh account so overwrite what has been done before
    943         undef $pbaccount;
    944         pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
    945         pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
    946         if ((! $vmexist) && ($cmt eq "vm")) {
    947             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)");
    948         }
    949         pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
    950     }
    951 }
    952 
    953 sub pb_script2v {
    954     my $pbscript=shift;
    955     my $vtype=shift;
    956 
    957     # Prepare the script to be executed on the VM
    958     # in $ENV{'PBDESTDIR'}/pbscript
    959     if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
    960         copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
    961         chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
    962     }
    963 
    964     my ($vm,$all) = pb_get_v($vtype);
    965     my ($vmexist,$vmpid) = (undef,undef);
    966 
    967     foreach my $v (@$vm) {
    968         # Launch the VM/VE
    969         if ($vtype eq "vm") {
    970             ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
    971 
    972             # Skip that VM if something went wrong
    973             next if (($vmpid == 0) && ($vmexist ==0));
    974         }
    975 
    976         # Gather all required files to send them to the VM
    977         # and launch the build through pbscript
    978         pb_send2target("Script","$v",$vmexist,$vmpid);
    979 
    980     }
    981 }
    982 
    983 sub pb_launchv {
    984     my $vtype = shift;
    985     my $v = shift;
    986     my $create = shift || 0;        # By default do not create a VM
    987 
    988     die "No VM/VE defined, unable to launch" if (not defined $v);
    989     # Keep only the first VM in case many were given
    990     $v =~ s/,.*//;
    991 
    992     # Which is our local arch ? (standardize on i386 for those platforms)
    993     my $arch = `uname -m`;
    994     chomp($arch);
    995     $arch =~ s/i.86/i386/;
    996 
    997     # Launch the VMs/VEs
    998     if ($vtype eq "vm") {
    999         die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
    1000 
    1001         my ($ptr,$vmopt,$vmport,$vmpath,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmport","vmpath","vmtmout","vmsize");
    1002 
    1003         my $vmtype = $ptr->{$ENV{'PBPROJ'}};
    1004         if (not defined $ENV{'PBVMOPT'}) {
    1005             $ENV{'PBVMOPT'} = "";
    1006         }
    1007         if (defined $vmopt->{$ENV{'PBPROJ'}}) {
    1008             $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
    1009         }
    1010         my $nport = $vmport->{$ENV{'PBPROJ'}};
    1011         $nport = "$pbport" if (defined $pbport);
    1012    
    1013         my $cmd;
    1014         my $vmcmd;      # has to be used for pb_check_ps
    1015         my $vmm;        # has to be used for pb_check_ps
    1016         if ($vmtype eq "qemu") {
    1017             my $qemucmd32;
    1018             my $qemucmd64;
    1019             if ($arch eq "x86_64") {
    1020                 $qemucmd32 = "/usr/bin/qemu-system-i386";
    1021                 $qemucmd64 = "/usr/bin/qemu";
    1022             } else {
    1023                 $qemucmd32 = "/usr/bin/qemu";
    1024                 $qemucmd64 = "/usr/bin/qemu-system-x86_64";
    1025             }
    1026         if ($v =~ /x86_64/) {
    1027                 $vmcmd = "$qemucmd64 -no-kqemu";
    1028             } else {
    1029                 $vmcmd = "$qemucmd32";
    1030             }
    1031             $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
    1032             if ($create != 0) {
    1033                 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
    1034             }
    1035             $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
    1036         } elsif ($vmtype eq "xen") {
    1037         } elsif ($vmtype eq "vmware") {
    1038         } else {
    1039             die "VM of type $vmtype not supported. Report to the dev team";
    1040         }
    1041         my ($tmpcmd,$void) = split(/ +/,$cmd);
    1042         my $vmexist = pb_check_ps($tmpcmd,$vmm);
    1043         my $vmpid = 0;
    1044         if (! $vmexist) {
    1045             if ($create != 0) {
    1046                 if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
    1047                     pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
    1048                 } elsif ($vmtype eq "vmware") {
    1049                 } else {
    1050                 }
    1051             }
    1052             if (! -f "$vmm") {
    1053                 pb_log(0,"Unable to find VM $vmm\n");
    1054             } else {
    1055                 pb_system("$cmd &","Launching the VM $vmm");
    1056                 pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
    1057                 $vmpid = pb_check_ps($tmpcmd,$vmm);
    1058                 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
    1059             }
    1060         } else {
    1061             pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
    1062         }
    1063         return($vmexist,$vmpid);
    1064     # VE here
    1065     } else {
    1066         # Get VE context
    1067         my ($ptr,$vepath,$vetmout,$verebuild,$veconf) = pb_conf_get("vetype","vepath","vetmout","verebuild","veconf");
    1068         my $vetype = $ptr->{$ENV{'PBPROJ'}};
    1069 
    1070         # Get distro context
    1071         my ($name,$ver,$darch) = split(/-/,$v);
    1072         chomp($darch);
    1073         my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
    1074 
    1075         if ($vetype eq "chroot") {
    1076             # Architecture consistency
    1077             if ($arch ne $darch) {
    1078                 die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
    1079             }
    1080 
    1081             if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
    1082                 # We have to rebuild the chroot
    1083                 if ($dtype eq "rpm") {
    1084                     pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
    1085                     # Once setup we need to install some packages, the pb account, ...
    1086                     pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
    1087                     #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
    1088                 } elsif ($dtype eq "deb") {
    1089                     pb_system("","Creating the pbuilder VE");
    1090                 } elsif ($dtype eq "ebuild") {
    1091                     die "Please teach the dev team how to build gentoo chroot";
    1092                 } else {
    1093                     die "Unknown distribution type $dtype. Report to dev team";
    1094                 }
    1095             }
    1096             # Nothing more to do for VE. No real launch
    1097         } else {
    1098             die "VE of type $vetype not supported. Report to the dev team";
    1099         }
    1100     }
    1101 }
    1102 
    1103 sub pb_build2v {
    1104 
    1105 my $vtype = shift;
    1106 
    1107 # Prepare the script to be executed on the VM/VE
    1108 # in $ENV{'PBDESTDIR'}/pbscript
    1109 #my ($ntp) = pb_conf_get($vtype."ntp");
    1110 #my $vntp = $ntp->{$ENV{'PBPROJ'}};
    1111 
    1112 open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
    1113 print SCRIPT "#!/bin/bash\n";
    1114 print SCRIPT "echo ... Execution needed\n";
    1115 print SCRIPT "# This is in directory delivery\n";
    1116 print SCRIPT "# Setup the variables required for building\n";
    1117 print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
    1118 print SCRIPT "# Preparation for pb\n";
    1119 print SCRIPT "mv .pbrc \$HOME\n";
    1120 print SCRIPT "cd ..\n";
    1121 # Force new date to be in the future compared to the date of the tar file by adding 1 minute
    1122 my @date=pb_get_date();
    1123 $date[1]++;
    1124 my $upddate = strftime("%m%d%H%M%Y", @date);
    1125 #print SCRIPT "echo Setting up date on $vntp...\n";
    1126 # Or use ntpdate if available TBC
    1127 print SCRIPT "sudo date $upddate\n";
    1128 # Get list of packages to build and get some ENV vars as well
    1129 my $ptr = pb_get_pkg();
    1130 @pkgs = @$ptr;
    1131 my $p = join(' ',@pkgs) if (@pkgs);
    1132 print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
    1133 print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
    1134 print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
    1135 print SCRIPT "# Build\n";
    1136 print SCRIPT "echo Building packages on $vtype...\n";
    1137 print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
    1138 close(SCRIPT);
    1139 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
    1140 
    1141 my ($v,$all) = pb_get_v($vtype);
    1142 
    1143 # Send tar files when we do a global generation
    1144 pb_build2ssh() if ($all == 1);
    1145 
    1146 my ($vmexist,$vmpid) = (undef,undef);
    1147 
    1148 foreach my $v (@$v) {
    1149     if ($vtype eq "vm") {
    1150         # Launch the VM
    1151         ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
    1152 
    1153         # Skip that VM if it something went wrong
    1154         next if (($vmpid == 0) && ($vmexist == 0));
    1155     }
    1156     # Gather all required files to send them to the VM/VE
    1157     # and launch the build through pbscript
    1158     pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
    1159     pb_send2target($vtype,"$v",$vmexist,$vmpid);
    1160 }
    1161 }
    1162 
    1163 
    1164 sub pb_newver {
    1165 
    1166     die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
    1167 
    1168     # Need this call for PBDIR
    1169     my ($scheme2,$uri) = pb_cms_init($pbinit);
    1170 
    1171     my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
    1172     $uri = $pbconf->{$ENV{'PBPROJ'}};
    1173     my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
    1174 
    1175     # Checking CMS repositories status
    1176     my ($pburl) = pb_conf_get("pburl");
    1177     ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
    1178 
    1179     if ($scheme !~ /^svn/) {
    1180         die "Only SVN is supported at the moment";
    1181     }
    1182     my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
    1183     die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
    1184 
    1185     $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
    1186     die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
    1187 
    1188     # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
    1189     # we want to get for the root of the new URL
    1190 
    1191     my $tmp = $ENV{'PBROOTDIR'};
    1192     $tmp =~ s|^$ENV{'PBCONFDIR'}||;
    1193 
    1194     my $newurl = "$uri/".dirname($tmp)."/$newver";
    1195     # Should probably use projver in the old file
    1196     my $oldver= basename($tmp);
    1197 
    1198     # Checking pbcl files
    1199     foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
    1200         open(PBCL,$f) || die "Unable to open $f";
    1201         my $foundnew = 0;
    1202         while (<PBCL>) {
    1203             $foundnew = 1 if (/^$newver \(/);
    1204         }
    1205         close(PBCL);
    1206         die "ERROR: version $newver not found in $f" if ($foundnew == 0);
    1207     }
    1208 
    1209     # Duplicate and extract project-builder part
    1210     pb_log(2,"Copying $uri/$tmp to $newurl\n");
    1211     pb_cms_copy($scheme,"$uri/$tmp",$newurl);
    1212     pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
    1213     pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
    1214 
    1215     # Duplicate and extract project
    1216     my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
    1217 
    1218     pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
    1219     pb_cms_copy($scheme,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
    1220     pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
    1221     pb_cms_up($scheme,"$ENV{'PBDIR'}/..");
    1222 
    1223     # Update the .pb file
    1224     open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
    1225     open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
    1226     while(<FILE>) {
    1227         s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
    1228         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/);
    1229         s/^testver/#testver/;
    1230         pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
    1231         print OUT $_;
    1232     }
    1233     close(FILE);
    1234     close(OUT);
    1235     rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
    1236 
    1237     pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
    1238     pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver");
    1239 }
    1240 
    1241 #
    1242 # Return the list of VMs/VEs we are working on
    1243 # $all is a flag to know if we return all of them
    1244 # or only some (if all we publish also tar files in addition to pkgs
    1245 #
    1246 sub pb_get_v {
    1247 
    1248 my $vtype = shift;
    1249 my @v;
    1250 my $all = 0;
    1251 my $vlist;
    1252 my $pbv = 'PBV';
    1253 
    1254 if ($vtype eq "vm") {
    1255     $vlist = "vmlist";
    1256 } elsif ($vtype eq "ve") {
    1257     $vlist = "velist";
    1258 }
    1259 # Get VM/VE list
    1260 if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
    1261     my ($ptr) = pb_conf_get($vlist);
    1262     $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
    1263     $all = 1;
    1264 }
    1265 pb_log(2,"$vtype: $ENV{$pbv}\n");
    1266 @v = split(/,/,$ENV{$pbv});
    1267 return(\@v,$all);
    1268 }
    1269 
    1270 # Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
    1271 # Needs to use root account to connect to the VM/VE
    1272 # pb will take your local public SSH key to access
    1273 # the pb account in the VM later on if needed
    1274 sub pb_setup_v {
    1275 
    1276 my $vtype = shift;
    1277 
    1278 my ($vm,$all) = pb_get_v($vtype);
    1279 
    1280 # Script generated
    1281 my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
    1282 
    1283 foreach my $v (@$vm) {
    1284     # Name of the account to deal with for VM/VE
    1285     # Do not use the one passed potentially with -a
    1286     my ($pbac) = pb_conf_get($vtype."login");
    1287     my ($key,$zero0,$zero1,$zero2);
    1288     my ($vmexist,$vmpid);
    1289 
    1290     if ($vtype eq "vm") {
    1291         # Prepare the key to be used and transfered remotely
    1292         my $keyfile = pb_ssh_get(1);
    1293        
    1294         my ($vmhost,$vmport) = pb_conf_get("vmhost","vmport");
    1295         my $nport = $vmport->{$ENV{'PBPROJ'}};
    1296         $nport = "$pbport" if (defined $pbport);
    1297    
    1298         # Launch the VM
    1299         ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
    1300 
    1301         # Skip that VM if something went wrong
    1302         return if (($vmpid == 0) && ($vmexist == 0));
    1303    
    1304         # Store the pub key part in a variable
    1305         open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
    1306         ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
    1307         close(FILE);
    1308 
    1309         $key = "\Q$zero1";
    1310 
    1311         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");
    1312         # once this is done, we can do what we want on the VM remotely
    1313     }
    1314    
    1315     # Prepare the script to be executed on the VM/VE
    1316     # in $ENV{'PBDESTDIR'}/setupv
    1317    
    1318     open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
    1319     print SCRIPT << 'EOF';
    1320 #!/usr/bin/perl -w
    1321 
    1322 use strict;
    1323 use File::Copy;
    1324 
    1325 EOF
    1326     if ($vtype eq "vm") {
    1327         print SCRIPT << 'EOF';
    1328 # Removes duplicate in .ssh/authorized_keys of our key if needed
    1329 #
    1330 my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
    1331 open(PBFILE,$file1) || die "Unable to open $file1";
    1332 open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
    1333 my $count = 0;
    1334 while (<PBFILE>) {
    1335 EOF
    1336         print SCRIPT << "EOF";
    1337     if (/ $key /) {
    1338         \$count++;
    1339     }
    1340 print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
    1341 }
    1342 close(PBFILE);
    1343 close(PBOUT);
    1344 rename("\$file1.new",\$file1);
    1345 chmod 0600,\$file1;
    1346 EOF
    1347     }
    1348     print SCRIPT << 'EOF';
    1349 
    1350 # Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
    1351 #
    1352 my $file="/etc/passwd";
    1353 open(PBFILE,$file) || die "Unable to open $file";
    1354 my $found = 0;
    1355 while (<PBFILE>) {
    1356 EOF
    1357     print SCRIPT << "EOF";
    1358     \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
    1359 EOF
    1360     print SCRIPT << 'EOF';
    1361 }
    1362 close(PBFILE);
    1363 
    1364 if ( $found == 0 ) {
    1365     if ( ! -d "/home" ) {
    1366         mkdir "/home";
    1367     }
    1368 EOF
    1369     print SCRIPT << "EOF";
    1370 system "groupadd $pbac->{$ENV{'PBPROJ'}}";
    1371 system "useradd $pbac->{$ENV{'PBPROJ'}} -g $pbac->{$ENV{'PBPROJ'}} -m -d /home/$pbac->{$ENV{'PBPROJ'}}";
    1372 
    1373 # allow ssh entry to build
    1374 #
    1375 chdir "/home/$pbac->{$ENV{'PBPROJ'}}";
    1376 mkdir ".ssh",0700;
    1377 # Allow those accessing root to access the build account
    1378 copy("\$ENV{'HOME'}/.ssh/authorized_keys",".ssh/authorized_keys");
    1379 chmod 0600,".ssh/authorized_keys";
    1380 system 'chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} .ssh';
    1381 
    1382 EOF
    1383     print SCRIPT << 'EOF';
    1384 }
    1385 
    1386 # No passwd for build account only keys
    1387 $file="/etc/shadow";
    1388 open(PBFILE,$file) || die "Unable to open $file";
    1389 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
    1390 while (<PBFILE>) {
    1391 EOF
    1392     print SCRIPT << "EOF";
    1393     s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
    1394     s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
    1395 EOF
    1396     print SCRIPT << 'EOF';
    1397     print PBOUT $_;
    1398 }
    1399 close(PBFILE);
    1400 close(PBOUT);
    1401 rename("$file.new",$file);
    1402 chmod 0640,$file;
    1403 
    1404 # pb has to be added to portage group on gentoo
    1405 
    1406 # Adapt sudoers
    1407 $file="/etc/sudoers";
    1408 open(PBFILE,$file) || die "Unable to open $file";
    1409 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
    1410 while (<PBFILE>) {
    1411 EOF
    1412     print SCRIPT << "EOF";
    1413     next if (/^$pbac->{$ENV{'PBPROJ'}}   /);
    1414 EOF
    1415     print SCRIPT << 'EOF';
    1416     s/Defaults[ \t]+requiretty//;
    1417     print PBOUT $_;
    1418 }
    1419 close(PBFILE);
    1420 EOF
    1421     print SCRIPT << "EOF";
    1422 # This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
    1423 print PBOUT "$pbac->{$ENV{'PBPROJ'}}   ALL=(ALL) NOPASSWD:ALL\n";
    1424 EOF
    1425     print SCRIPT << 'EOF';
    1426 close(PBOUT);
    1427 rename("$file.new",$file);
    1428 chmod 0440,$file;
    1429 
    1430 EOF
    1431        
    1432     my $SCRIPT = \*SCRIPT;
    1433    
    1434     pb_install_deps($SCRIPT);
    1435    
    1436     print SCRIPT << 'EOF';
    1437 # Suse wants sudoers as 640
    1438 if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
    1439     chmod 0640,$file;
    1440 }
    1441 
    1442 # Sync date
    1443 #system "/usr/sbin/ntpdate ntp.pool.org";
    1444 
    1445 system "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-*";
    1446 system "pb 2>&1 | head -5";
    1447 EOF
    1448     if ((! $vmexist) && ($vtype eq "vm")) {
    1449         print SCRIPT << 'EOF';
    1450 system "sudo /sbin/halt -p";
    1451 EOF
    1452     }
    1453    
    1454     # Adds pb_distro_init from ProjectBuilder::Distribution
    1455     foreach my $d (@INC) {
    1456         my $f = "$d/ProjectBuilder/Distribution.pm";
    1457         if (-f "$f") {
    1458             open(PBD,"$f") || die "Unable to open $f";
    1459             while (<PBD>) {
    1460                 next if (/^package/);
    1461                 next if (/^use Exporter/);
    1462                 next if (/^\@our /);
    1463                 print SCRIPT $_;
    1464             }
    1465             close(PBD);
    1466             last;
    1467         }
    1468     }
    1469     close(SCRIPT);
    1470     chmod 0755,"$pbscript";
    1471 
    1472     # That build script needs to be run as root
    1473     $pbaccount = "root";
    1474     pb_script2v($pbscript,$vtype);
    1475 }
    1476 return;
    1477 }
    1478 
    1479 sub pb_install_deps {
    1480 
    1481 my $SCRIPT = shift;
    1482 
    1483 print {$SCRIPT} << 'EOF';
    1484 # We need to have that pb_distro_init function
    1485 # Get it from Project-Builder::Distribution
    1486 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
    1487 print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
    1488 
    1489 # Get and install pb
    1490 my $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*";
    1491 my $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*";
    1492 my $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*";
    1493 my $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*";
    1494 
    1495 if ( $ddir eq "fedora" ) {
    1496     system "yum clean all";
    1497     #system "yum update -y";
    1498     my $arch=`uname -m`;
    1499     my $opt = "";
    1500     chomp($arch);
    1501     if ($arch eq "x86_64") {
    1502         $opt="--exclude=*.i?86";
    1503     }
    1504 
    1505     system "yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker";
    1506     if ($dver eq 4) {
    1507         system "$insmb";
    1508         system "$insfm";
    1509         system "$insfb";
    1510     }
    1511 } elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
    1512     # Suppose pkg are installed already as no online mirror available
    1513     system "rpm -e lsb 2>&1 > /dev/null";
    1514     system "$insdm";
    1515     system "$insmb";
    1516     system "$insfm";
    1517     system "$insfb";
    1518 } elsif ($ddir eq "suse") {
    1519     # New OpenSuSE
    1520     system "$insmb";
    1521     system "$insfm";
    1522     system "$insfb";
    1523     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";
    1524 } elsif ( $dfam eq "md" ) {
    1525         system "urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo";
    1526         if (($ddir eq "mandrake") && ($dver eq "10.1")) {
    1527             system "$insdm";
    1528         } else {
    1529             system "urpmi --auto perl-DateManip";
    1530         }
    1531 } elsif ( $dfam eq "du" ) {
    1532     if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
    1533         #system "apt-get update";
    1534         system "$insfb";
    1535         system "$insfm";
    1536         system "apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl";
    1537     } else  {
    1538         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";
    1539     }
    1540 } elsif ( $dfam eq "gen" ) {
    1541         #system "emerge -u system ; emerge wget sudo ntp DateManip File-MimeInfo";
    1542         system "emerge wget sudo ntp DateManip File-MimeInfo";
    1543 } else {
    1544     print "No pkg to install\n";
    1545 }
    1546 EOF
    1547 }
    1548 
    1549 # Return the SSH key file to use
    1550 # Potentially create it if needed
    1551 
    1552 sub pb_ssh_get {
    1553 
    1554 my $create = shift || 0;    # Do not create keys by default
    1555 
    1556 # Check the SSH environment
    1557 my $keyfile = undef;
    1558 
    1559 # We have specific keys by default
    1560 $keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
    1561 if (!(-e $keyfile) && ($create eq 1)) {
    1562     pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
    1563 }
    1564 
    1565 $keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
    1566 $keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
    1567 $keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
    1568 die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
    1569 return($keyfile);
    1570 }
    1571 
    1572 
    1573 # Returns the pid of a running VM command using a specific VM file
    1574 sub pb_check_ps {
    1575     my $vmcmd = shift;
    1576     my $vmm = shift;
    1577     my $vmexist = 0;        # FALSE by default
    1578 
    1579     open(PS, "ps auxhww|") || die "Unable to call ps";
    1580     while (<PS>) {
    1581         next if (! /$vmcmd/);
    1582         next if (! /$vmm/);
    1583         my ($void1, $void2);
    1584         ($void1, $vmexist, $void2) = split(/ +/);
    1585         last;
    1586     }
    1587     return($vmexist);
    1588 }
    1589 
    1590 
    1591 sub pb_extract_build_files {
    1592 
    1593 my $src=shift;
    1594 my $dir=shift;
    1595 my $ddir=shift;
    1596 my @files;
    1597 
    1598 if ($src =~ /tar\.gz$/) {
    1599     pb_system("tar xfpz $src $dir","Extracting build files");
    1600 } elsif ($src =~ /tar\.bz2$/) {
    1601     pb_system("tar xfpj $src $dir","Extracting build files");
    1602 } else {
    1603     die "Unknown compression algorithm for $src";
    1604 }
    1605 opendir(DIR,"$dir") || die "Unable to open directory $dir";
    1606 foreach my $f (readdir(DIR)) {
    1607     next if ($f =~ /^\./);
    1608     move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
    1609     pb_log(2,"mv $dir/$f $ddir\n");
    1610     push @files,"$ddir/$f";
    1611 }
    1612 closedir(DIR);
    1613 # Not enough but still a first cleanup
    1614 pb_rm_rf("$dir");
    1615 return(@files);
    1616 }
    1617 
    1618 sub pb_list_bfiles {
    1619 
    1620 my $dir = shift;
    1621 my $pbpkg = shift;
    1622 my $bfiles = shift;
    1623 my $pkgfiles = shift;
    1624 my $supfiles = shift;
    1625 
    1626 opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
    1627 foreach my $f (readdir(BDIR)) {
    1628     next if ($f =~ /^\./);
    1629     $bfiles->{$f} = "$dir/$f";
    1630     $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
    1631     if (defined $supfiles->{$pbpkg}) {
    1632         $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
    1633     }
    1634 }
    1635 closedir(BDIR);
    1636 }
    1637 
    1638 sub pb_env_init {
    1639 
    1640 my $proj=shift || undef;
    1641 my $pbinit=shift || undef;
    1642 my $action=shift;
    1643 my $ver;
    1644 my $tag;
    1645 
    1646 $ENV{'PBETC'} = "$ENV{'HOME'}/.pbrc";
    1647 
    1648 #
    1649 # Check project name
    1650 # Could be with env var PBPROJ
    1651 # or option -p
    1652 # if not define take the first in conf file
    1653 #
    1654 if ((defined $ENV{'PBPROJ'}) &&
    1655     (not (defined $proj))) {
    1656     $proj = $ENV{'PBPROJ'};
    1657 }
    1658 
    1659 #
    1660 # We get the pbconf file for that project
    1661 # and use its content
    1662 #
    1663 my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
    1664 pb_log(2,"DEBUG pbconfurl: ".Dumper($pbconf)."\n");
    1665 
    1666 my %pbconf = %$pbconf;
    1667 if (not defined $proj) {
    1668     # Take the first as the default project
    1669     $proj = (keys %pbconf)[0];
    1670     if (defined $proj) {
    1671         pb_log(1,"WARNING: using $proj as default project as none has been specified\n");
    1672         pb_log(1,"         Please either create a pbconfurl reference for project $proj in $ENV{'PBETC'}\n");
    1673         pb_log(1,"         or call pb with the -p project option or use the env var PBPROJ\n");
    1674         pb_log(1,"         if you want to use another project\n");
    1675     }
    1676 }
    1677 die "No project defined - use env var PBPROJ or -p proj or a pbconfurl entry in $ENV{'PBETC'}" if (not (defined $proj));
    1678 
    1679 # That's always the environment variable that will be used
    1680 $ENV{'PBPROJ'} = $proj;
    1681 pb_log(2,"PBPROJ: $ENV{'PBPROJ'}\n");
    1682 
    1683 if (not defined ($pbconf{$ENV{'PBPROJ'}})) {
    1684     die "Please create a pbconfurl reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n";
    1685 }
    1686 
    1687 #
    1688 # Detect the root dir for hosting all the content generated with pb
    1689 #
    1690 # Tree will look like this:
    1691 #
    1692 #             maint pbdefdir                         PBDEFDIR            dev dir (optional)
    1693 #                  |                                                        |
    1694 #            ------------------------                                --------------------
    1695 #            |                      |                                |                  |
    1696 #         pbproj1                pbproj2             PBPROJ       pbproj1           pbproj2   PBPROJDIR
    1697 #            |                                                       |
    1698 #  ---------------------------------------------                ----------
    1699 #  *      *        *       |        |          |                *        *
    1700 # tag    dev    pbconf    ...     build     delivery PBCONFDIR dev      tag                 
    1701 #  |               |                           |     PBDESTDIR           |
    1702 #  ---          ------                        pbrc   PBBUILDDIR       -------
    1703 #    |          |    |                                                |     |
    1704 #   1.1        dev  tag                                              1.0   1.1                PBDIR
    1705 #                    |
    1706 #                 -------
    1707 #                 |     |
    1708 #                1.0   1.1                           PBROOTDIR
    1709 #                       |
    1710 #               ----------------------------------
    1711 #               |          |           |         |
    1712 #             pkg1      pbproj1.pb   pbfilter   pbcl
    1713 #               |
    1714 #        -----------------
    1715 #        |      |        |
    1716 #       rpm    deb    pbfilter
    1717 #
    1718 #
    1719 # (*) By default, if no relocation in .pbrc, dev dir is taken in the maint pbdefdir (when appropriate)
    1720 # Names under a pbproj and the corresponding pbconf should be similar
    1721 #
    1722 
    1723 my ($pbdefdir) = pb_conf_get_if("pbdefdir");
    1724 
    1725 if (not defined $ENV{'PBDEFDIR'}) {
    1726     if ((not defined $pbdefdir) || (not defined $pbdefdir->{$ENV{'PBPROJ'}})) {
    1727         pb_log(1,"WARNING: no pbdefdir defined, using /var/cache\n");
    1728         pb_log(1,"         Please create a pbdefdir reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
    1729         pb_log(1,"         if you want to use another directory\n");
    1730         $ENV{'PBDEFDIR'} = "/var/cache";
    1731     } else {
    1732         # That's always the environment variable that will be used
    1733         $ENV{'PBDEFDIR'} = $pbdefdir->{$ENV{'PBPROJ'}};
    1734     }
    1735 }
    1736 # Expand potential env variable in it
    1737 eval { $ENV{'PBDEFDIR'} =~ s/(\$ENV.+\})/$1/eeg };
    1738 
    1739 pb_log(2,"PBDEFDIR: $ENV{'PBDEFDIR'}\n");
    1740 #
    1741 # Set delivery directory
    1742 #
    1743 $ENV{'PBDESTDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/delivery";
    1744 
    1745 pb_log(2,"PBDESTDIR: $ENV{'PBDESTDIR'}\n");
    1746 #
    1747 # Removes all directory existing below the delivery dir
    1748 # as they are temp dir only
    1749 # Files stay and have to be cleaned up manually if needed
    1750 # those files serves as communication channels between pb phases
    1751 # Removing them prevents a following phase to detect what has been done before
    1752 #
    1753 if (-d $ENV{'PBDESTDIR'}) {
    1754     opendir(DIR,$ENV{'PBDESTDIR'}) || die "Unable to open directory $ENV{'PBDESTDIR'}: $!";
    1755     foreach my $d (readdir(DIR)) {
    1756         next if ($d =~ /^\./);
    1757         next if (-f "$ENV{'PBDESTDIR'}/$d");
    1758         pb_rm_rf("$ENV{'PBDESTDIR'}/$d") if (-d "$ENV{'PBDESTDIR'}/$d");
    1759     }
    1760     closedir(DIR);
    1761 }
    1762 if (! -d "$ENV{'PBDESTDIR'}") {
    1763     pb_mkdir_p($ENV{'PBDESTDIR'}) || die "Unable to recursively create $ENV{'PBDESTDIR'}";
    1764 }
    1765 
    1766 #
    1767 # Set build directory
    1768 #
    1769 $ENV{'PBBUILDDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/build";
    1770 if (! -d "$ENV{'PBBUILDDIR'}") {
    1771     pb_mkdir_p($ENV{'PBBUILDDIR'}) || die "Unable to recursively create $ENV{'PBBUILDDIR'}";
    1772 }
    1773 
    1774 pb_log(2,"PBBUILDDIR: $ENV{'PBBUILDDIR'}\n");
    1775 
    1776 pb_temp_init();
    1777 pb_log(2,"PBTMP: $ENV{'PBTMP'}\n");
    1778 
    1779 #
    1780 # The following part is only useful when in cms2something of newver
    1781 # In VMs/VEs we want to skip that by providing good env vars.
    1782 # return values in that case are useless
    1783 #
    1784 if (($action =~ /^cms2/) || ($action =~ /^newver$/)) {
    1785 
    1786     #
    1787     # Check pbconf cms compliance
    1788     #
    1789     pb_cms_compliant("pbconfdir",'PBCONFDIR',"$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/pbconf",$pbconf{$ENV{'PBPROJ'}},$pbinit);
    1790 
    1791     # Check where is our PBROOTDIR (release tag name can't be guessed the first time)
    1792     #
    1793     if (not defined $ENV{'PBROOTDIR'}) {
    1794         if (! -f ("$ENV{'PBDESTDIR'}/pbrc")) {
    1795             opendir(DIR,$ENV{'PBCONFDIR'}) || die "Unable to open directory $ENV{'PBCONFDIR'}: $!";
    1796             my $maxmtime = 0;
    1797             foreach my $d (readdir(DIR)) {
    1798                 pb_log(3,"Looking at \'$d\'...");
    1799                 next if ($d =~ /^\./);
    1800                 next if (! -d "$ENV{'PBCONFDIR'}/$d");
    1801                 my $s = stat("$ENV{'PBCONFDIR'}/$d");
    1802                 next if (not defined $s);
    1803                 pb_log(3,"KEEP\n");
    1804                 # Keep the most recent
    1805                 pb_log(2," $s->mtime\n");
    1806                 if ($s->mtime > $maxmtime) {
    1807                     $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$d";
    1808                     $maxmtime = $s->mtime;
    1809                 }
    1810             }
    1811             closedir(DIR);
    1812             die "No directory found under $ENV{'PBCONFDIR'}" if (not defined $ENV{'PBROOTDIR'});
    1813             pb_log(1,"WARNING: no pbroot defined, using $ENV{'PBROOTDIR'}\n");
    1814             pb_log(1,"         Please use -r release if you want to use another release\n");
    1815         } else {
    1816             my ($pbroot) = pb_conf_read_if("$ENV{'PBDESTDIR'}/pbrc","pbroot");
    1817             # That's always the environment variable that will be used
    1818             die "Please remove inconsistent $ENV{'PBDESTDIR'}/pbrc" if ((not defined $pbroot) || (not defined $pbroot->{$ENV{'PBPROJ'}}));
    1819             $ENV{'PBROOTDIR'} = $pbroot->{$ENV{'PBPROJ'}};
    1820         }
    1821     } else {
    1822         # transform in full path if relative
    1823         $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$ENV{'PBROOTDIR'}" if ($ENV{'PBROOTDIR'} !~ /^\//);
    1824         pb_mkdir_p($ENV{'PBROOTDIR'}) if (defined $pbinit);
    1825         die "$ENV{'PBROOTDIR'} is not a directory" if (not -d $ENV{'PBROOTDIR'});
    1826     }
    1827 
    1828     return  if ($action =~ /^newver$/);
    1829 
    1830     my %version = ();
    1831     my %defpkgdir = ();
    1832     my %extpkgdir = ();
    1833     my %filteredfiles = ();
    1834     my %supfiles = ();
    1835    
    1836     if ((-f "$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") and (not defined $pbinit)) {
    1837         # List of pkg to build by default (mandatory)
    1838         my ($defpkgdir,$pbpackager, $pkgv, $pkgt) = pb_conf_get("defpkgdir","pbpackager","projver","projtag");
    1839         # List of additional pkg to build when all is called (optional)
    1840         # Valid version names (optional)
    1841         # List of files to filter (optional)
    1842         # Project version and tag (optional)
    1843         my ($extpkgdir, $version, $filteredfiles, $supfiles) = pb_conf_get_if("extpkgdir","version","filteredfiles","supfiles");
    1844         pb_log(2,"DEBUG: defpkgdir: ".Dumper($defpkgdir)."\n");
    1845         pb_log(2,"DEBUG: extpkgdir: ".Dumper($extpkgdir)."\n");
    1846         pb_log(2,"DEBUG: version: ".Dumper($version)."\n");
    1847         pb_log(2,"DEBUG: filteredfiles: ".Dumper($filteredfiles)."\n");
    1848         pb_log(2,"DEBUG: supfiles: ".Dumper($supfiles)."\n");
    1849         # Global
    1850         %defpkgdir = %$defpkgdir;
    1851         %extpkgdir = %$extpkgdir if (defined $extpkgdir);
    1852         %version = %$version if (defined $version);
    1853         %filteredfiles = %$filteredfiles if (defined $filteredfiles);
    1854         %supfiles = %$supfiles if (defined $supfiles);
    1855         #
    1856         # Get global Version/Tag
    1857         #
    1858         if (not defined $ENV{'PBPROJVER'}) {
    1859             if ((defined $pkgv) && (defined $pkgv->{$ENV{'PBPROJ'}})) {
    1860                 $ENV{'PBPROJVER'}=$pkgv->{$ENV{'PBPROJ'}};
    1861             } else {
    1862                 die "No projver found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    1863             }
    1864         }
    1865         die "Invalid version name $ENV{'PBPROJVER'} in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb" if (($ENV{'PBPROJVER'} !~ /[0-9.]+/) && (not defined $version) && ($ENV{'PBPROJVER'} =~ /$version{$ENV{'PBPROJ'}}/));
    1866        
    1867         if (not defined $ENV{'PBPROJTAG'}) {
    1868             if ((defined $pkgt) && (defined $pkgt->{$ENV{'PBPROJ'}})) {
    1869                 $ENV{'PBPROJTAG'}=$pkgt->{$ENV{'PBPROJ'}};
    1870             } else {
    1871                 die "No projtag found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    1872             }
    1873         }
    1874         die "Invalid tag name $ENV{'PBPROJTAG'} in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb" if ($ENV{'PBPROJTAG'} !~ /[0-9.]+/);
    1875    
    1876    
    1877         if (not defined $ENV{'PBPACKAGER'}) {
    1878             if ((defined $pbpackager) && (defined $pbpackager->{$ENV{'PBPROJ'}})) {
    1879                 $ENV{'PBPACKAGER'}=$pbpackager->{$ENV{'PBPROJ'}};
    1880             } else {
    1881                 die "No pbpackager found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    1882             }
    1883         }
    1884     } else {
    1885         if (defined $pbinit) {
    1886             my $ptr = pb_get_pkg();
    1887             my @pkgs = @$ptr;
    1888             @pkgs = ("pkg1") if (not @pkgs);
    1889    
    1890             open(CONF,"> $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") || die "Unable to create $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    1891             print CONF << "EOF";
    1892 #
    1893 # Project Builder configuration file
    1894 # For project $ENV{'PBPROJ'}
    1895 #
    1896 # \$Id\$
    1897 #
    1898 
    1899 #
    1900 # What is the project URL
    1901 #
    1902 #pburl $ENV{'PBPROJ'} = svn://svn.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
    1903 #pburl $ENV{'PBPROJ'} = svn://svn+ssh.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
    1904 #pburl $ENV{'PBPROJ'} = cvs://cvs.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
    1905 #pburl $ENV{'PBPROJ'} = http://www.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
    1906 #pburl $ENV{'PBPROJ'} = ftp://ftp.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
    1907 #pburl $ENV{'PBPROJ'} = file:///src/$ENV{'PBPROJ'}-devel.tar.gz
    1908 #pburl $ENV{'PBPROJ'} = dir:///src/$ENV{'PBPROJ'}-devel
    1909 
    1910 # Check whether project is well formed
    1911 # (containing already a directory with the project-version name)
    1912 #pbwf $ENV{'PBPROJ'} = 1
    1913 
    1914 #
    1915 # Packager label
    1916 #
    1917 #pbpackager $ENV{'PBPROJ'} = William Porte <bill\@$ENV{'PBPROJ'}.org>
    1918 #
    1919 
    1920 # For delivery to a machine by SSH (potentially the FTP server)
    1921 # Needs hostname, account and directory
    1922 #
    1923 #sshhost $ENV{'PBPROJ'} = www.$ENV{'PBPROJ'}.org
    1924 #sshlogin $ENV{'PBPROJ'} = bill
    1925 #sshdir $ENV{'PBPROJ'} = /$ENV{'PBPROJ'}/ftp
    1926 #sshport $ENV{'PBPROJ'} = 22
    1927 
    1928 #
    1929 # For Virtual machines management
    1930 # Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
    1931 # followed by '-' and by release number
    1932 # followed by '-' and by architecture
    1933 # a .vmtype extension will be added to the resulting string
    1934 # a QEMU rhel-3-i286 here means that the VM will be named rhel-3-i386.qemu
    1935 #
    1936 #vmlist $ENV{'PBPROJ'} = mandrake-10.1-i386,mandrake-10.2-i386,mandriva-2006.0-i386,mandriva-2007.0-i386,mandriva-2007.1-i386,mandriva-2008.0-i386,redhat-7.3-i386,redhat-9-i386,fedora-4-i386,fedora-5-i386,fedora-6-i386,fedora-7-i386,fedora-8-i386,rhel-3-i386,rhel-4-i386,rhel-5-i386,suse-10.0-i386,suse-10.1-i386,suse-10.2-i386,suse-10.3-i386,sles-9-i386,sles-10-i386,gentoo-nover-i386,debian-3.1-i386,debian-4.0-i386,ubuntu-6.06-i386,ubuntu-7.04-i386,ubuntu-7.10-i386,mandriva-2007.0-x86_64,mandriva-2007.1-x86_64,mandriva-2008.0-x86_64,fedora-6-x86_64,fedora-7-x86_64,fedora-8-x86_64,rhel-4-x86_64,rhel-5-x86_64,suse-10.2-x86_64,suse-10.3-x86_64,sles-10-x86_64,gentoo-nover-x86_64,debian-4.0-x86_64,ubuntu-7.04-x86_64,ubuntu-7.10-x86_64
    1937 
    1938 #
    1939 # Valid values for vmtype are
    1940 # qemu, (vmware, xen, ... TBD)
    1941 #vmtype $ENV{'PBPROJ'} = qemu
    1942 
    1943 # Hash for VM stuff on vmtype
    1944 #vmntp default = pool.ntp.org
    1945 
    1946 # We suppose we can commmunicate with the VM through SSH
    1947 #vmhost $ENV{'PBPROJ'} = localhost
    1948 #vmlogin $ENV{'PBPROJ'} = pb
    1949 #vmport $ENV{'PBPROJ'} = 2222
    1950 
    1951 # Timeout to wait when VM is launched/stopped
    1952 #vmtmout default = 120
    1953 
    1954 # per VMs needed paramaters
    1955 #vmopt $ENV{'PBPROJ'} = -m 384 -daemonize
    1956 #vmpath $ENV{'PBPROJ'} = /home/qemu
    1957 #vmsize $ENV{'PBPROJ'} = 5G
    1958 
    1959 #
    1960 # For Virtual environment management
    1961 # Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
    1962 # followed by '-' and by release number
    1963 # followed by '-' and by architecture
    1964 # a .vetype extension will be added to the resulting string
    1965 # a chroot rhel-3-i286 here means that the VE will be named rhel-3-i386.chroot
    1966 #
    1967 #velist $ENV{'PBPROJ'} = fedora-7-i386
    1968 
    1969 # VE params
    1970 #vetype $ENV{'PBPROJ'} = chroot
    1971 #ventp default = pool.ntp.org
    1972 #velogin $ENV{'PBPROJ'} = pb
    1973 #vepath $ENV{'PBPROJ'} = /var/lib/mock
    1974 #veconf $ENV{'PBPROJ'} = /etc/mock
    1975 #verebuild $ENV{'PBPROJ'} = false
    1976 
    1977 #
    1978 # Global version/tag for the project
    1979 #
    1980 #projver $ENV{'PBPROJ'} = devel
    1981 #projtag $ENV{'PBPROJ'} = 1
    1982 
    1983 # Hash of valid version names
    1984 #version $ENV{'PBPROJ'} = devel,stable
    1985 
    1986 # Adapt to your needs:
    1987 # Optional if you need to overwrite the global values above
    1988 #
    1989 EOF
    1990        
    1991             foreach my $pp (@pkgs) {
    1992                 print CONF << "EOF";
    1993 #pkgver $pp = stable
    1994 #pkgtag $pp = 3
    1995 EOF
    1996             }
    1997             foreach my $pp (@pkgs) {
    1998                 print CONF << "EOF";
    1999 # Hash of default package/package directory
    2000 #defpkgdir $pp = dir-$pp
    2001 EOF
    2002             }
    2003    
    2004             print CONF << "EOF";
    2005 # Hash of additional package/package directory
    2006 #extpkgdir minor-pkg = dir-minor-pkg
    2007 
    2008 # List of files per pkg on which to apply filters
    2009 # Files are mentioned relatively to pbroot/defpkgdir
    2010 EOF
    2011             foreach my $pp (@pkgs) {
    2012                 print CONF << "EOF";
    2013 #filteredfiles $pp = Makefile.PL,configure.in,install.sh,$pp.8
    2014 #supfiles $pp = $pp.init
    2015 EOF
    2016             }
    2017             close(CONF);
    2018             pb_mkdir_p("$ENV{'PBROOTDIR'}/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter";
    2019             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/all.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/all.pbf";
    2020             print CONF << "EOF";
    2021 #
    2022 # \$Id\$
    2023 #
    2024 # Filter for all files
    2025 #
    2026 # PBSRC is replaced by the source package format
    2027 #filter PBSRC = ftp://ftp.$ENV{'PBPROJ'}.org/src/%{name}-%{version}.tar.gz
    2028 
    2029 # PBVER is replaced by the version (\$pbver in code)
    2030 filter PBVER = \$pbver
    2031 
    2032 # PBDATE is replaced by the date (\$pbdate in code)
    2033 filter PBDATE = \$pbdate
    2034 
    2035 # PBLOG is replaced by the changelog if value is yes
    2036 #filter PBLOG = yes
    2037 
    2038 # PBTAG is replaced by the tag (\$pbtag in code)
    2039 filter PBTAG = \$pbtag
    2040 
    2041 # PBREV is replaced by the revision (\$pbrev in code)
    2042 filter PBREV = \$pbrev
    2043 
    2044 # PBPKG is replaced by the package name (\$pbpkg in code)
    2045 filter PBPKG = \$pbpkg
    2046 
    2047 # PBPACKAGER is replaced by the packager name (\$pbpackager in code)
    2048 filter PBPACKAGER = \$pbpackager
    2049 
    2050 # PBDESC contains the description of the package
    2051 #filter PBDESC = "Bla-Bla"
    2052 
    2053 # PBURL contains the URL of the Web site of the project
    2054 #filter PBURL = http://www.$ENV{'PBPROJ'}.org
    2055 EOF
    2056             close(CONF);
    2057             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf";
    2058             print CONF << "EOF";
    2059 #
    2060 # \$Id\$
    2061 #
    2062 # Filter for rpm build
    2063 #
    2064 
    2065 # PBGRP is replaced by the RPM group of apps
    2066 # Cf: http://fedoraproject.org/wiki/RPMGroups
    2067 #filter PBGRP = Applications/Archiving
    2068 
    2069 # PBLIC is replaced by the license of the application
    2070 # Cf: http://fedoraproject.org/wiki/Licensing
    2071 #filter PBLIC = GPL
    2072 
    2073 # PBDEP is replaced by the list of dependencies
    2074 #filter PBDEP =
    2075 
    2076 # PBSUF is replaced by the package suffix (\$pbsuf in code)
    2077 filter PBSUF = \$pbsuf
    2078 
    2079 # PBOBS is replaced by the Obsolete line
    2080 #filter PBOBS =
    2081 
    2082 EOF
    2083             close(CONF);
    2084             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/deb.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/deb.pbf";
    2085             print CONF << "EOF";
    2086 #
    2087 # \$Id\$
    2088 #
    2089 # Filter for debian build
    2090 #
    2091 # PBGRP is replaced by the group of apps
    2092 filter PBGRP = utils
    2093 
    2094 # PBLIC is replaced by the license of the application
    2095 # Cf:
    2096 #filter PBLIC = GPL
    2097 
    2098 # PBDEP is replaced by the list of dependencies
    2099 #filter PBDEP =
    2100 
    2101 # PBSUG is replaced by the list of suggestions
    2102 #filter PBSUG =
    2103 
    2104 # PBREC is replaced by the list of recommandations
    2105 #filter PBREC =
    2106 
    2107 EOF
    2108             close(CONF);
    2109             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/md.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/md.pbf";
    2110             print CONF << "EOF";
    2111 # Specific group for Mandriva for $ENV{'PBPROJ'}
    2112 # Cf: http://wiki.mandriva.com/en/Development/Packaging/Groups
    2113 #filter PBGRP = Archiving/Backup
    2114 
    2115 # PBLIC is replaced by the license of the application
    2116 # Cf: http://wiki.mandriva.com/en/Development/Packaging/Licenses
    2117 #filter PBLIC = GPL
    2118 
    2119 EOF
    2120             close(CONF);
    2121             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/novell.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/novell.pbf";
    2122             print CONF << "EOF";
    2123 # Specific group for SuSE for $ENV{'PBPROJ'}
    2124 # Cf: http://en.opensuse.org/SUSE_Package_Conventions/RPM_Groups
    2125 #filter PBGRP = Productivity/Archiving/Backup
    2126 
    2127 # PBLIC is replaced by the license of the application
    2128 # Cf: http://en.opensuse.org/Packaging/SUSE_Package_Conventions/RPM_Style#1.6._License_Tag
    2129 #filter PBLIC = GPL
    2130 
    2131 EOF
    2132             close(CONF);
    2133             foreach my $pp (@pkgs) {
    2134                 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/deb") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb";
    2135                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/control") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/control";
    2136                 print CONF << "EOF";
    2137 Source: PBPKG
    2138 Section: PBGRP
    2139 Priority: optional
    2140 Maintainer: PBPACKAGER
    2141 Build-Depends: debhelper (>= 4.2.20), PBDEP
    2142 Standards-Version: 3.6.1
    2143 
    2144 Package: PBPKG
    2145 Architecture: amd64 i386 ia64
    2146 Section: PBGRP
    2147 Priority: optional
    2148 Depends: \${shlibs:Depends}, \${misc:Depends}, PBDEP
    2149 Recommends: PBREC
    2150 Suggests: PBSUG
    2151 Description:
    2152  PBDESC
    2153  .
    2154  Homepage: PBURL
    2155 
    2156 EOF
    2157                 close(CONF);
    2158                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/copyright") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/copyright";
    2159                 print CONF << "EOF";
    2160 This package is debianized by PBPACKAGER
    2161 `date`
    2162 
    2163 The current upstream source was downloaded from
    2164 ftp://ftp.$ENV{'PBPROJ'}.org/src/.
    2165 
    2166 Upstream Authors: Put their name here
    2167 
    2168 Copyright:
    2169 
    2170    This package is free software; you can redistribute it and/or modify
    2171    it under the terms of the GNU General Public License as published by
    2172    the Free Software Foundation; version 2 dated June, 1991.
    2173 
    2174    This package is distributed in the hope that it will be useful,
    2175    but WITHOUT ANY WARRANTY; without even the implied warranty of
    2176    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2177    GNU General Public License for more details.
    2178 
    2179    You should have received a copy of the GNU General Public License
    2180    along with this package; if not, write to the Free Software
    2181    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
    2182    MA 02110-1301, USA.
    2183 
    2184 On Debian systems, the complete text of the GNU General
    2185 Public License can be found in /usr/share/common-licenses/GPL.
    2186 
    2187 EOF
    2188                 close(CONF);
    2189                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/changelog") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/changelog";
    2190                 print CONF << "EOF";
    2191 PBLOG
    2192 EOF
    2193                 close(CONF);
    2194                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/compat") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/compat";
    2195                 print CONF << "EOF";
    2196 4
    2197 EOF
    2198                 close(CONF);
    2199                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs";
    2200                 print CONF << "EOF";
    2201 EOF
    2202                 close(CONF);
    2203                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs";
    2204                 print CONF << "EOF";
    2205 INSTALL
    2206 COPYING
    2207 AUTHORS
    2208 NEWS
    2209 README
    2210 EOF
    2211                 close(CONF);
    2212                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/rules") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/rules";
    2213                 print CONF << 'EOF';
    2214 #!/usr/bin/make -f
    2215 # -*- makefile -*-
    2216 # Sample debian/rules that uses debhelper.
    2217 # GNU copyright 1997 to 1999 by Joey Hess.
    2218 #
    2219 # $Id$
    2220 #
    2221 
    2222 # Uncomment this to turn on verbose mode.
    2223 #export DH_VERBOSE=1
    2224 
    2225 # Define package name variable for a one-stop change.
    2226 PACKAGE_NAME = PBPKG
    2227 
    2228 # These are used for cross-compiling and for saving the configure script
    2229 # from having to guess our platform (since we know it already)
    2230 DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
    2231 DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
    2232 
    2233 CFLAGS = -Wall -g
    2234 
    2235 ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
    2236         CFLAGS += -O0
    2237 else
    2238         CFLAGS += -O2
    2239 endif
    2240 ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
    2241         INSTALL_PROGRAM += -s
    2242 endif
    2243 config.status: configure
    2244         dh_testdir
    2245 
    2246         # Configure the package.
    2247         CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr
    2248  --mandir=\$${prefix}/share/man
    2249 
    2250 # Build both architecture dependent and independent
    2251 build: build-arch build-indep
    2252 
    2253 # Build architecture dependent
    2254 build-arch: build-arch-stamp
    2255 
    2256 build-arch-stamp:  config.status
    2257         dh_testdir
    2258 
    2259         # Compile the package.
    2260         $(MAKE)
    2261 
    2262         touch build-stamp
    2263 
    2264 # Build architecture independent
    2265 build-indep: build-indep-stamp
    2266 
    2267 build-indep-stamp:  config.status
    2268         # Nothing to do, the only indep item is the manual which is available as html in original source
    2269         touch build-indep-stamp
    2270 
    2271 # Clean up
    2272 clean:
    2273         dh_testdir
    2274         dh_testroot
    2275         rm -f build-arch-stamp build-indep-stamp #CONFIGURE-STAMP#
    2276         # Clean temporary document directory
    2277         rm -rf debian/doc-temp
    2278         # Clean up.
    2279         -$(MAKE) distclean
    2280         rm -f config.log
    2281 ifneq "$(wildcard /usr/share/misc/config.sub)" ""
    2282         cp -f /usr/share/misc/config.sub config.sub
    2283 endif
    2284 ifneq "$(wildcard /usr/share/misc/config.guess)" ""
    2285         cp -f /usr/share/misc/config.guess config.guess
    2286 endif
    2287 
    2288         dh_clean
    2289 
    2290 # Install architecture dependent and independent
    2291 install: install-arch install-indep
    2292 
    2293 # Install architecture dependent
    2294 install-arch: build-arch
    2295         dh_testdir
    2296         dh_testroot
    2297         dh_clean -k -s
    2298         dh_installdirs -s
    2299 
    2300         # Install the package files into build directory:
    2301         # - start with upstream make install
    2302         $(MAKE) install prefix=$(CURDIR)/debian/$(PACKAGE_NAME)/usr mandir=$(CURDIR)/debian/$(PACKAGE_NAME)/us
    2303 r/share/man
    2304         # - copy html manual to temporary location for renaming
    2305         mkdir -p debian/doc-temp
    2306         dh_install -s
    2307 
    2308 # Install architecture independent
    2309 install-indep: build-indep
    2310         dh_testdir
    2311         dh_testroot
    2312         dh_clean -k -i
    2313         dh_installdirs -i
    2314         dh_install -i
    2315 
    2316 # Must not depend on anything. This is to be called by
    2317 # binary-arch/binary-indep
    2318 # in another 'make' thread.
    2319 binary-common:
    2320         dh_testdir
    2321         dh_testroot
    2322         dh_installchangelogs ChangeLog
    2323         dh_installdocs
    2324         dh_installman
    2325         dh_link
    2326         dh_strip
    2327         dh_compress
    2328         dh_fixperms
    2329         dh_installdeb
    2330         dh_shlibdeps
    2331         dh_gencontrol
    2332         dh_md5sums
    2333         dh_builddeb
    2334 
    2335 # Build architecture independant packages using the common target.
    2336 binary-indep: build-indep install-indep
    2337         $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
    2338 
    2339 # Build architecture dependant packages using the common target.
    2340 binary-arch: build-arch install-arch
    2341         $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
    2342 
    2343 # Build architecture depdendent and independent packages
    2344 binary: binary-arch binary-indep
    2345 .PHONY: clean binary
    2346 
    2347 EOF
    2348                 close(CONF);
    2349                 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/rpm") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm";
    2350                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec";
    2351                 print CONF << 'EOF';
    2352 #
    2353 # $Id$
    2354 #
    2355 
    2356 Summary:        bla-bla
    2357 Summary(fr):    french bla-bla
    2358 
    2359 Name:           PBPKG
    2360 Version:        PBVER
    2361 Release:        PBTAGPBSUF
    2362 License:        PBLIC
    2363 Group:          PBGRP
    2364 Url:            PBURL
    2365 Source:         PBSRC
    2366 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -u -n)
    2367 #Requires:       PBDEP
    2368 
    2369 %description
    2370 PBDESC
    2371 
    2372 %description -l fr
    2373 french desc
    2374 
    2375 %prep
    2376 %setup -q
    2377 
    2378 %build
    2379 %configure
    2380 make %{?_smp_mflags}
    2381 
    2382 %install
    2383 %{__rm} -rf $RPM_BUILD_ROOT
    2384 make DESTDIR=$RPM_BUILD_ROOT install
    2385 
    2386 %clean
    2387 %{__rm} -rf $RPM_BUILD_ROOT
    2388 
    2389 %files
    2390 %defattr(-,root,root)
    2391 %doc ChangeLog
    2392 %doc INSTALL COPYING README AUTHORS NEWS
    2393 
    2394 %changelog
    2395 PBLOG
    2396 
    2397 EOF
    2398                 close(CONF);
    2399                 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/pbfilter";
    2400    
    2401                 pb_log(0,"\nDo not to forget to commit the pbconf directory in your CMS if needed\n");
    2402             }
    2403         } else {
    2404             die "Unable to open $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    2405         }
    2406     }
    2407     umask 0022;
    2408     return(\%filteredfiles, \%supfiles, \%defpkgdir, \%extpkgdir);
    2409 } else {
    2410     # Setup the variables from what has been stored at the end of cms2build
    2411     my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbroot");
    2412     $ENV{'PBROOTDIR'} = $var->{$ENV{'PBPROJ'}};
    2413 
    2414     ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projver");
    2415     $ENV{'PBPROJVER'} = $var->{$ENV{'PBPROJ'}};
    2416 
    2417     ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projtag");
    2418     $ENV{'PBPROJTAG'} = $var->{$ENV{'PBPROJ'}};
    2419 
    2420     ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbpackager");
    2421     $ENV{'PBPACKAGER'} = $var->{$ENV{'PBPROJ'}};
    2422 
    2423     return;
    2424 }
    2425 }
    2426 
    2427 # Function which returns a pointer on a table
    2428 # corresponding to a set of values queried in the conf file
    2429 # and test the returned vaue as they need to exist in that case
    2430 sub pb_conf_get {
    2431 
    2432 my @param = @_;
    2433 my @return = pb_conf_get_if(@param);
    2434 
    2435 die "No params found for $ENV{'PBPROJ'}" if (not @return);
    2436 
    2437 foreach my $i (0..$#param) {
    2438     die "No $param[$i] defined for $ENV{'PBPROJ'}" if (not defined $return[$i]);
    2439 }
    2440 return(@return);
    2441 }
    2442 
    2443 # Function which returns a pointer on a table
    2444 # corresponding to a set of values queried in the conf file
    2445 # Those value may be undef if they do not exist
    2446 sub pb_conf_get_if {
    2447 
    2448 my @param = @_;
    2449 
    2450 # Everything is returned via ptr1
    2451 my @ptr1 = ();
    2452 my @ptr2 = ();
    2453 @ptr1 = pb_conf_read_if("$ENV{'PBETC'}", @param) if (defined $ENV{'PBETC'});
    2454 @ptr2 = pb_conf_read_if("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb", @param) if ((defined $ENV{'PBROOTDIR'}) and (defined $ENV{'PBPROJ'}));
    2455 
    2456 my $p1;
    2457 my $p2;
    2458 
    2459 pb_log(2,"DEBUG: pb_conf_get param1: ".Dumper(@ptr1)."\n");
    2460 pb_log(2,"DEBUG: pb_conf_get param2: ".Dumper(@ptr2)."\n");
    2461 
    2462 foreach my $i (0..$#param) {
    2463     $p1 = $ptr1[$i];
    2464     $p2 = $ptr2[$i];
    2465     # Always try to take the param from the home dir conf file in priority
    2466     # in order to mask what could be defined under the CMS to allow for overloading
    2467     if (not defined $p2) {
    2468         # No ref in CMS project conf file so use the home dir one.
    2469         $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if ((not defined $p1->{$ENV{'PBPROJ'}}) && (defined $p1->{'default'}));
    2470     } else {
    2471         # Ref found in CMS project conf file
    2472         if (not defined $p1) {
    2473             # No ref in home dir project conf file so use the CMS one.
    2474             $p2->{$ENV{'PBPROJ'}} = $p2->{'default'} if ((not defined $p2->{$ENV{'PBPROJ'}}) && (defined $p2->{'default'}));
    2475             $p1 = $p2;
    2476         } else {
    2477             # Both are defined - handling the overloading
    2478             if (not defined $p1->{'default'}) {
    2479                 if (defined $p2->{'default'}) {
    2480                     $p1->{'default'} = $p2->{'default'};
    2481                 }
    2482             }
    2483 
    2484             if (not defined $p1->{$ENV{'PBPROJ'}}) {
    2485                 if (defined $p2->{$ENV{'PBPROJ'}}) {
    2486                     $p1->{$ENV{'PBPROJ'}} = $p2->{$ENV{'PBPROJ'}} if (defined $p2->{$ENV{'PBPROJ'}});
    2487                 } else {
    2488                     $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if (defined $p1->{'default'});
    2489                 }
    2490             }
    2491             # Now copy back into p1 all p2 content which doesn't exist in p1
    2492             # p1 content (local) always has priority over p2 (project)
    2493             foreach my $k (keys %$p2) {
    2494                 $p1->{$k} = $p2->{$k} if (not defined $p1->{$k});
    2495             }
    2496         }
    2497     }
    2498     $ptr1[$i] = $p1;
    2499 }
    2500 pb_log(2,"DEBUG: pb_conf_get param ptr1: ".Dumper(@ptr1)."\n");
    2501 return(@ptr1);
    2502 }
    250344
    250445# Setup environment for CMS system for URL passed
     
    2645186}
    2646187
    2647 
    2648 sub pb_create_authors {
     188# This function is only called with a real CMS system
     189sub pb_cms_get_uri {
     190
     191my $scheme = shift;
     192my $dir = shift;
     193
     194my $res = "";
     195my $void = "";
     196
     197if ($scheme =~ /^svn/) {
     198    open(PIPE,"LANGUAGE=C svn info $dir |") || return("");
     199    while (<PIPE>) {
     200        ($void,$res) = split(/^URL:/) if (/^URL:/);
     201    }
     202    $res =~ s/^\s*//;
     203    close(PIPE);
     204    chomp($res);
     205} elsif ($scheme =~ /^cvs/) {
     206    # This path is always the root path of CVS, but we may be below
     207    open(FILE,"$dir/CVS/Root") || die "$dir isn't CVS controlled";
     208    $res = <FILE>;
     209    chomp($res);
     210    close(FILE);
     211    # Find where we are in the tree
     212    my $rdir = $dir;
     213    while ((! -d "$rdir/CVSROOT") && ($rdir ne "/")) {
     214        $rdir = dirname($rdir);
     215    }
     216    die "Unable to find a CVSROOT dir in the parents of $dir" if (! -d "$rdir/CVSROOT");
     217    #compute our place under that root dir - should be a relative path
     218    $dir =~ s|^$rdir||;
     219    my $suffix = "";
     220    $suffix = "$dir" if ($dir ne "");
     221
     222    my $prefix = "";
     223    if ($scheme =~ /ssh/) {
     224        $prefix = "cvs+ssh://";
     225    } else {
     226        $prefix = "cvs://";
     227    }
     228    $res = $prefix.$res.$suffix;
     229} else {
     230    die "cms $scheme unknown";
     231}
     232pb_log(2,"Found CMS info: $res\n");
     233return($res);
     234}
     235
     236sub pb_cms_copy {
     237my $scheme = shift;
     238my $oldurl = shift;
     239my $newurl = shift;
     240
     241if ($scheme =~ /^svn/) {
     242    pb_system("svn copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
     243} elsif ($scheme eq "flat") {
     244} elsif ($scheme =~ /^cvs/) {
     245} else {
     246    die "cms $scheme unknown";
     247}
     248}
     249
     250sub pb_cms_checkout {
     251my $scheme = shift;
     252my $url = shift;
     253my $destination = shift;
     254
     255if ($scheme =~ /^svn/) {
     256    pb_system("svn co $url $destination","Checking out $url to $destination ");
     257} elsif (($scheme eq "ftp") || ($scheme eq "http")) {
     258    return;
     259} elsif ($scheme =~ /^cvs/) {
     260    pb_system("cvs co $url $destination","Checking out $url to $destination ");
     261} else {
     262    die "cms $scheme unknown";
     263}
     264}
     265
     266sub pb_cms_up {
     267my $scheme = shift;
     268my $dir = shift;
     269
     270if ($scheme =~ /^svn/) {
     271    pb_system("svn up $dir","Updating $dir");
     272} elsif ($scheme eq "flat") {
     273} elsif ($scheme =~ /^cvs/) {
     274} else {
     275    die "cms $scheme unknown";
     276}
     277}
     278
     279sub pb_cms_checkin {
     280my $scheme = shift;
     281my $dir = shift;
     282
     283my $ver = basename($dir);
     284if ($scheme =~ /^svn/) {
     285    pb_system("svn ci -m \"updated to $ver\" $dir","Checking in $dir");
     286} elsif ($scheme eq "flat") {
     287} elsif ($scheme =~ /^cvs/) {
     288} else {
     289    die "cms $scheme unknown";
     290}
     291pb_cms_up($scheme,$dir);
     292}
     293
     294sub pb_cms_isdiff {
     295my $scheme = shift;
     296my $dir =shift;
     297
     298if ($scheme =~ /^svn/) {
     299    open(PIPE,"svn diff $dir |") || die "Unable to get svn diff from $dir";
     300    my $l = 0;
     301    while (<PIPE>) {
     302        $l++;
     303    }
     304    return($l);
     305} elsif ($scheme eq "flat") {
     306} elsif ($scheme =~ /^cvs/) {
     307    open(PIPE,"cvs diff $dir |") || die "Unable to get svn diff from $dir";
     308    my $l = 0;
     309    while (<PIPE>) {
     310        # Skipping normal messages
     311        next if (/^cvs diff:/);
     312        $l++;
     313    }
     314    return($l);
     315} else {
     316    die "cms $scheme unknown";
     317}
     318}
     319
     320#
     321# Return the list of packages we are working on in a CMS action
     322#
     323sub pb_cms_get_pkg {
     324
     325my @pkgs = ();
     326my $defpkgdir = shift || undef;
     327my $extpkgdir = shift || undef;
     328
     329# Get packages list
     330if (not defined $ARGV[0]) {
     331    @pkgs = keys %$defpkgdir if (defined $defpkgdir);
     332} elsif ($ARGV[0] =~ /^all$/) {
     333    @pkgs = keys %$defpkgdir if (defined $defpkgdir);
     334    push(@pkgs, keys %$extpkgdir) if (defined $extpkgdir);
     335} else {
     336    @pkgs = @ARGV;
     337}
     338pb_log(0,"Packages: ".join(',',@pkgs)."\n");
     339return(\@pkgs);
     340}
     341
     342#
     343# Check pbconf/project cms compliance
     344#
     345sub pb_cms_compliant {
     346
     347my $param = shift;
     348my $envar = shift;
     349my $defdir = shift;
     350my $uri = shift;
     351my $pbinit = shift;
     352my %pdir;
     353
     354my ($pdir) = pb_conf_get_if($param) if (defined $param);
     355if (defined $pdir) {
     356    %pdir = %$pdir;
     357}
     358
     359
     360if ((defined $pdir) && (%pdir) && (defined $pdir{$ENV{'PBPROJ'}})) {
     361    # That's always the environment variable that will be used
     362    $ENV{$envar} = $pdir{$ENV{'PBPROJ'}};
     363} else {
     364    if (defined $param) {
     365        pb_log(1,"WARNING: no $param defined, using $defdir\n");
     366        pb_log(1,"         Please create a $param reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
     367        pb_log(1,"         if you want to use another directory\n");
     368    }
     369    $ENV{$envar} = "$defdir";
     370}
     371
     372# Expand potential env variable in it
     373eval { $ENV{$envar} =~ s/(\$ENV.+\})/$1/eeg };
     374pb_log(2,"$envar: $ENV{$envar}\n");
     375
     376my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
     377
     378if ((! -d "$ENV{$envar}") || (defined $pbinit)) {
     379    if (defined $pbinit) {
     380        pb_mkdir_p("$ENV{$envar}");
     381    } else {
     382        pb_log(1,"Checking out $uri\n");
     383        pb_cms_checkout($scheme,$uri,$ENV{$envar});
     384    }
     385} elsif (($scheme !~ /^cvs/) || ($scheme !~ /^svn/)) {
     386    # Do not compare if it's not a real cms
     387    return;
     388} else {
     389    pb_log(1,"$uri found locally, checking content\n");
     390    my $cmsurl = pb_cms_get_uri($scheme,$ENV{$envar});
     391    my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
     392    if ($cmsurl ne $uri) {
     393        # The local content doesn't correpond to the repository
     394        pb_log(0,"ERROR: Inconsistency detected:\n");
     395        pb_log(0,"       * $ENV{$envar} refers to $cmsurl but\n");
     396        pb_log(0,"       * $ENV{'PBETC'} refers to $uri\n");
     397        die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
     398    } else {
     399        pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
     400        # they match - do nothing - there may be local changes
     401    }
     402}
     403}
     404
     405sub pb_cms_create_authors {
    2649406
    2650407my $authors=shift;
     
    2689446my $authors = shift;
    2690447
    2691 pb_create_authors($authors,$dest,$scheme);
     448pb_cms_create_authors($authors,$dest,$scheme);
    2692449
    2693450if ($scheme =~ /^svn/) {
     
    2726483}
    2727484
    2728 # This function is only called with a real CMS system
    2729 sub pb_cms_get_uri {
    2730 
    2731 my $scheme = shift;
    2732 my $dir = shift;
    2733 
    2734 my $res = "";
    2735 my $void = "";
    2736 
    2737 if ($scheme =~ /^svn/) {
    2738     open(PIPE,"LANGUAGE=C svn info $dir |") || return("");
    2739     while (<PIPE>) {
    2740         ($void,$res) = split(/^URL:/) if (/^URL:/);
    2741     }
    2742     $res =~ s/^\s*//;
    2743     close(PIPE);
    2744     chomp($res);
    2745 } elsif ($scheme =~ /^cvs/) {
    2746     # This path is always the root path of CVS, but we may be below
    2747     open(FILE,"$dir/CVS/Root") || die "$dir isn't CVS controlled";
    2748     $res = <FILE>;
    2749     chomp($res);
    2750     close(FILE);
    2751     # Find where we are in the tree
    2752     my $rdir = $dir;
    2753     while ((! -d "$rdir/CVSROOT") && ($rdir ne "/")) {
    2754         $rdir = dirname($rdir);
    2755     }
    2756     die "Unable to find a CVSROOT dir in the parents of $dir" if (! -d "$rdir/CVSROOT");
    2757     #compute our place under that root dir - should be a relative path
    2758     $dir =~ s|^$rdir||;
    2759     my $suffix = "";
    2760     $suffix = "$dir" if ($dir ne "");
    2761 
    2762     my $prefix = "";
    2763     if ($scheme =~ /ssh/) {
    2764         $prefix = "cvs+ssh://";
    2765     } else {
    2766         $prefix = "cvs://";
    2767     }
    2768     $res = $prefix.$res.$suffix;
    2769 } else {
    2770     die "cms $scheme unknown";
    2771 }
    2772 pb_log(2,"Found CMS info: $res\n");
    2773 return($res);
    2774 }
    2775 
    2776 sub pb_cms_copy {
    2777 my $scheme = shift;
    2778 my $oldurl = shift;
    2779 my $newurl = shift;
    2780 
    2781 if ($scheme =~ /^svn/) {
    2782     pb_system("svn copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
    2783 } elsif ($scheme eq "flat") {
    2784 } elsif ($scheme =~ /^cvs/) {
    2785 } else {
    2786     die "cms $scheme unknown";
    2787 }
    2788 }
    2789 
    2790 sub pb_cms_checkout {
    2791 my $scheme = shift;
    2792 my $url = shift;
    2793 my $destination = shift;
    2794 
    2795 if ($scheme =~ /^svn/) {
    2796     pb_system("svn co $url $destination","Checking out $url to $destination ");
    2797 } elsif (($scheme eq "ftp") || ($scheme eq "http")) {
    2798     return;
    2799 } elsif ($scheme =~ /^cvs/) {
    2800     pb_system("cvs co $url $destination","Checking out $url to $destination ");
    2801 } else {
    2802     die "cms $scheme unknown";
    2803 }
    2804 }
    2805 
    2806 sub pb_cms_up {
    2807 my $scheme = shift;
    2808 my $dir = shift;
    2809 
    2810 if ($scheme =~ /^svn/) {
    2811     pb_system("svn up $dir","Updating $dir");
    2812 } elsif ($scheme eq "flat") {
    2813 } elsif ($scheme =~ /^cvs/) {
    2814 } else {
    2815     die "cms $scheme unknown";
    2816 }
    2817 }
    2818 
    2819 sub pb_cms_checkin {
    2820 my $scheme = shift;
    2821 my $dir = shift;
    2822 
    2823 my $ver = basename($dir);
    2824 if ($scheme =~ /^svn/) {
    2825     pb_system("svn ci -m \"updated to $ver\" $dir","Checking in $dir");
    2826 } elsif ($scheme eq "flat") {
    2827 } elsif ($scheme =~ /^cvs/) {
    2828 } else {
    2829     die "cms $scheme unknown";
    2830 }
    2831 pb_cms_up($scheme,$dir);
    2832 }
    2833 
    2834 sub pb_cms_isdiff {
    2835 my $scheme = shift;
    2836 my $dir =shift;
    2837 
    2838 if ($scheme =~ /^svn/) {
    2839     open(PIPE,"svn diff $dir |") || die "Unable to get svn diff from $dir";
    2840     my $l = 0;
    2841     while (<PIPE>) {
    2842         $l++;
    2843     }
    2844     return($l);
    2845 } elsif ($scheme eq "flat") {
    2846 } elsif ($scheme =~ /^cvs/) {
    2847     open(PIPE,"cvs diff $dir |") || die "Unable to get svn diff from $dir";
    2848     my $l = 0;
    2849     while (<PIPE>) {
    2850         # Skipping normal messages
    2851         next if (/^cvs diff:/);
    2852         $l++;
    2853     }
    2854     return($l);
    2855 } else {
    2856     die "cms $scheme unknown";
    2857 }
    2858 }
    2859 
    2860 # Get all filters to apply
    2861 # They're cumulative from less specific to most specific
    2862 # suffix is .pbf
    2863 
    2864 sub pb_get_filters {
    2865 
    2866 my @ffiles;
    2867 my ($ffile00, $ffile0, $ffile1, $ffile2, $ffile3);
    2868 my ($mfile00, $mfile0, $mfile1, $mfile2, $mfile3);
    2869 my $pbpkg = shift || die "No package specified";
    2870 my $dtype = shift || "";
    2871 my $dfam = shift || "";
    2872 my $ddir = shift || "";
    2873 my $dver = shift || "";
    2874 my $ptr = undef; # returned value pointer on the hash of filters
    2875 my %h;
    2876 
    2877 # Global filter files first, then package specificities
    2878 if (-d "$ENV{'PBROOTDIR'}/pbfilter") {
    2879     $mfile00 = "$ENV{'PBROOTDIR'}/pbfilter/all.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/all.pbf");
    2880     $mfile0 = "$ENV{'PBROOTDIR'}/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$dtype.pbf");
    2881     $mfile1 = "$ENV{'PBROOTDIR'}/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$dfam.pbf");
    2882     $mfile2 = "$ENV{'PBROOTDIR'}/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$ddir.pbf");
    2883     $mfile3 = "$ENV{'PBROOTDIR'}/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$ddir-$dver.pbf");
    2884 
    2885     push @ffiles,$mfile00 if (defined $mfile00);
    2886     push @ffiles,$mfile0 if (defined $mfile0);
    2887     push @ffiles,$mfile1 if (defined $mfile1);
    2888     push @ffiles,$mfile2 if (defined $mfile2);
    2889     push @ffiles,$mfile3 if (defined $mfile3);
    2890 }
    2891 
    2892 if (-d "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter") {
    2893     $ffile00 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/all.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/all.pbf");
    2894     $ffile0 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dtype.pbf");
    2895     $ffile1 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dfam.pbf");
    2896     $ffile2 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir.pbf");
    2897     $ffile3 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir-$dver.pbf");
    2898 
    2899     push @ffiles,$ffile00 if (defined $ffile00);
    2900     push @ffiles,$ffile0 if (defined $ffile0);
    2901     push @ffiles,$ffile1 if (defined $ffile1);
    2902     push @ffiles,$ffile2 if (defined $ffile2);
    2903     push @ffiles,$ffile3 if (defined $ffile3);
    2904 }
    2905 if (@ffiles) {
    2906     pb_log(2,"DEBUG ffiles: ".Dumper(\@ffiles)."\n");
    2907 
    2908     foreach my $f (@ffiles) {
    2909         open(CONF,$f) || next;
    2910         while(<CONF>)  {
    2911             if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
    2912                 $h{$1}{$2}=$3;
    2913             }
    2914         }
    2915         close(CONF);
    2916 
    2917         $ptr = $h{"filter"};
    2918         pb_log(2,"DEBUG f:".Dumper($ptr)."\n");
    2919     }
    2920 }
    2921 return($ptr);
    2922 }
    2923 
    2924 # Function which applies filter on pb build files
    2925 sub pb_filter_file_pb {
    2926 
    2927 my $f=shift;
    2928 my $ptr=shift;
    2929 my %filter=%$ptr;
    2930 my $destfile=shift;
    2931 my $dtype=shift;
    2932 my $pbsuf=shift;
    2933 my $pbproj=shift;
    2934 my $pbpkg=shift;
    2935 my $pbver=shift;
    2936 my $pbtag=shift;
    2937 my $pbrev=shift;
    2938 my $pbdate=shift;
    2939 my $defpkgdir = shift;
    2940 my $extpkgdir = shift;
    2941 my $pbpackager = shift;
    2942 my $chglog = shift || undef;
    2943 
    2944 pb_log(2,"DEBUG: From $f to $destfile\n");
    2945 pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
    2946 open(DEST,"> $destfile") || die "Unable to create $destfile";
    2947 open(FILE,"$f") || die "Unable to open $f: $!";
    2948 while (<FILE>) {
    2949     my $line = $_;
    2950     foreach my $s (keys %filter) {
    2951         # Process single variables
    2952         pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
    2953         my $tmp = $filter{$s};
    2954         next if (not defined $tmp);
    2955         # Expand variables if any single one found
    2956         pb_log(2,"DEBUG tmp: $tmp\n");
    2957         if ($tmp =~ /\$/) {
    2958             eval { $tmp =~ s/(\$\w+)/$1/eeg };
    2959         # special case for ChangeLog only for pb
    2960         } elsif (($s =~ /^PBLOG$/) && ($line =~ /^PBLOG$/)) {
    2961             my $p = $defpkgdir->{$pbpkg};
    2962             $p = $extpkgdir->{$pbpkg} if (not defined $p);
    2963             pb_changelog($dtype, $pbpkg, $pbver, $pbtag, $pbsuf, $p, \*DEST, $tmp, $chglog);
    2964             $tmp = "";
    2965         }
    2966         $line =~ s|$s|$tmp|;
    2967     }
    2968     print DEST $line;
    2969 }
    2970 close(FILE);
    2971 close(DEST);
    2972 }
    2973 
    2974 # Function which applies filter on files (external call)
    2975 sub pb_filter_file_inplace {
    2976 
    2977 my $ptr=shift;
    2978 my %filter=%$ptr;
    2979 my $destfile=shift;
    2980 my $pbproj=shift;
    2981 my $pbpkg=shift;
    2982 my $pbver=shift;
    2983 my $pbtag=shift;
    2984 my $pbrev=shift;
    2985 my $pbdate=shift;
    2986 my $pbpackager=shift;
    2987 
    2988 my $cp = "$ENV{'PBTMP'}/".basename($destfile);
    2989 copy($destfile,$cp) || die "Unable to create $cp";
    2990 
    2991 pb_filter_file($cp,$ptr,$destfile,$pbproj,$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$pbpackager);
    2992 unlink $cp;
    2993 }
    2994 
    2995 # Function which applies filter on files (external call)
    2996 sub pb_filter_file {
    2997 
    2998 my $f=shift;
    2999 my $ptr=shift;
    3000 my %filter=%$ptr;
    3001 my $destfile=shift;
    3002 my $pbproj=shift;
    3003 my $pbpkg=shift;
    3004 my $pbver=shift;
    3005 my $pbtag=shift;
    3006 my $pbrev=shift;
    3007 my $pbdate=shift;
    3008 my $pbpackager=shift;
    3009 
    3010 pb_log(2,"DEBUG: From $f to $destfile\n");
    3011 pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
    3012 open(DEST,"> $destfile") || die "Unable to create $destfile";
    3013 open(FILE,"$f") || die "Unable to open $f: $!";
    3014 while (<FILE>) {
    3015     my $line = $_;
    3016     foreach my $s (keys %filter) {
    3017         # Process single variables
    3018         pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
    3019         my $tmp = $filter{$s};
    3020         next if (not defined $tmp);
    3021         # Expand variables if any single one found
    3022         if ($tmp =~ /\$/) {
    3023             eval { $tmp =~ s/(\$\w+)/$1/eeg };
    3024         }
    3025         $line =~ s|$s|$tmp|;
    3026     }
    3027     print DEST $line;
    3028 }
    3029 close(FILE);
    3030 close(DEST);
    3031 }
    3032 
    3033 #
    3034 # Return the list of packages we are working on in a CMS action
    3035 #
    3036 sub pb_cms_get_pkg {
    3037 
    3038 my @pkgs = ();
    3039 my $defpkgdir = shift || undef;
    3040 my $extpkgdir = shift || undef;
    3041 
    3042 # Get packages list
    3043 if (not defined $ARGV[0]) {
    3044     @pkgs = keys %$defpkgdir if (defined $defpkgdir);
    3045 } elsif ($ARGV[0] =~ /^all$/) {
    3046     @pkgs = keys %$defpkgdir if (defined $defpkgdir);
    3047     push(@pkgs, keys %$extpkgdir) if (defined $extpkgdir);
    3048 } else {
    3049     @pkgs = @ARGV;
    3050 }
    3051 pb_log(0,"Packages: ".join(',',@pkgs)."\n");
    3052 return(\@pkgs);
    3053 }
    3054 
    3055 #
    3056 # Return the list of packages we are working on in a non CMS action
    3057 #
    3058 sub pb_get_pkg {
    3059 
    3060 my @pkgs = ();
    3061 
    3062 my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
    3063 @pkgs = keys %$var;
    3064 
    3065 pb_log(0,"Packages: ".join(',',@pkgs)."\n");
    3066 return(\@pkgs);
    3067 }
    3068 
    3069 #
    3070 # Check pbconf/project cms compliance
    3071 #
    3072 sub pb_cms_compliant {
    3073 
    3074 my $param = shift;
    3075 my $envar = shift;
    3076 my $defdir = shift;
    3077 my $uri = shift;
    3078 my $pbinit = shift;
    3079 my %pdir;
    3080 
    3081 my ($pdir) = pb_conf_get_if($param) if (defined $param);
    3082 if (defined $pdir) {
    3083     %pdir = %$pdir;
    3084 }
    3085 
    3086 
    3087 if ((defined $pdir) && (%pdir) && (defined $pdir{$ENV{'PBPROJ'}})) {
    3088     # That's always the environment variable that will be used
    3089     $ENV{$envar} = $pdir{$ENV{'PBPROJ'}};
    3090 } else {
    3091     if (defined $param) {
    3092         pb_log(1,"WARNING: no $param defined, using $defdir\n");
    3093         pb_log(1,"         Please create a $param reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
    3094         pb_log(1,"         if you want to use another directory\n");
    3095     }
    3096     $ENV{$envar} = "$defdir";
    3097 }
    3098 
    3099 # Expand potential env variable in it
    3100 eval { $ENV{$envar} =~ s/(\$ENV.+\})/$1/eeg };
    3101 pb_log(2,"$envar: $ENV{$envar}\n");
    3102 
    3103 my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
    3104 
    3105 if ((! -d "$ENV{$envar}") || (defined $pbinit)) {
    3106     if (defined $pbinit) {
    3107         pb_mkdir_p("$ENV{$envar}");
    3108     } else {
    3109         pb_log(1,"Checking out $uri\n");
    3110         pb_cms_checkout($scheme,$uri,$ENV{$envar});
    3111     }
    3112 } elsif (($scheme !~ /^cvs/) || ($scheme !~ /^svn/)) {
    3113     # Do not compare if it's not a real cms
    3114     return;
    3115 } else {
    3116     pb_log(1,"$uri found locally, checking content\n");
    3117     my $cmsurl = pb_cms_get_uri($scheme,$ENV{$envar});
    3118     my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
    3119     if ($cmsurl ne $uri) {
    3120         # The local content doesn't correpond to the repository
    3121         pb_log(0,"ERROR: Inconsistency detected:\n");
    3122         pb_log(0,"       * $ENV{$envar} refers to $cmsurl but\n");
    3123         pb_log(0,"       * $ENV{'PBETC'} refers to $uri\n");
    3124         die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
    3125     } else {
    3126         pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
    3127         # they match - do nothing - there may be local changes
    3128     }
    3129 }
    3130 }
    3131 
    3132 sub pb_changelog {
    3133 
    3134 my $dtype = shift;
    3135 my $pkg = shift;
    3136 my $pbver = shift;
    3137 my $pbtag = shift;
    3138 my $dsuf = shift;
    3139 my $path = shift;
    3140 my $OUTPUT = shift;
    3141 my $doit = shift;
    3142 my $chglog = shift || undef;
    3143 
    3144 my $log = "";
    3145 
    3146 # For date handling
    3147 $ENV{LANG}="C";
    3148 
    3149 if ((not (defined $dtype)) || ($dtype eq "") ||
    3150         (not (defined $pkg)) || ($pkg eq "") ||
    3151         (not (defined $pbver)) || ($pbver eq "") ||
    3152         (not (defined $pbtag)) || ($pbtag eq "") ||
    3153         (not (defined $dsuf)) || ($dsuf eq "") ||
    3154         (not (defined $path)) || ($path eq "") ||
    3155         (not (defined $OUTPUT)) || ($OUTPUT eq "") ||
    3156         (not (defined $doit)) || ($doit eq "")) {
    3157     print $OUTPUT "\n";
    3158     return;
    3159 }
    3160 
    3161 if (((not defined $chglog) || (! -f $chglog)) && ($doit eq "yes")) {
    3162     #pb_log(2,"No ChangeLog file ($chglog) for $pkg\n";
    3163     print $OUTPUT "\n";
    3164     return;
    3165 }
    3166 
    3167 my $date;
    3168 my $ndate;
    3169 my $n2date;
    3170 my $ver;
    3171 my $ver2;
    3172 my ($pbpackager) = pb_conf_get("pbpackager");
    3173 
    3174 if (not defined $pbpackager->{$ENV{'PBPROJ'}}) {
    3175     $pbpackager->{$ENV{'PBPROJ'}} = "undefined\@noproject.noorg";
    3176 }
    3177 
    3178 # If we don't need to do it, or don't have it fake something
    3179 if (((not defined $chglog) || (! -f $chglog)) && ($doit ne "yes")) {
    3180     my @date = pb_get_date();
    3181     $date = strftime("%Y-%m-%d", @date);
    3182     $ndate = UnixDate($date,"%a", "%b", "%d", "%Y");
    3183     $n2date = &UnixDate($date,"%a, %d %b %Y %H:%M:%S %z");
    3184     if (($dtype eq "rpm") || ($dtype eq "fc")) {
    3185         $ver2 = "$pbver-$pbtag$dsuf";
    3186         print $OUTPUT "* $ndate $pbpackager->{$ENV{'PBPROJ'}} $ver2\n";
    3187         print $OUTPUT "- Updated to $pbver\n";
    3188         }
    3189     if ($dtype eq "deb") {
    3190         print $OUTPUT "$pkg ($pbver) unstable; urgency=low\n";
    3191         print $OUTPUT "\n";
    3192         print $OUTPUT " -- $pbpackager->{$ENV{'PBPROJ'}}  $n2date\n\n\n";
    3193         }
    3194     return;
    3195 }
    3196 
    3197 open(INPUT,"$chglog") || die "Unable to open $chglog (read)";
    3198 
    3199 # Skip first 4 lines
    3200 my $tmp = <INPUT>;
    3201 $tmp = <INPUT>;
    3202 $tmp = <INPUT>;
    3203 if ($dtype eq "announce") {
    3204     print $OUTPUT $tmp;
    3205 }
    3206 $tmp = <INPUT>;
    3207 if ($dtype eq "announce") {
    3208     print $OUTPUT $tmp;
    3209 }
    3210 
    3211 my $first=1;
    3212 
    3213 # Handle each block separated by newline
    3214 while (<INPUT>) {
    3215     ($ver, $date) = split(/ /);
    3216     $ver =~ s/^v//;
    3217     chomp($date);
    3218     $date =~ s/\(([0-9-]+)\)/$1/;
    3219     #pb_log(2,"**$date**\n";
    3220     $ndate = UnixDate($date,"%a", "%b", "%d", "%Y");
    3221     $n2date = &UnixDate($date,"%a, %d %b %Y %H:%M:%S %z");
    3222     #pb_log(2,"**$ndate**\n";
    3223 
    3224     if (($dtype eq "rpm") || ($dtype eq "fc")) {
    3225         if ($ver !~ /-/) {
    3226             if ($first eq 1) {
    3227                 $ver2 = "$ver-$pbtag$dsuf";
    3228                 $first=0;
    3229             } else {
    3230                 $ver2 = "$ver-1$dsuf";
    3231             }
    3232         } else {
    3233             $ver2 = "$ver$dsuf";
    3234         }
    3235         print $OUTPUT "* $ndate $pbpackager->{$ENV{'PBPROJ'}} $ver2\n";
    3236         print $OUTPUT "- Updated to $ver\n";
    3237         }
    3238     if ($dtype eq "deb") {
    3239         print $OUTPUT "$pkg ($ver) unstable; urgency=low\n";
    3240         print $OUTPUT "\n";
    3241         }
    3242 
    3243     $tmp = <INPUT>;
    3244     while ($tmp !~ /^$/) {
    3245         if ($dtype eq "deb") {
    3246             $tmp =~ s/^- //;
    3247             print $OUTPUT "  * $tmp";
    3248         } elsif ($dtype eq "rpm") {
    3249             print $OUTPUT "$tmp";
    3250         } else {
    3251             print $OUTPUT "$tmp";
    3252         }
    3253         last if (eof(INPUT));
    3254         $tmp = <INPUT>;
    3255     }
    3256     print $OUTPUT "\n";
    3257 
    3258     if ($dtype eq "deb") {
    3259         # Cf: http://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog
    3260         print $OUTPUT " -- $pbpackager->{$ENV{'PBPROJ'}}  $n2date\n\n\n";
    3261         }
    3262 
    3263     last if (eof(INPUT));
    3264     last if ($dtype eq "announce");
    3265 }
    3266 close(INPUT);
    3267 }
    32684851;
  • devel/pb/lib/ProjectBuilder/Filter.pm

    r404 r405  
    11#!/usr/bin/perl -w
    22#
    3 # Project Builder main application
     3# ProjectBuilder Filter module
     4# Filtering subroutines brought by the the Project-Builder project
     5# which can be easily used by pbinit
    46#
    57# $Id$
     
    810# Provided under the GPL v2
    911
    10 # Syntax: see at end
     12package ProjectBuilder::Filter;
    1113
    1214use strict 'vars';
    13 use Getopt::Long qw(:config auto_abbrev no_ignore_case);
    1415use Data::Dumper;
    1516use English;
    1617use File::Basename;
    1718use File::Copy;
    18 use File::stat;
    19 use File::Temp qw(tempdir);
    20 use Date::Manip;
    21 use POSIX qw(strftime);
    2219use lib qw (lib);
    23 use ProjectBuilder::Distribution;
    24 use ProjectBuilder::Version;
    2520use ProjectBuilder::Base;
    26 
    27 # Global variables
    28 my %opts;                   # CLI Options
    29 my $action;                 # action to realize
    30 my $test = "FALSE";         # Not used
    31 my $force = 0;              # Force VE/VM rebuild
    32 my $option = "";            # Not used
    33 my @pkgs;                   # list of packages
    34 my $pbtag;                  # Global Tag variable
    35 my $pbver;                  # Global Version variable
    36 my $pbscript;               # Name of the script
    37 my %pbver;                  # per package
    38 my %pbtag;                  # per package
    39 my $pbrev;                  # Global REVISION variable
    40 my $pbaccount;              # Login to use to connect to the VM
    41 my $pbport;                 # Port to use to connect to the VM
    42 my $newver;                 # New version to create
    43 my $iso;                    # ISO image for the VM to create
    44 
    45 my @date = pb_get_date();
    46 my $pbdate = strftime("%Y-%m-%d", @date);
     21use ProjectBuilder::Changelog;
     22
     23# Inherit from the "Exporter" module which handles exporting functions.
     24 
     25use Exporter;
     26 
     27# Export, by default, all the functions into the namespace of
     28# any code which uses this module.
     29 
     30our @ISA = qw(Exporter);
     31our @EXPORT = qw(pb_get_filters pb_filter_file_pb pb_filter_file_inplace pb_filter_file);
    4732
    4833=pod
     
    5035=head1 NAME
    5136
    52 pb, aka project-builder.org - builds packages for your projects
     37ProjectBuilder::Base, part of the project-builder.org - module dealing with generic functions suitable for perl project development
    5338
    5439=head1 DESCRIPTION
     
    6247if you could also have multiple .spec files if required.
    6348
    64 =head1 SYNOPSIS
    65 
    66 pb [-vhq][-r pbroot][-p project][[-s script -a account -P port][-m mach-1[,...]]][-i iso] <action> [<pkg1> ...]
    67 
    68 pb [--verbose][--help][--man][--quiet][--revision pbroot][--project project][[--script script --account account --port port][--machine mach-1[,...]]][--iso iso] <action> [<pkg1> ...]
    69 
    70 =head1 OPTIONS
    71 
    72 =over 4
    73 
    74 =item B<-v|--verbose>
    75 
    76 Print a brief help message and exits.
    77 
    78 =item B<-q|--quiet>
    79 
    80 Do not print any output.
    81 
    82 =item B<-h|--help>
    83 
    84 Print a brief help message and exits.
    85 
    86 =item B<--man>
    87 
    88 Prints the manual page and exits.
    89 
    90 =item B<-m|--machine machine1[,machine2,...]>
    91 
    92 Name of the Virtual Machines (VM) or Virtual Environments (VE) you want to build on (coma separated).
    93 All if none precised (or use the env variable PBV).
    94 
    95 =item B<-s|--script script>
    96 
    97 Name of the script you want to execute on the related VMs or VEs.
    98 
    99 =item B<-i|--iso iso_image>
    100 
    101 Name of the ISO image of the distribution you want to install on the related VMs.
    102 
    103 =item B<-a|--account account>
    104 
    105 Name of the account to use to connect on the related VMs.
    106 
    107 =item B<-P|--port port_number>
    108 
    109 Port number to use to connect on the related VMs.\n";
    110 
    111 =item B<-p|--project project_name>
    112 
    113 Name of the project you're working on (or use the env variable PBPROJ)
    114 
    115 =item B<-r|--revision revision>
    116 
    117 Path Name of the project revision under the CMS (or use the env variable PBROOT)
    118 
    119 =item B<-V|--version new_version>
    120 
    121 New version of the project to create based on the current one.
    122 
    123 =back
    124 
    125 =head1 ARGUMENTS
    126 
    127 <action> can be:
    128 
    129 =over 4
    130 
    131 =item B<cms2build>
    132 
    133 Create tar files for the project under your CMS.
    134 CMS supported are SVN and CVS
    135 parameters are packages to build
    136 if not using default list
    137 
    138 =item B<build2pkg>
    139 
    140 Create packages for your running distribution
    141 
    142 =item B<cms2pkg>
    143 
    144 cms2build + build2pkg
    145 
    146 =item B<build2ssh>
    147 
    148 Send the tar files to a SSH host
    149 
    150 =item B<cms2ssh>
    151 
    152 cms2build + build2ssh
    153 
    154 =item B<pkg2ssh>
    155 
    156 Send the packages built to a SSH host
    157 
    158 =item B<build2vm>
    159 
    160 Create packages in VMs, launching them if needed
    161 and send those packages to a SSH host once built
    162 VM type supported are QEMU
    163 
    164 =item B<build2ve>
    165 
    166 Create packages in VEs, creating it if needed
    167 and send those packages to a SSH host once built
    168 
    169 =item B<cms2vm>
    170 
    171 cms2build + build2vm
    172 
    173 =item B<cms2ve>
    174 
    175 cms2build + build2ve
    176 
    177 =item B<launchvm>
    178 
    179 Launch one virtual machine
    180 
    181 =item B<launchve>
    182 
    183 Launch one virtual environment
    184 
    185 =item B<script2vm>
    186 
    187 Launch one virtual machine if needed
    188 and executes a script on it
    189 
    190 =item B<script2ve>
    191 
    192 Execute a script in a virtual environment
    193 
    194 =item B<newvm>
    195 
    196 Create a new virtual machine
    197 
    198 =item B<newve>
    199 
    200 Create a new virtual environment
    201 
    202 =item B<setupvm>
    203 
    204 Setup a virtual machine for pb usage
    205 
    206 =item B<setupve>
    207 
    208 Setup a virtual environment for pb usage
    209 
    210 =item B<newver>
    211 
    212 Create a new version of the project derived
    213 from the current one
    214 
    215 =item B<newproj>
    216 
    217 Create a new project and a template set of
    218 configuration files under pbconf
    219 
    220 =back
    221 
    222 <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).
    223 
    224 =head1 WEB SITES
    225 
    226 The 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/>.
    227 
    228 =head1 USER MAILING LIST
    229 
    230 None exists for the moment.
    231 
    232 =head1 CONFIGURATION FILES
    233 
    234 Each pb user may have a configuration in F<$HOME/.pbrc>. The values in this file may overwrite any other configuration file value.
    235 
    236 Here is an example of such a configuration file:
    237 
    238  #
    239  # Define for each project the URL of its pbconf repository
    240  # No default option allowed here as they need to be all different
    241  #
    242  # URL of the pbconf content
    243  # This is the format of a classical URL with the extension of additional schema such as
    244  # svn+ssh, cvs+ssh, ...
    245  #
    246  pbconfurl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe/pbconf
    247 
    248  # This is normaly defined in the project's configuration file
    249  # Url of the project
    250  #
    251  pburl linuxcoe = cvs+ssh://:ext:bcornec@linuxcoe.cvs.sourceforge.net:/cvsroot/linuxcoe
    252  
    253  # All these URLs needs to be defined here as the are the entry point
    254  # for how to build packages for the project
    255  #
    256  pbconfurl pb = svn+ssh://svn.project-builder.org/mondo/svn/pb/pbconf
    257  pbconfurl mondorescue = svn+ssh://svn.project-builder.org/mondo/svn/project-builder/mondorescue/pbconf
    258  pbconfurl collectl = svn+ssh://bruno@svn.mondorescue.org/mondo/svn/project-builder/collectl/pbconf
    259  pbconfurl netperf = svn+ssh://svn.mondorescue.org/mondo/svn/project-builder/netperf/pbconf
    260  
    261  # Under that dir will take place everything related to pb
    262  # If you want to use VMs/chroot/..., then use $ENV{'HOME'} to make it portable
    263  # to your VMs/chroot/...
    264  # if not defined then /var/cache
    265  pbdefdir default = $ENV{'HOME'}/project-builder
    266  pbdefdir pb = $ENV{'HOME'}
    267  pbdefdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
    268  pbdefdir mondorescue = $ENV{'HOME'}/mondo/svn
    269  
    270  # pbconfdir points to the directory where the CMS content of the pbconfurl is checked out
    271  # If not defined, pbconfdir is under pbdefdir/pbproj/pbconf
    272  pbconfdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs/pbconf
    273  pbconfdir mondorescue = $ENV{'HOME'}/mondo/svn/pbconf
    274  
    275  # pbdir points to the directory where the CMS content of the pburl is checked out
    276  # If not defined, pbdir is under pbdefdir/pbproj
    277  # Only defined if we have access to the dev of the project
    278  pbdir linuxcoe = $ENV{'HOME'}/LinuxCOE/cvs
    279  pbdir mondorescue = $ENV{'HOME'}/mondo/svn
    280  
    281  # -daemonize doesn't work with qemu 0.8.2
    282  vmopt default = -m 384
    283 
    284 =head1 AUTHORS
    285 
    286 The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
    287 
    288 =head1 COPYRIGHT
    289 
    290 Project-Builder.org is distributed under the GPL v2.0 license
    291 described in the file C<COPYING> included with the distribution.
    292 
    29349=cut
    294 
    295 # ---------------------------------------------------------------------------
    296 
    297 # Old syntax
    298 #getopts('a:fhi:l:m:P:p:qr:s:vV:',\%opts);
    299 
    300 my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
    301 
    302 # Initialize the syntax string
    303 
    304 pb_syntax_init("pb (aka project-builder.org) Version $projectbuilderver-$projectbuilderrev\n");
    305 
    306 GetOptions("help|?|h" => \$opts{'h'},
    307         "man" => \$opts{'man'},
    308         "verbose|v+" => \$opts{'v'},
    309         "quiet|q" => \$opts{'q'},
    310         "log-files|l=s" => \$opts{'l'},
    311         "force|f" => \$opts{'f'},
    312         "account|a=s" => \$opts{'a'},
    313         "revision|r=s" => \$opts{'r'},
    314         "script|s=s" => \$opts{'s'},
    315         "machines|mock|m=s" => \$opts{'m'},
    316         "port|P=i" => \$opts{'P'},
    317         "project|p=s" => \$opts{'p'},
    318         "iso|i=s" => \$opts{'i'},
    319         "version|V=s" => \$opts{'V'},
    320 ) || pb_syntax(-1,0);
    321 
    322 if (defined $opts{'h'}) {
    323     pb_syntax(0,1);
    324 }
    325 if (defined $opts{'man'}) {
    326     pb_syntax(0,2);
    327 }
    328 if (defined $opts{'v'}) {
    329     $debug = $opts{'v'};
    330     pb_log(0,"Debug value: $debug\n");
    331 }
    332 if (defined $opts{'f'}) {
    333     $force=1;
    334 }
    335 if (defined $opts{'q'}) {
    336     $debug=-1;
    337 }
    338 if (defined $opts{'l'}) {
    339     open(LOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
    340     $LOG = \*LOG;
    341     $debug = 0  if ($debug == -1);
    342     }
    343 pb_log_init($debug, $LOG);
    344 
    345 # Handle root of the project if defined
    346 if (defined $opts{'r'}) {
    347     $ENV{'PBROOTDIR'} = $opts{'r'};
    348 }
    349 # Handle virtual machines if any
    350 if (defined $opts{'m'}) {
    351     $ENV{'PBV'} = $opts{'m'};
    352 }
    353 if (defined $opts{'s'}) {
    354     $pbscript = $opts{'s'};
    355 }
    356 if (defined $opts{'a'}) {
    357     $pbaccount = $opts{'a'};
    358     die "option -a requires a -s script option" if (not defined $pbscript);
    359 }
    360 if (defined $opts{'P'}) {
    361     $pbport = $opts{'P'};
    362 }
    363 if (defined $opts{'V'}) {
    364     $newver = $opts{'V'};
    365 }
    366 if (defined $opts{'i'}) {
    367     $iso = $opts{'i'};
    368 }
    369 
    370 # Get Action
    371 $action = shift @ARGV;
    372 die pb_syntax(-1,1) if (not defined $action);
    373 
    374 my ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir);
    375 my $pbinit = undef;
    376 $pbinit = 1 if ($action =~ /^newproj$/);
    377 
    378 # Handles project name if any
    379 # And get global params
    380 ($filteredfiles, $supfiles, $defpkgdir, $extpkgdir) = pb_env_init($opts{'p'},$pbinit,$action);
    381 
    382 pb_log(0,"Project: $ENV{'PBPROJ'}\n");
    383 pb_log(0,"Action: $action\n");
    384 
    385 # Act depending on action
    386 if ($action =~ /^cms2build$/) {
    387     pb_cms2build();
    388 } elsif ($action =~ /^build2pkg$/) {
    389     pb_build2pkg();
    390 } elsif ($action =~ /^cms2pkg$/) {
    391     pb_cms2build();
    392     pb_build2pkg();
    393 } elsif ($action =~ /^build2ssh$/) {
    394     pb_build2ssh();
    395 } elsif ($action =~ /^cms2ssh$/) {
    396     pb_cms2build();
    397     pb_build2ssh();
    398 } elsif ($action =~ /^pkg2ssh$/) {
    399     pb_pkg2ssh();
    400 } elsif ($action =~ /^build2ve$/) {
    401     pb_build2v("ve");
    402 } elsif ($action =~ /^build2vm$/) {
    403     pb_build2v("vm");
    404 } elsif ($action =~ /^cms2ve$/) {
    405     pb_cms2build();
    406     pb_build2v("ve");
    407 } elsif ($action =~ /^cms2vm$/) {
    408     pb_cms2build();
    409     pb_build2v("vm");
    410 } elsif ($action =~ /^launchvm$/) {
    411     pb_launchv("vm",$ENV{'PBV'},0);
    412 } elsif ($action =~ /^launchve$/) {
    413     pb_launchv("ve",$ENV{'PBV'},0);
    414 } elsif ($action =~ /^script2vm$/) {
    415     pb_script2v($pbscript,"vm");
    416 } elsif ($action =~ /^script2ve$/) {
    417     pb_script2v($pbscript,"ve");
    418 } elsif ($action =~ /^newver$/) {
    419     pb_newver();
    420 } elsif ($action =~ /^newve$/) {
    421     pb_launchv("ve",$ENV{'PBV'},1);
    422 } elsif ($action =~ /^newvm$/) {
    423     pb_launchv("vm",$ENV{'PBV'},1);
    424 } elsif ($action =~ /^setupve$/) {
    425     pb_setup_v("ve");
    426 } elsif ($action =~ /^setupvm$/) {
    427     pb_setup_v("vm");
    428 } elsif ($action =~ /^newproj$/) {
    429     # Nothing to do - already done in pb_env_init
    430 } elsif ($action =~ /^clean$/) {
    431 } else {
    432     pb_log(0,"\'$action\' is not available\n");
    433     pb_syntax(-2,1);
    434 }
    435 
    436 sub pb_cms2build {
    437 
    438     my $pkg = pb_cms_get_pkg($defpkgdir,$extpkgdir);
    439     my @pkgs = @$pkg;
    440     my %pkgs;
    441 
    442     my ($scheme, $uri) = pb_cms_init($pbinit);
    443 
    444     my ($pkgv, $pkgt) = pb_conf_get_if("pkgver","pkgtag");
    445 
    446     # declare packager for filtering
    447     my ($tmp) = pb_conf_get("pbpackager");
    448     $ENV{'PBPACKAGER'} = $tmp->{$ENV{'PBPROJ'}};
    449 
    450     foreach my $pbpkg (@pkgs) {
    451         $ENV{'PBPKG'} = $pbpkg;
    452         if ((defined $pkgv) && (defined $pkgv->{$pbpkg})) {
    453             $pbver = $pkgv->{$pbpkg};
    454         } else {
    455             $pbver = $ENV{'PBPROJVER'};
    456         }
    457         if ((defined $pkgt) && (defined $pkgt->{$pbpkg})) {
    458             $pbtag = $pkgt->{$pbpkg};
    459         } else {
    460             $pbtag = $ENV{'PBPROJTAG'};
    461         }
    462 
    463         $pbrev = $ENV{'PBREVISION'};
    464         pb_log(0,"\n");
    465         pb_log(0,"Management of $pbpkg $pbver-$pbtag (rev $pbrev)\n");
    466         die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
    467         # Clean up dest if necessary. The export will recreate it
    468         my $dest = "$ENV{'PBDESTDIR'}/$pbpkg-$pbver";
    469         pb_rm_rf($dest) if (-d $dest);
    470 
    471         # Export CMS tree for the concerned package to dest
    472         # And generate some additional files
    473         $OUTPUT_AUTOFLUSH=1;
    474 
    475         # computes in which dir we have to work
    476         my $dir = $defpkgdir->{$pbpkg};
    477         $dir = $extpkgdir->{$pbpkg} if (not defined $dir);
    478         pb_log(2,"def:".Dumper($defpkgdir)." ext: ".Dumper($extpkgdir)." \n");
    479 
    480         # Exporting from CMS
    481         pb_cms_export($uri,"$ENV{'PBDIR'}/$dir",$dest);
    482 
    483         # Get project info on authors and log file
    484         my $chglog = "$ENV{'PBROOTDIR'}/$pbpkg/pbcl";
    485         $chglog = "$ENV{'PBROOTDIR'}/pbcl" if (! -f $chglog);
    486         $chglog = undef if (! -f $chglog);
    487 
    488         my $authors = "$ENV{'PBROOTDIR'}/$pbpkg/pbauthors";
    489         $authors = "$ENV{'PBROOTDIR'}/pbauthors" if (! -f $authors);
    490         $authors = "/dev/null" if (! -f $authors);
    491 
    492         # Extract cms log history and store it
    493         if ((defined $chglog) && (! -f "$dest/NEWS")) {
    494             pb_log(2,"Generating NEWS file from $chglog\n");
    495             copy($chglog,"$dest/NEWS") || die "Unable to create $dest/NEWS";
    496         }
    497         pb_cms_log($scheme,"$ENV{'PBDIR'}/$dir",$dest,$chglog,$authors);
    498 
    499         my %build;
    500 
    501         my @pt;
    502         @pt = pb_conf_get_if("vmlist","velist");
    503         my $tmpl = "";
    504         if (defined $pt[0]->{$ENV{'PBPROJ'}}) {
    505             $tmpl .= $pt[0]->{$ENV{'PBPROJ'}};
    506         }
    507         if (defined $pt[1]->{$ENV{'PBPROJ'}}) {
    508             # the 2 lists needs to be grouped with a ',' separated them
    509             if ($tmpl ne "") {
    510                 $tmpl .= ",";
    511             }
    512             $tmpl .= $pt[1]->{$ENV{'PBPROJ'}}
    513         }
    514         foreach my $d (split(/,/,$tmpl)) {
    515             my ($name,$ver,$arch) = split(/-/,$d);
    516             chomp($arch);
    517             my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
    518             pb_log(2,"DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n");
    519             pb_log(2,"DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n");
    520 
    521             # Filter build files from the less precise up to the most with overloading
    522             # Filter all files found, keeping the name, and generating in dest
    523 
    524             # Find all build files first relatively to PBROOTDIR
    525             # Find also all specific files referenced in the .pb conf file
    526             my %bfiles = ();
    527             my %pkgfiles = ();
    528             $build{"$ddir-$dver"} = "yes";
    529 
    530             if (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dtype") {
    531                 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dtype",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
    532             } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$dfam") {
    533                 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$dfam",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
    534             } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir") {
    535                 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
    536             } elsif (-d "$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver") {
    537                 pb_list_bfiles("$ENV{'PBROOTDIR'}/$pbpkg/$ddir-$dver",$pbpkg,\%bfiles,\%pkgfiles,$supfiles);
    538             } else {
    539                 $build{"$ddir-$dver"} = "no";
    540                 next;
    541             }
    542             pb_log(2,"DEBUG bfiles: ".Dumper(\%bfiles)."\n");
    543 
    544             # Get all filters to apply
    545             my $ptr = pb_get_filters($pbpkg, $dtype, $dfam, $ddir, $dver);
    546 
    547             # Apply now all the filters on all the files concerned
    548             # destination dir depends on the type of file
    549             if (defined $ptr) {
    550                 foreach my $f (values %bfiles,values %pkgfiles) {
    551                     pb_filter_file_pb("$ENV{'PBROOTDIR'}/$f",$ptr,"$dest/pbconf/$ddir-$dver/".basename($f),$dtype,$pbsuf,$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$defpkgdir,$extpkgdir,$ENV{'PBPACKAGER'},$chglog);
    552                 }
    553             }
    554         }
    555         my @found;
    556         my @notfound;
    557         foreach my $b (keys %build) {
    558             push @found,$b if ($build{$b} =~ /yes/);
    559             push @notfound,$b if ($build{$b} =~ /no/);
    560         }
    561         pb_log(0,"Build files generated for ".join(',',@found)."\n");
    562         pb_log(0,"No Build files found for ".join(',',@notfound)."\n") if (@notfound);
    563         # Get the generic filter (all.pbf) and
    564         # apply those to the non-build files including those
    565         # generated by pbinit if applicable
    566 
    567         # Get only all.pbf filter
    568         my $ptr = pb_get_filters($pbpkg);
    569 
    570         my $liste ="";
    571         if (defined $filteredfiles->{$pbpkg}) {
    572             foreach my $f (split(/,/,$filteredfiles->{$pbpkg})) {
    573                 pb_filter_file_inplace($ptr,"$dest/$f",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'});
    574                 $liste = "$f $liste";
    575             }
    576         }
    577         pb_log(2,"Files ".$liste."have been filtered\n");
    578 
    579         # Prepare the dest directory for archive
    580         if (-x "$ENV{'PBROOTDIR'}/$pbpkg/pbinit") {
    581             pb_filter_file("$ENV{'PBROOTDIR'}/$pbpkg/pbinit",$ptr,"$ENV{'PBTMP'}/pbinit",$ENV{'PBPROJ'},$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$ENV{'PBPACKAGER'});
    582             chmod 0755,"$ENV{'PBTMP'}/pbinit";
    583             pb_system("cd $dest ; $ENV{'PBTMP'}/pbinit","Executing init script from $ENV{'PBROOTDIR'}/$pbpkg/pbinit");
    584         }
    585 
    586         # Archive dest dir
    587         chdir "$ENV{'PBDESTDIR'}" || die "Unable to change dir to $ENV{'PBDESTDIR'}";
    588         # Possibility to look at PBSRC to guess more the filename
    589         pb_system("tar cfz $pbpkg-$pbver.tar.gz $pbpkg-$pbver","Creating $pbpkg tar files compressed");
    590         pb_log(0,"Under $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz\n");
    591 
    592         # Keep track of version-tag per pkg
    593         $pkgs{$pbpkg} = "$pbver-$pbtag";
    594 
    595         # Final cleanup
    596         pb_rm_rf($dest) if (-d $dest);
    597     }
    598 
    599     # Keep track of per package version
    600     pb_log(2,"DEBUG pkgs: ".Dumper(%pkgs)."\n");
    601     open(PKG,"> $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb") || die "Unable to create $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb";
    602     foreach my $pbpkg (@pkgs) {
    603         print PKG "pbpkg $pbpkg = $pkgs{$pbpkg}\n";
    604     }
    605     close(PKG);
    606 
    607     # Keep track of what is generated by default
    608     # We need to store the dir and info on version-tag
    609     # Base our content on the existing .pb file
    610     copy("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb","$ENV{'PBDESTDIR'}/pbrc");
    611     open(LAST,">> $ENV{'PBDESTDIR'}/pbrc") || die "Unable to create $ENV{'PBDESTDIR'}/pbrc";
    612     print LAST "pbroot $ENV{'PBPROJ'} = $ENV{'PBROOTDIR'}\n";
    613     print LAST "pbprojver $ENV{'PBPROJ'} = $ENV{'PBPROJVER'}\n";
    614     print LAST "pbprojtag $ENV{'PBPROJ'} = $ENV{'PBPROJTAG'}\n";
    615     print LAST "pbpackager $ENV{'PBPROJ'} = $ENV{'PBPACKAGER'}\n";
    616     close(LAST);
    617 }
    618 
    619 sub pb_build2pkg {
    620 
    621     # Get the running distro to build on
    622     my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
    623     pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
    624 
    625     # Get list of packages to build
    626     # Get content saved in cms2build
    627     my $ptr = pb_get_pkg();
    628     @pkgs = @$ptr;
    629 
    630     my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
    631     $pkg = { } if (not defined $pkg);
    632 
    633     chdir "$ENV{'PBBUILDDIR'}";
    634     my $made = ""; # pkgs made during build
    635     foreach my $pbpkg (@pkgs) {
    636         my $vertag = $pkg->{$pbpkg};
    637         # get the version of the current package - maybe different
    638         ($pbver,$pbtag) = split(/-/,$vertag);
    639 
    640         my $src="$ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
    641         pb_log(2,"Source file: $src\n");
    642 
    643         pb_log(2,"Working directory: $ENV{'PBBUILDDIR'}\n");
    644         if ($dtype eq "rpm") {
    645             foreach my $d ('RPMS','SRPMS','SPECS','SOURCES','BUILD') {
    646                 if (! -d "$ENV{'PBBUILDDIR'}/$d") {
    647                 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";
    648                 }
    649             }
    650 
    651             # Remove in case a previous link/file was there
    652             unlink "$ENV{'PBBUILDDIR'}/SOURCES/".basename($src);
    653             symlink "$src","$ENV{'PBBUILDDIR'}/SOURCES/".basename($src) || die "Unable to symlink $src in $ENV{'PBBUILDDIR'}/SOURCES";
    654             # We need to first extract the spec file
    655             my @specfile;
    656             @specfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$ENV{'PBBUILDDIR'}/SPECS");
    657 
    658             pb_log(2,"specfile: ".Dumper(\@specfile)."\n");
    659             # set LANGUAGE to check for correct log messages
    660             $ENV{'LANGUAGE'}="C";
    661             foreach my $f (@specfile) {
    662                 if ($f =~ /\.spec$/) {
    663                     pb_system("rpmbuild --define \'packager $ENV{'PBPACKAGER'}\' --define \"_topdir $ENV{'PBBUILDDIR'}\" -ba $f","Building package with $f under $ENV{'PBBUILDDIR'}");
    664                     last;
    665                 }
    666             }
    667             $made="$made RPMS/*/$pbpkg-$pbver-$pbtag$pbsuf.*.rpm SRPMS/$pbpkg-$pbver-$pbtag$pbsuf.src.rpm";
    668             if (-f "/usr/bin/rpmlint") {
    669                 pb_system("rpmlint $made","Checking validity of rpms with rpmlint");
    670             }
    671         } elsif ($dtype eq "deb") {
    672             chdir "$ENV{'PBBUILDDIR'}" || die "Unable to chdir to $ENV{'PBBUILDDIR'}";
    673             pb_system("tar xfz $src","Extracting sources");
    674 
    675             chdir "$pbpkg-$pbver" || die "Unable to chdir to $pbpkg-$pbver";
    676             pb_rm_rf("debian");
    677             symlink "pbconf/$ddir-$dver","debian" || die "Unable to symlink to pbconf/$ddir-$dver";
    678             chmod 0755,"debian/rules";
    679             pb_system("dpkg-buildpackage -us -uc -rfakeroot","Building package");
    680             $made="$made $pbpkg"."_*.deb $pbpkg"."_*.dsc $pbpkg"."_*.tar.gz";
    681             if (-f "/usr/bin/lintian") {
    682                 pb_system("lintian $made","Checking validity of debs with lintian");
    683             }
    684         } elsif ($dtype eq "ebuild") {
    685             my @ebuildfile;
    686             # For gentoo we need to take pb as subsystem name
    687             # We put every apps here under sys-apps. hope it's correct
    688             # We use pb's home dir in order o have a single OVERLAY line
    689             my $tmpd = "$ENV{'HOME'}/portage/pb/sys-apps/$pbpkg";
    690             pb_mkdir_p($tmpd) if (! -d "$tmpd");
    691             pb_mkdir_p("$ENV{'HOME'}/portage/distfiles") if (! -d "$ENV{'HOME'}/portage/distfiles");
    692 
    693             # We need to first extract the ebuild file
    694             @ebuildfile = pb_extract_build_files($src,"$pbpkg-$pbver/pbconf/$ddir-$dver/","$tmpd");
    695 
    696             # Prepare the build env for gentoo
    697             my $found = 0;
    698             my $pbbd = $ENV{'HOME'};
    699             $pbbd =~ s|/|\\/|g;
    700             if (-r "/etc/make.conf") {
    701                 open(MAKE,"/etc/make.conf");
    702                 while (<MAKE>) {
    703                     $found = 1 if (/$pbbd\/portage/);
    704                 }
    705                 close(MAKE);
    706             }
    707             if ($found == 0) {
    708                 pb_system("sudo sh -c 'echo PORTDIR_OVERLAY=\"$ENV{'HOME'}/portage\" >> /etc/make.conf'");
    709             }
    710             #$found = 0;
    711             #if (-r "/etc/portage/package.keywords") {
    712             #open(KEYW,"/etc/portage/package.keywords");
    713             #while (<KEYW>) {
    714             #$found = 1 if (/portage\/pb/);
    715             #}
    716             #close(KEYW);
    717             #}
    718             #if ($found == 0) {
    719             #pb_system("sudo sh -c \"echo portage/pb >> /etc/portage/package.keywords\"");
    720             #}
    721 
    722             # Build
    723             foreach my $f (@ebuildfile) {
    724                 if ($f =~ /\.ebuild$/) {
    725                     move($f,"$tmpd/$pbpkg-$pbver.ebuild");
    726                     pb_system("cd $tmpd ; ebuild $pbpkg-$pbver.ebuild clean ; ebuild $pbpkg-$pbver.ebuild digest ; ebuild $pbpkg-$pbver.ebuild package");
    727                     # Now move it where pb expects it
    728                     pb_mkdir_p("$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
    729                     move("$tmpd/$pbpkg-$pbver.ebuild","$ENV{'PBBUILDDIR'}/portage/pb/sys-apps/$pbpkg");
    730                 }
    731             }
    732 
    733             $made="$made portage/pb/sys-apps/$pbpkg/$pbpkg-$pbver.ebuild";
    734         } elsif ($dtype eq "slackware") {
    735             $made="$made build-$pbpkg/$pbpkg-$pbver-*-$pbtag.tgz";
    736             pb_mkdir_p("$ENV{'PBBUILDDIR'}/install") if (! -d "$ENV{'PBBUILDDIR'}/install");
    737         } else {
    738             die "Unknown dtype format $dtype";
    739         }
    740     }
    741     # Keep track of what is generated so that we can get them back from VMs
    742     open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to create $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
    743     print KEEP "$made\n";
    744     close(KEEP);
    745 }
    746 
    747 sub pb_build2ssh {
    748     pb_send2target("Sources");
    749 }
    750 
    751 sub pb_pkg2ssh {
    752     pb_send2target("Packages");
    753 }
    754 
    755 # By default deliver to the the public site hosting the
    756 # ftp structure (or whatever) or a VM/VE
    757 sub pb_send2target {
    758 
    759     my $cmt = shift;
    760     my $v = shift || undef;
    761     my $vmexist = shift || 0;           # 0 is FALSE
    762     my $vmpid = shift || 0;             # 0 is FALSE
    763 
    764     my $host = "sshhost";
    765     my $login = "sshlogin";
    766     my $dir = "sshdir";
    767     my $port = "sshport";
    768     my $tmout = "sshtmout";
    769     my $path = "sshpath";
    770     my $conf = "sshconf";
    771     my $rebuild = "sshrebuild";
    772     if (($cmt eq "vm") || ($cmt eq "Script")) {
    773         $login = "vmlogin";
    774         $dir = "pbdefdir";
    775         $tmout = "vmtmout";
    776         $rebuild = "vmrebuild";
    777         # Specific VM
    778         $host = "vmhost";
    779         $port = "vmport";
    780     } elsif ($cmt eq "ve") {
    781         $login = "velogin";
    782         $dir = "pbdefdir";
    783         $tmout = "vetmout";
    784         # Specific VE
    785         $path = "vepath";
    786         $conf = "veconf";
    787         $rebuild = "verebuild";
    788     }
    789     my $cmd = "";
    790 
    791     my $ptr = pb_get_pkg();
    792     @pkgs = @$ptr;
    793 
    794     # Get the running distro to consider
    795     my ($odir,$over,$oarch) = (undef, undef, undef);
    796     if (defined $v) {
    797         ($odir,$over,$oarch) = split(/-/,$v);
    798     }
    799     my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($odir,$over);
    800     pb_log(2,"DEBUG: distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n");
    801 
    802     # Get list of packages to build
    803     # Get content saved in cms2build
    804     my ($pkg) = pb_conf_read("$ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb","pbpkg");
    805     $pkg = { } if (not defined $pkg);
    806 
    807     my $src = "";
    808     chdir "$ENV{'PBBUILDDIR'}";
    809     foreach my $pbpkg (@pkgs) {
    810         my $vertag = $pkg->{$pbpkg};
    811         # get the version of the current package - maybe different
    812         ($pbver,$pbtag) = split(/-/,$vertag);
    813 
    814         if (($cmt eq "Sources") || ($cmt eq "vm") || ($cmt eq "ve")) {
    815             $src = "$src $ENV{'PBDESTDIR'}/$pbpkg-$pbver.tar.gz";
    816             if ($cmd eq "") {
    817                 $cmd = "ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
    818             } else {
    819                 $cmd = "$cmd ; ln -sf $pbpkg-$pbver.tar.gz $pbpkg-latest.tar.gz";
    820             }
    821         }
    822     }
    823     if (($cmt eq "vm") || ($cmt eq "ve")) {
    824         $src="$src $ENV{'PBDESTDIR'}/pbscript $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc";
    825     } elsif ($cmt eq "Script") {
    826         $src="$src $ENV{'PBDESTDIR'}/pbscript";
    827     } elsif ($cmt eq "Packages") {
    828         # Get package list from file made during build2pkg
    829         open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
    830         $src = <KEEP>;
    831         chomp($src);
    832         close(KEEP);
    833         if ($dtype eq "rpm") {
    834             # Also make a pbscript to generate yum/urpmi bases
    835             # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
    836         } elsif ($dtype eq "deb") {
    837             # Also make a pbscript to generate apt bases
    838             # $src = "$src $ENV{'PBDESTDIR'}/pbscript"
    839         }
    840     }
    841     # Remove potential leading spaces (cause problem with basename)
    842     $src =~ s/^ *//;
    843     my $basesrc = "";
    844     foreach my $i (split(/ +/,$src)) {
    845         $basesrc .= " ".basename($i);
    846     }
    847 
    848     pb_log(0,"Sources handled ($cmt): $src\n");
    849     pb_log(2,"values: ".Dumper(($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf))."\n");
    850     my ($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf) = pb_conf_get($host,$login,$dir,$port,$tmout,$rebuild,$path,$conf);
    851     pb_log(2,"ssh: ".Dumper(($sshhost,$sshlogin,$sshdir,$sshport,$vtmout,$vrebuild,$vepath,$veconf))."\n");
    852     # Not mandatory
    853     my ($testver) = pb_conf_get_if("testver");
    854 
    855     my $mac;
    856     # Useless for VE
    857     if ($cmt ne "ve") {
    858         $mac = "$sshlogin->{$ENV{'PBPROJ'}}\@$sshhost->{$ENV{'PBPROJ'}}";
    859         # Overwrite account value if passed as parameter
    860         $mac = "$pbaccount\@$sshhost->{$ENV{'PBPROJ'}}" if (defined $pbaccount);
    861         pb_log(2, "DEBUG: pbaccount: $pbaccount => mac: $mac\n") if (defined $pbaccount);
    862     }
    863 
    864     my $tdir;
    865     my $bdir;
    866     if (($cmt eq "Sources") || ($cmt eq "Script")) {
    867         $tdir = "$sshdir->{$ENV{'PBPROJ'}}/src";
    868     } elsif (($cmt eq "vm") || ($cmt eq "ve")) {
    869         $tdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/delivery";
    870         $bdir = $sshdir->{$ENV{'PBPROJ'}}."/$ENV{'PBPROJ'}/build";
    871         # Remove a potential $ENV{'HOME'} as bdir should be relative to pb's home
    872         $bdir =~ s|\$ENV.+\}/||;
    873     } elsif ($cmt eq "Packages") {
    874         $tdir = "$sshdir->{$ENV{'PBPROJ'}}/$ddir/$dver";
    875         if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
    876             # This is a test pkg => target dir is under test
    877             $tdir .= "/test";
    878         }
    879     } else {
    880         return;
    881     }
    882 
    883     # Useless for VE
    884     my $nport;
    885     if ($cmt ne "ve") {
    886         $nport = $sshport->{$ENV{'PBPROJ'}};
    887         $nport = "$pbport" if (defined $pbport);
    888     }
    889 
    890     # Remove a potential $ENV{'HOME'} as tdir should be relative to pb's home
    891     $tdir =~ s|\$ENV.+\}/||;
    892 
    893     my $tm = $vtmout->{$ENV{'PBPROJ'}};
    894 
    895     # ssh communication if not VE
    896     # should use a hash instead...
    897     my ($shcmd,$cpcmd,$cptarget,$cp2target);
    898     if ($cmt ne "ve") {
    899         my $keyfile = pb_ssh_get(0);
    900         $shcmd = "ssh -i $keyfile -q -p $nport $mac";
    901         $cpcmd = "scp -i $keyfile -p -P $nport";
    902         $cptarget = "$mac:$tdir";
    903         if ($cmt eq "vm") {
    904             $cp2target = "$mac:$bdir";
    905         }
    906     } else {
    907         my $tp = $vepath->{$ENV{'PBPROJ'}};
    908         $shcmd = "sudo chroot $tp/$v /bin/su - $sshlogin->{$ENV{'PBPROJ'}} -c ";
    909         $cpcmd = "cp -a ";
    910         $cptarget = "$tp/$tdir";
    911         $cp2target = "$tp/$bdir";
    912     }
    913 
    914     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");
    915     pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget");
    916     # For VE we need to change the owner manually - To be tested if needed
    917     #if ($cmt eq "ve") {
    918     #pb_system("cd $cptarget ; sudo chown -R $sshlogin->{$ENV{'PBPROJ'}} .","$cmt chown in $cptarget to $sshlogin->{$ENV{'PBPROJ'}}");
    919     #}
    920     pb_system("$shcmd \"echo \'cd $tdir ; if [ -f pbscript ]; then ./pbscript; fi\' | bash\"","Executing pbscript on $cptarget if needed");
    921     if (($cmt eq "vm") || ($cmt eq "ve")) {
    922         # Get back info on pkg produced, compute their name and get them from the VM
    923         pb_system("$cpcmd $cp2target/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'} $ENV{'PBBUILDDIR'} 2> /dev/null","Get package names in $cp2target");
    924         open(KEEP,"$ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to read $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
    925         my $src = <KEEP>;
    926         chomp($src);
    927         close(KEEP);
    928         $src =~ s/^ *//;
    929         pb_mkdir_p("$ENV{'PBBUILDDIR'}/$odir/$over");
    930         # Change pgben to make the next send2target happy
    931         my $made = "";
    932         open(KEEP,"> $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}") || die "Unable to write $ENV{'PBBUILDDIR'}/pbgen-$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}";
    933         foreach my $p (split(/ +/,$src)) {
    934             my $j = basename($p);
    935             pb_system("$cpcmd $cp2target/\'$p\' $ENV{'PBBUILDDIR'}/$odir/$over 2> /dev/null","Package recovery of $j in $cp2target");
    936             $made="$made $odir/$over/$j" if (($dtype ne "rpm") || ($j !~ /.src.rpm$/));
    937         }
    938         print KEEP "$made\n";
    939         close(KEEP);
    940         pb_system("$shcmd \"rm -rf $tdir $bdir\"","$cmt cleanup");
    941 
    942         # We want to send them to the ssh account so overwrite what has been done before
    943         undef $pbaccount;
    944         pb_log(2,"Before sending pkgs, vmexist: $vmexist, vmpid: $vmpid\n");
    945         pb_send2target("Packages",$odir."-".$over."-".$oarch,$vmexist,$vmpid);
    946         if ((! $vmexist) && ($cmt eq "vm")) {
    947             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)");
    948         }
    949         pb_rm_rf("$ENV{'PBBUILDDIR'}/$odir");
    950     }
    951 }
    952 
    953 sub pb_script2v {
    954     my $pbscript=shift;
    955     my $vtype=shift;
    956 
    957     # Prepare the script to be executed on the VM
    958     # in $ENV{'PBDESTDIR'}/pbscript
    959     if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript")) {
    960         copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
    961         chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
    962     }
    963 
    964     my ($vm,$all) = pb_get_v($vtype);
    965     my ($vmexist,$vmpid) = (undef,undef);
    966 
    967     foreach my $v (@$vm) {
    968         # Launch the VM/VE
    969         if ($vtype eq "vm") {
    970             ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
    971 
    972             # Skip that VM if something went wrong
    973             next if (($vmpid == 0) && ($vmexist ==0));
    974         }
    975 
    976         # Gather all required files to send them to the VM
    977         # and launch the build through pbscript
    978         pb_send2target("Script","$v",$vmexist,$vmpid);
    979 
    980     }
    981 }
    982 
    983 sub pb_launchv {
    984     my $vtype = shift;
    985     my $v = shift;
    986     my $create = shift || 0;        # By default do not create a VM
    987 
    988     die "No VM/VE defined, unable to launch" if (not defined $v);
    989     # Keep only the first VM in case many were given
    990     $v =~ s/,.*//;
    991 
    992     # Which is our local arch ? (standardize on i386 for those platforms)
    993     my $arch = `uname -m`;
    994     chomp($arch);
    995     $arch =~ s/i.86/i386/;
    996 
    997     # Launch the VMs/VEs
    998     if ($vtype eq "vm") {
    999         die "-i iso parameter needed" if (((not defined $iso) || ($iso eq "")) && ($create != 0));
    1000 
    1001         my ($ptr,$vmopt,$vmport,$vmpath,$vmtmout,$vmsize) = pb_conf_get("vmtype","vmopt","vmport","vmpath","vmtmout","vmsize");
    1002 
    1003         my $vmtype = $ptr->{$ENV{'PBPROJ'}};
    1004         if (not defined $ENV{'PBVMOPT'}) {
    1005             $ENV{'PBVMOPT'} = "";
    1006         }
    1007         if (defined $vmopt->{$ENV{'PBPROJ'}}) {
    1008             $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/);
    1009         }
    1010         my $nport = $vmport->{$ENV{'PBPROJ'}};
    1011         $nport = "$pbport" if (defined $pbport);
    1012    
    1013         my $cmd;
    1014         my $vmcmd;      # has to be used for pb_check_ps
    1015         my $vmm;        # has to be used for pb_check_ps
    1016         if ($vmtype eq "qemu") {
    1017             my $qemucmd32;
    1018             my $qemucmd64;
    1019             if ($arch eq "x86_64") {
    1020                 $qemucmd32 = "/usr/bin/qemu-system-i386";
    1021                 $qemucmd64 = "/usr/bin/qemu";
    1022             } else {
    1023                 $qemucmd32 = "/usr/bin/qemu";
    1024                 $qemucmd64 = "/usr/bin/qemu-system-x86_64";
    1025             }
    1026         if ($v =~ /x86_64/) {
    1027                 $vmcmd = "$qemucmd64 -no-kqemu";
    1028             } else {
    1029                 $vmcmd = "$qemucmd32";
    1030             }
    1031             $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu";
    1032             if ($create != 0) {
    1033                 $ENV{'PBVMOPT'} .= " -cdrom $iso -boot d";
    1034             }
    1035             $cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm"
    1036         } elsif ($vmtype eq "xen") {
    1037         } elsif ($vmtype eq "vmware") {
    1038         } else {
    1039             die "VM of type $vmtype not supported. Report to the dev team";
    1040         }
    1041         my ($tmpcmd,$void) = split(/ +/,$cmd);
    1042         my $vmexist = pb_check_ps($tmpcmd,$vmm);
    1043         my $vmpid = 0;
    1044         if (! $vmexist) {
    1045             if ($create != 0) {
    1046                 if (($vmtype eq "qemu") || ($vmtype eq "xen")) {
    1047                     pb_system("/usr/bin/qemu-img create -f qcow2 $vmm $vmsize->{$ENV{'PBPROJ'}}","Creating the QEMU VM");
    1048                 } elsif ($vmtype eq "vmware") {
    1049                 } else {
    1050                 }
    1051             }
    1052             if (! -f "$vmm") {
    1053                 pb_log(0,"Unable to find VM $vmm\n");
    1054             } else {
    1055                 pb_system("$cmd &","Launching the VM $vmm");
    1056                 pb_system("sleep $vmtmout->{$ENV{'PBPROJ'}}","Waiting for VM $v to come up");
    1057                 $vmpid = pb_check_ps($tmpcmd,$vmm);
    1058                 pb_log(0,"VM $vmm launched (pid $vmpid)\n");
    1059             }
    1060         } else {
    1061             pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n");
    1062         }
    1063         return($vmexist,$vmpid);
    1064     # VE here
    1065     } else {
    1066         # Get VE context
    1067         my ($ptr,$vepath,$vetmout,$verebuild,$veconf) = pb_conf_get("vetype","vepath","vetmout","verebuild","veconf");
    1068         my $vetype = $ptr->{$ENV{'PBPROJ'}};
    1069 
    1070         # Get distro context
    1071         my ($name,$ver,$darch) = split(/-/,$v);
    1072         chomp($darch);
    1073         my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($name,$ver);
    1074 
    1075         if ($vetype eq "chroot") {
    1076             # Architecture consistency
    1077             if ($arch ne $darch) {
    1078                 die "Unable to launch a VE of architecture $darch on a $arch platform" if (not (($darch eq "x86_64") && ($arch =~ /i?86/)));
    1079             }
    1080 
    1081             if (($create != 0) || ($verebuild->{$ENV{'PBPROJ'}} eq "true") || ($force == 1)) {
    1082                 # We have to rebuild the chroot
    1083                 if ($dtype eq "rpm") {
    1084                     pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
    1085                     # Once setup we need to install some packages, the pb account, ...
    1086                     pb_system("sudo /usr/sbin/mock --install --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
    1087                     #pb_system("sudo /usr/sbin/mock --init --resultdir=\"/tmp\" --configdir=\"$veconf->{$ENV{'PBPROJ'}}\" --basedir=\"$vepath->{$ENV{'PBPROJ'}}\" -r $v","Creating the mock VE");
    1088                 } elsif ($dtype eq "deb") {
    1089                     pb_system("","Creating the pbuilder VE");
    1090                 } elsif ($dtype eq "ebuild") {
    1091                     die "Please teach the dev team how to build gentoo chroot";
    1092                 } else {
    1093                     die "Unknown distribution type $dtype. Report to dev team";
    1094                 }
    1095             }
    1096             # Nothing more to do for VE. No real launch
    1097         } else {
    1098             die "VE of type $vetype not supported. Report to the dev team";
    1099         }
    1100     }
    1101 }
    1102 
    1103 sub pb_build2v {
    1104 
    1105 my $vtype = shift;
    1106 
    1107 # Prepare the script to be executed on the VM/VE
    1108 # in $ENV{'PBDESTDIR'}/pbscript
    1109 #my ($ntp) = pb_conf_get($vtype."ntp");
    1110 #my $vntp = $ntp->{$ENV{'PBPROJ'}};
    1111 
    1112 open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript";
    1113 print SCRIPT "#!/bin/bash\n";
    1114 print SCRIPT "echo ... Execution needed\n";
    1115 print SCRIPT "# This is in directory delivery\n";
    1116 print SCRIPT "# Setup the variables required for building\n";
    1117 print SCRIPT "export PBPROJ=$ENV{'PBPROJ'}\n";
    1118 print SCRIPT "# Preparation for pb\n";
    1119 print SCRIPT "mv .pbrc \$HOME\n";
    1120 print SCRIPT "cd ..\n";
    1121 # Force new date to be in the future compared to the date of the tar file by adding 1 minute
    1122 my @date=pb_get_date();
    1123 $date[1]++;
    1124 my $upddate = strftime("%m%d%H%M%Y", @date);
    1125 #print SCRIPT "echo Setting up date on $vntp...\n";
    1126 # Or use ntpdate if available TBC
    1127 print SCRIPT "sudo date $upddate\n";
    1128 # Get list of packages to build and get some ENV vars as well
    1129 my $ptr = pb_get_pkg();
    1130 @pkgs = @$ptr;
    1131 my $p = join(' ',@pkgs) if (@pkgs);
    1132 print SCRIPT "export PBPROJVER=$ENV{'PBPROJVER'}\n";
    1133 print SCRIPT "export PBPROJTAG=$ENV{'PBPROJTAG'}\n";
    1134 print SCRIPT "export PBPACKAGER=\"$ENV{'PBPACKAGER'}\"\n";
    1135 print SCRIPT "# Build\n";
    1136 print SCRIPT "echo Building packages on $vtype...\n";
    1137 print SCRIPT "pb -p $ENV{'PBPROJ'} build2pkg $p\n";
    1138 close(SCRIPT);
    1139 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript";
    1140 
    1141 my ($v,$all) = pb_get_v($vtype);
    1142 
    1143 # Send tar files when we do a global generation
    1144 pb_build2ssh() if ($all == 1);
    1145 
    1146 my ($vmexist,$vmpid) = (undef,undef);
    1147 
    1148 foreach my $v (@$v) {
    1149     if ($vtype eq "vm") {
    1150         # Launch the VM
    1151         ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
    1152 
    1153         # Skip that VM if it something went wrong
    1154         next if (($vmpid == 0) && ($vmexist == 0));
    1155     }
    1156     # Gather all required files to send them to the VM/VE
    1157     # and launch the build through pbscript
    1158     pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");
    1159     pb_send2target($vtype,"$v",$vmexist,$vmpid);
    1160 }
    1161 }
    1162 
    1163 
    1164 sub pb_newver {
    1165 
    1166     die "-V Version parameter needed" if ((not defined $newver) || ($newver eq ""));
    1167 
    1168     # Need this call for PBDIR
    1169     my ($scheme2,$uri) = pb_cms_init($pbinit);
    1170 
    1171     my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
    1172     $uri = $pbconf->{$ENV{'PBPROJ'}};
    1173     my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
    1174 
    1175     # Checking CMS repositories status
    1176     my ($pburl) = pb_conf_get("pburl");
    1177     ($scheme2, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
    1178 
    1179     if ($scheme !~ /^svn/) {
    1180         die "Only SVN is supported at the moment";
    1181     }
    1182     my $res = pb_cms_isdiff($scheme,$ENV{'PBROOTDIR'});
    1183     die "ERROR: No differences accepted in CMS for $ENV{'PBROOTDIR'} before creating a new version" if ($res != 0);
    1184 
    1185     $res = pb_cms_isdiff($scheme2,$ENV{'PBDIR'});
    1186     die "ERROR: No differences accepted in CMS for $ENV{'PBDIR'} before creating a new version" if ($res != 0);
    1187 
    1188     # Tree identical between PBCONFDIR and PBROOTDIR. The delta is what
    1189     # we want to get for the root of the new URL
    1190 
    1191     my $tmp = $ENV{'PBROOTDIR'};
    1192     $tmp =~ s|^$ENV{'PBCONFDIR'}||;
    1193 
    1194     my $newurl = "$uri/".dirname($tmp)."/$newver";
    1195     # Should probably use projver in the old file
    1196     my $oldver= basename($tmp);
    1197 
    1198     # Checking pbcl files
    1199     foreach my $f (<$ENV{'PBROOTDIR'}/*/pbcl>) {
    1200         open(PBCL,$f) || die "Unable to open $f";
    1201         my $foundnew = 0;
    1202         while (<PBCL>) {
    1203             $foundnew = 1 if (/^$newver \(/);
    1204         }
    1205         close(PBCL);
    1206         die "ERROR: version $newver not found in $f" if ($foundnew == 0);
    1207     }
    1208 
    1209     # Duplicate and extract project-builder part
    1210     pb_log(2,"Copying $uri/$tmp to $newurl\n");
    1211     pb_cms_copy($scheme,"$uri/$tmp",$newurl);
    1212     pb_log(2,"Checkout $newurl to $ENV{'PBROOTDIR'}/../$newver\n");
    1213     pb_cms_up($scheme,"$ENV{'PBCONFDIR'}/..");
    1214 
    1215     # Duplicate and extract project
    1216     my $newurl2 = "$pburl->{$ENV{'PBPROJ'}}/".dirname($tmp)."/$newver";
    1217 
    1218     pb_log(2,"Copying $pburl->{$ENV{'PBPROJ'}}/$tmp to $newurl2\n");
    1219     pb_cms_copy($scheme,"$pburl->{$ENV{'PBPROJ'}}/$tmp",$newurl2);
    1220     pb_log(2,"Checkout $newurl2 to $ENV{'PBDIR'}/../$newver\n");
    1221     pb_cms_up($scheme,"$ENV{'PBDIR'}/..");
    1222 
    1223     # Update the .pb file
    1224     open(FILE,"$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb") || die "Unable to open $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb";
    1225     open(OUT,"> $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new") || die "Unable to write to $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new";
    1226     while(<FILE>) {
    1227         s/^projver\s+$ENV{'PBPROJ'}\s*=\s*$oldver/projver $ENV{'PBPROJ'} = $newver/;
    1228         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/);
    1229         s/^testver/#testver/;
    1230         pb_log(0,"Commenting testver in $ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb\n") if (/^testver/);
    1231         print OUT $_;
    1232     }
    1233     close(FILE);
    1234     close(OUT);
    1235     rename("$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb.new","$ENV{'PBROOTDIR'}/../$newver/$ENV{'PBPROJ'}.pb");
    1236 
    1237     pb_log(2,"Checkin $ENV{'PBROOTDIR'}/../$newver\n");
    1238     pb_cms_checkin($scheme,"$ENV{'PBROOTDIR'}/../$newver");
    1239 }
    1240 
    1241 #
    1242 # Return the list of VMs/VEs we are working on
    1243 # $all is a flag to know if we return all of them
    1244 # or only some (if all we publish also tar files in addition to pkgs
    1245 #
    1246 sub pb_get_v {
    1247 
    1248 my $vtype = shift;
    1249 my @v;
    1250 my $all = 0;
    1251 my $vlist;
    1252 my $pbv = 'PBV';
    1253 
    1254 if ($vtype eq "vm") {
    1255     $vlist = "vmlist";
    1256 } elsif ($vtype eq "ve") {
    1257     $vlist = "velist";
    1258 }
    1259 # Get VM/VE list
    1260 if ((not defined $ENV{$pbv}) || ($ENV{$pbv} =~ /^all$/)) {
    1261     my ($ptr) = pb_conf_get($vlist);
    1262     $ENV{$pbv} = $ptr->{$ENV{'PBPROJ'}};
    1263     $all = 1;
    1264 }
    1265 pb_log(2,"$vtype: $ENV{$pbv}\n");
    1266 @v = split(/,/,$ENV{$pbv});
    1267 return(\@v,$all);
    1268 }
    1269 
    1270 # Function to create a potentialy missing pb account on the VM/VE, and adds it to sudo
    1271 # Needs to use root account to connect to the VM/VE
    1272 # pb will take your local public SSH key to access
    1273 # the pb account in the VM later on if needed
    1274 sub pb_setup_v {
    1275 
    1276 my $vtype = shift;
    1277 
    1278 my ($vm,$all) = pb_get_v($vtype);
    1279 
    1280 # Script generated
    1281 my $pbscript = "$ENV{'PBDESTDIR'}/setupv";
    1282 
    1283 foreach my $v (@$vm) {
    1284     # Name of the account to deal with for VM/VE
    1285     # Do not use the one passed potentially with -a
    1286     my ($pbac) = pb_conf_get($vtype."login");
    1287     my ($key,$zero0,$zero1,$zero2);
    1288     my ($vmexist,$vmpid);
    1289 
    1290     if ($vtype eq "vm") {
    1291         # Prepare the key to be used and transfered remotely
    1292         my $keyfile = pb_ssh_get(1);
    1293        
    1294         my ($vmhost,$vmport) = pb_conf_get("vmhost","vmport");
    1295         my $nport = $vmport->{$ENV{'PBPROJ'}};
    1296         $nport = "$pbport" if (defined $pbport);
    1297    
    1298         # Launch the VM
    1299         ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);
    1300 
    1301         # Skip that VM if something went wrong
    1302         return if (($vmpid == 0) && ($vmexist == 0));
    1303    
    1304         # Store the pub key part in a variable
    1305         open(FILE,"$keyfile.pub") || die "Unable to open $keyfile.pub";
    1306         ($zero0,$zero1,$zero2) = split(/ /,<FILE>);
    1307         close(FILE);
    1308 
    1309         $key = "\Q$zero1";
    1310 
    1311         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");
    1312         # once this is done, we can do what we want on the VM remotely
    1313     }
    1314    
    1315     # Prepare the script to be executed on the VM/VE
    1316     # in $ENV{'PBDESTDIR'}/setupv
    1317    
    1318     open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript";
    1319     print SCRIPT << 'EOF';
    1320 #!/usr/bin/perl -w
    1321 
    1322 use strict;
    1323 use File::Copy;
    1324 
    1325 EOF
    1326     if ($vtype eq "vm") {
    1327         print SCRIPT << 'EOF';
    1328 # Removes duplicate in .ssh/authorized_keys of our key if needed
    1329 #
    1330 my $file1="$ENV{'HOME'}/.ssh/authorized_keys";
    1331 open(PBFILE,$file1) || die "Unable to open $file1";
    1332 open(PBOUT,"> $file1.new") || die "Unable to open $file1.new";
    1333 my $count = 0;
    1334 while (<PBFILE>) {
    1335 EOF
    1336         print SCRIPT << "EOF";
    1337     if (/ $key /) {
    1338         \$count++;
    1339     }
    1340 print PBOUT \$_ if ((\$count <= 1) || (\$_ !~ / $key /));
    1341 }
    1342 close(PBFILE);
    1343 close(PBOUT);
    1344 rename("\$file1.new",\$file1);
    1345 chmod 0600,\$file1;
    1346 EOF
    1347     }
    1348     print SCRIPT << 'EOF';
    1349 
    1350 # Adds $pbac->{$ENV{'PBPROJ'}} as an account if needed
    1351 #
    1352 my $file="/etc/passwd";
    1353 open(PBFILE,$file) || die "Unable to open $file";
    1354 my $found = 0;
    1355 while (<PBFILE>) {
    1356 EOF
    1357     print SCRIPT << "EOF";
    1358     \$found = 1 if (/^$pbac->{$ENV{'PBPROJ'}}:/);
    1359 EOF
    1360     print SCRIPT << 'EOF';
    1361 }
    1362 close(PBFILE);
    1363 
    1364 if ( $found == 0 ) {
    1365     if ( ! -d "/home" ) {
    1366         mkdir "/home";
    1367     }
    1368 EOF
    1369     print SCRIPT << "EOF";
    1370 system "groupadd $pbac->{$ENV{'PBPROJ'}}";
    1371 system "useradd $pbac->{$ENV{'PBPROJ'}} -g $pbac->{$ENV{'PBPROJ'}} -m -d /home/$pbac->{$ENV{'PBPROJ'}}";
    1372 
    1373 # allow ssh entry to build
    1374 #
    1375 chdir "/home/$pbac->{$ENV{'PBPROJ'}}";
    1376 mkdir ".ssh",0700;
    1377 # Allow those accessing root to access the build account
    1378 copy("\$ENV{'HOME'}/.ssh/authorized_keys",".ssh/authorized_keys");
    1379 chmod 0600,".ssh/authorized_keys";
    1380 system 'chown -R $pbac->{$ENV{'PBPROJ'}}:$pbac->{$ENV{'PBPROJ'}} .ssh';
    1381 
    1382 EOF
    1383     print SCRIPT << 'EOF';
    1384 }
    1385 
    1386 # No passwd for build account only keys
    1387 $file="/etc/shadow";
    1388 open(PBFILE,$file) || die "Unable to open $file";
    1389 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
    1390 while (<PBFILE>) {
    1391 EOF
    1392     print SCRIPT << "EOF";
    1393     s/^$pbac->{$ENV{'PBPROJ'}}:\!\!:/$pbac->{$ENV{'PBPROJ'}}:*:/;
    1394     s/^$pbac->{$ENV{'PBPROJ'}}:\!:/$pbac->{$ENV{'PBPROJ'}}:*:/; #SLES 9 e.g.
    1395 EOF
    1396     print SCRIPT << 'EOF';
    1397     print PBOUT $_;
    1398 }
    1399 close(PBFILE);
    1400 close(PBOUT);
    1401 rename("$file.new",$file);
    1402 chmod 0640,$file;
    1403 
    1404 # pb has to be added to portage group on gentoo
    1405 
    1406 # Adapt sudoers
    1407 $file="/etc/sudoers";
    1408 open(PBFILE,$file) || die "Unable to open $file";
    1409 open(PBOUT,"> $file.new") || die "Unable to open $file.new";
    1410 while (<PBFILE>) {
    1411 EOF
    1412     print SCRIPT << "EOF";
    1413     next if (/^$pbac->{$ENV{'PBPROJ'}}   /);
    1414 EOF
    1415     print SCRIPT << 'EOF';
    1416     s/Defaults[ \t]+requiretty//;
    1417     print PBOUT $_;
    1418 }
    1419 close(PBFILE);
    1420 EOF
    1421     print SCRIPT << "EOF";
    1422 # This is needed in order to be able to halt the machine from the $pbac->{$ENV{'PBPROJ'}} account at least
    1423 print PBOUT "$pbac->{$ENV{'PBPROJ'}}   ALL=(ALL) NOPASSWD:ALL\n";
    1424 EOF
    1425     print SCRIPT << 'EOF';
    1426 close(PBOUT);
    1427 rename("$file.new",$file);
    1428 chmod 0440,$file;
    1429 
    1430 EOF
    1431        
    1432     my $SCRIPT = \*SCRIPT;
    1433    
    1434     pb_install_deps($SCRIPT);
    1435    
    1436     print SCRIPT << 'EOF';
    1437 # Suse wants sudoers as 640
    1438 if (($ddir eq "sles") || (($ddir eq "suse")) && ($dver ne "10.3")) {
    1439     chmod 0640,$file;
    1440 }
    1441 
    1442 # Sync date
    1443 #system "/usr/sbin/ntpdate ntp.pool.org";
    1444 
    1445 system "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-*";
    1446 system "pb 2>&1 | head -5";
    1447 EOF
    1448     if ((! $vmexist) && ($vtype eq "vm")) {
    1449         print SCRIPT << 'EOF';
    1450 system "sudo /sbin/halt -p";
    1451 EOF
    1452     }
    1453    
    1454     # Adds pb_distro_init from ProjectBuilder::Distribution
    1455     foreach my $d (@INC) {
    1456         my $f = "$d/ProjectBuilder/Distribution.pm";
    1457         if (-f "$f") {
    1458             open(PBD,"$f") || die "Unable to open $f";
    1459             while (<PBD>) {
    1460                 next if (/^package/);
    1461                 next if (/^use Exporter/);
    1462                 next if (/^\@our /);
    1463                 print SCRIPT $_;
    1464             }
    1465             close(PBD);
    1466             last;
    1467         }
    1468     }
    1469     close(SCRIPT);
    1470     chmod 0755,"$pbscript";
    1471 
    1472     # That build script needs to be run as root
    1473     $pbaccount = "root";
    1474     pb_script2v($pbscript,$vtype);
    1475 }
    1476 return;
    1477 }
    1478 
    1479 sub pb_install_deps {
    1480 
    1481 my $SCRIPT = shift;
    1482 
    1483 print {$SCRIPT} << 'EOF';
    1484 # We need to have that pb_distro_init function
    1485 # Get it from Project-Builder::Distribution
    1486 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
    1487 print "distro tuple: ".join(',',($ddir, $dver, $dfam, $dtype, $pbsuf))."\n";
    1488 
    1489 # Get and install pb
    1490 my $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*";
    1491 my $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*";
    1492 my $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*";
    1493 my $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*";
    1494 
    1495 if ( $ddir eq "fedora" ) {
    1496     system "yum clean all";
    1497     #system "yum update -y";
    1498     my $arch=`uname -m`;
    1499     my $opt = "";
    1500     chomp($arch);
    1501     if ($arch eq "x86_64") {
    1502         $opt="--exclude=*.i?86";
    1503     }
    1504 
    1505     system "yum -y $opt install rpm-build wget patch ntp sudo perl-DateManip perl-File-MimeInfo perl-ExtUtils-MakeMaker";
    1506     if ($dver eq 4) {
    1507         system "$insmb";
    1508         system "$insfm";
    1509         system "$insfb";
    1510     }
    1511 } elsif (( $dfam eq "rh" ) || ($ddir eq "sles") || (($ddir eq "suse") && (($dver eq "10.1") || ($dver eq "10.0"))) || ($ddir eq "slackware")) {
    1512     # Suppose pkg are installed already as no online mirror available
    1513     system "rpm -e lsb 2>&1 > /dev/null";
    1514     system "$insdm";
    1515     system "$insmb";
    1516     system "$insfm";
    1517     system "$insfb";
    1518 } elsif ($ddir eq "suse") {
    1519     # New OpenSuSE
    1520     system "$insmb";
    1521     system "$insfm";
    1522     system "$insfb";
    1523     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";
    1524 } elsif ( $dfam eq "md" ) {
    1525         system "urpmi.update -a ; urpmi --auto rpm-build wget sudo patch ntp-client perl-File-MimeInfo";
    1526         if (($ddir eq "mandrake") && ($dver eq "10.1")) {
    1527             system "$insdm";
    1528         } else {
    1529             system "urpmi --auto perl-DateManip";
    1530         }
    1531 } elsif ( $dfam eq "du" ) {
    1532     if (( $dver eq "3.1" ) && ($ddir eq "debian")) {
    1533         #system "apt-get update";
    1534         system "$insfb";
    1535         system "$insfm";
    1536         system "apt-get -y install wget patch ssh sudo debian-builder dh-make fakeroot ntpdate libmodule-build-perl libdate-manip-perl";
    1537     } else  {
    1538         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";
    1539     }
    1540 } elsif ( $dfam eq "gen" ) {
    1541         #system "emerge -u system ; emerge wget sudo ntp DateManip File-MimeInfo";
    1542         system "emerge wget sudo ntp DateManip File-MimeInfo";
    1543 } else {
    1544     print "No pkg to install\n";
    1545 }
    1546 EOF
    1547 }
    1548 
    1549 # Return the SSH key file to use
    1550 # Potentially create it if needed
    1551 
    1552 sub pb_ssh_get {
    1553 
    1554 my $create = shift || 0;    # Do not create keys by default
    1555 
    1556 # Check the SSH environment
    1557 my $keyfile = undef;
    1558 
    1559 # We have specific keys by default
    1560 $keyfile = "$ENV{'HOME'}/.ssh/pb_dsa";
    1561 if (!(-e $keyfile) && ($create eq 1)) {
    1562     pb_system("ssh-keygen -q -b 1024 -N '' -f $keyfile -t dsa","Generating SSH keys for pb");
    1563 }
    1564 
    1565 $keyfile = "$ENV{'HOME'}/.ssh/id_rsa" if (-s "$ENV{'HOME'}/.ssh/id_rsa");
    1566 $keyfile = "$ENV{'HOME'}/.ssh/id_dsa" if (-s "$ENV{'HOME'}/.ssh/id_dsa");
    1567 $keyfile = "$ENV{'HOME'}/.ssh/pb_dsa" if (-s "$ENV{'HOME'}/.ssh/pb_dsa");
    1568 die "Unable to find your public ssh key under $keyfile" if (not defined $keyfile);
    1569 return($keyfile);
    1570 }
    1571 
    1572 
    1573 # Returns the pid of a running VM command using a specific VM file
    1574 sub pb_check_ps {
    1575     my $vmcmd = shift;
    1576     my $vmm = shift;
    1577     my $vmexist = 0;        # FALSE by default
    1578 
    1579     open(PS, "ps auxhww|") || die "Unable to call ps";
    1580     while (<PS>) {
    1581         next if (! /$vmcmd/);
    1582         next if (! /$vmm/);
    1583         my ($void1, $void2);
    1584         ($void1, $vmexist, $void2) = split(/ +/);
    1585         last;
    1586     }
    1587     return($vmexist);
    1588 }
    1589 
    1590 
    1591 sub pb_extract_build_files {
    1592 
    1593 my $src=shift;
    1594 my $dir=shift;
    1595 my $ddir=shift;
    1596 my @files;
    1597 
    1598 if ($src =~ /tar\.gz$/) {
    1599     pb_system("tar xfpz $src $dir","Extracting build files");
    1600 } elsif ($src =~ /tar\.bz2$/) {
    1601     pb_system("tar xfpj $src $dir","Extracting build files");
    1602 } else {
    1603     die "Unknown compression algorithm for $src";
    1604 }
    1605 opendir(DIR,"$dir") || die "Unable to open directory $dir";
    1606 foreach my $f (readdir(DIR)) {
    1607     next if ($f =~ /^\./);
    1608     move("$dir/$f","$ddir") || die "Unable to move $dir/$f to $ddir";
    1609     pb_log(2,"mv $dir/$f $ddir\n");
    1610     push @files,"$ddir/$f";
    1611 }
    1612 closedir(DIR);
    1613 # Not enough but still a first cleanup
    1614 pb_rm_rf("$dir");
    1615 return(@files);
    1616 }
    1617 
    1618 sub pb_list_bfiles {
    1619 
    1620 my $dir = shift;
    1621 my $pbpkg = shift;
    1622 my $bfiles = shift;
    1623 my $pkgfiles = shift;
    1624 my $supfiles = shift;
    1625 
    1626 opendir(BDIR,"$dir") || die "Unable to open dir $dir: $!";
    1627 foreach my $f (readdir(BDIR)) {
    1628     next if ($f =~ /^\./);
    1629     $bfiles->{$f} = "$dir/$f";
    1630     $bfiles->{$f} =~ s~$ENV{'PBROOTDIR'}~~;
    1631     if (defined $supfiles->{$pbpkg}) {
    1632         $pkgfiles->{$f} = "$dir/$f" if ($f =~ /$supfiles->{$pbpkg}/);
    1633     }
    1634 }
    1635 closedir(BDIR);
    1636 }
    1637 
    1638 sub pb_env_init {
    1639 
    1640 my $proj=shift || undef;
    1641 my $pbinit=shift || undef;
    1642 my $action=shift;
    1643 my $ver;
    1644 my $tag;
    1645 
    1646 $ENV{'PBETC'} = "$ENV{'HOME'}/.pbrc";
    1647 
    1648 #
    1649 # Check project name
    1650 # Could be with env var PBPROJ
    1651 # or option -p
    1652 # if not define take the first in conf file
    1653 #
    1654 if ((defined $ENV{'PBPROJ'}) &&
    1655     (not (defined $proj))) {
    1656     $proj = $ENV{'PBPROJ'};
    1657 }
    1658 
    1659 #
    1660 # We get the pbconf file for that project
    1661 # and use its content
    1662 #
    1663 my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
    1664 pb_log(2,"DEBUG pbconfurl: ".Dumper($pbconf)."\n");
    1665 
    1666 my %pbconf = %$pbconf;
    1667 if (not defined $proj) {
    1668     # Take the first as the default project
    1669     $proj = (keys %pbconf)[0];
    1670     if (defined $proj) {
    1671         pb_log(1,"WARNING: using $proj as default project as none has been specified\n");
    1672         pb_log(1,"         Please either create a pbconfurl reference for project $proj in $ENV{'PBETC'}\n");
    1673         pb_log(1,"         or call pb with the -p project option or use the env var PBPROJ\n");
    1674         pb_log(1,"         if you want to use another project\n");
    1675     }
    1676 }
    1677 die "No project defined - use env var PBPROJ or -p proj or a pbconfurl entry in $ENV{'PBETC'}" if (not (defined $proj));
    1678 
    1679 # That's always the environment variable that will be used
    1680 $ENV{'PBPROJ'} = $proj;
    1681 pb_log(2,"PBPROJ: $ENV{'PBPROJ'}\n");
    1682 
    1683 if (not defined ($pbconf{$ENV{'PBPROJ'}})) {
    1684     die "Please create a pbconfurl reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n";
    1685 }
    1686 
    1687 #
    1688 # Detect the root dir for hosting all the content generated with pb
    1689 #
    1690 # Tree will look like this:
    1691 #
    1692 #             maint pbdefdir                         PBDEFDIR            dev dir (optional)
    1693 #                  |                                                        |
    1694 #            ------------------------                                --------------------
    1695 #            |                      |                                |                  |
    1696 #         pbproj1                pbproj2             PBPROJ       pbproj1           pbproj2   PBPROJDIR
    1697 #            |                                                       |
    1698 #  ---------------------------------------------                ----------
    1699 #  *      *        *       |        |          |                *        *
    1700 # tag    dev    pbconf    ...     build     delivery PBCONFDIR dev      tag                 
    1701 #  |               |                           |     PBDESTDIR           |
    1702 #  ---          ------                        pbrc   PBBUILDDIR       -------
    1703 #    |          |    |                                                |     |
    1704 #   1.1        dev  tag                                              1.0   1.1                PBDIR
    1705 #                    |
    1706 #                 -------
    1707 #                 |     |
    1708 #                1.0   1.1                           PBROOTDIR
    1709 #                       |
    1710 #               ----------------------------------
    1711 #               |          |           |         |
    1712 #             pkg1      pbproj1.pb   pbfilter   pbcl
    1713 #               |
    1714 #        -----------------
    1715 #        |      |        |
    1716 #       rpm    deb    pbfilter
    1717 #
    1718 #
    1719 # (*) By default, if no relocation in .pbrc, dev dir is taken in the maint pbdefdir (when appropriate)
    1720 # Names under a pbproj and the corresponding pbconf should be similar
    1721 #
    1722 
    1723 my ($pbdefdir) = pb_conf_get_if("pbdefdir");
    1724 
    1725 if (not defined $ENV{'PBDEFDIR'}) {
    1726     if ((not defined $pbdefdir) || (not defined $pbdefdir->{$ENV{'PBPROJ'}})) {
    1727         pb_log(1,"WARNING: no pbdefdir defined, using /var/cache\n");
    1728         pb_log(1,"         Please create a pbdefdir reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
    1729         pb_log(1,"         if you want to use another directory\n");
    1730         $ENV{'PBDEFDIR'} = "/var/cache";
    1731     } else {
    1732         # That's always the environment variable that will be used
    1733         $ENV{'PBDEFDIR'} = $pbdefdir->{$ENV{'PBPROJ'}};
    1734     }
    1735 }
    1736 # Expand potential env variable in it
    1737 eval { $ENV{'PBDEFDIR'} =~ s/(\$ENV.+\})/$1/eeg };
    1738 
    1739 pb_log(2,"PBDEFDIR: $ENV{'PBDEFDIR'}\n");
    1740 #
    1741 # Set delivery directory
    1742 #
    1743 $ENV{'PBDESTDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/delivery";
    1744 
    1745 pb_log(2,"PBDESTDIR: $ENV{'PBDESTDIR'}\n");
    1746 #
    1747 # Removes all directory existing below the delivery dir
    1748 # as they are temp dir only
    1749 # Files stay and have to be cleaned up manually if needed
    1750 # those files serves as communication channels between pb phases
    1751 # Removing them prevents a following phase to detect what has been done before
    1752 #
    1753 if (-d $ENV{'PBDESTDIR'}) {
    1754     opendir(DIR,$ENV{'PBDESTDIR'}) || die "Unable to open directory $ENV{'PBDESTDIR'}: $!";
    1755     foreach my $d (readdir(DIR)) {
    1756         next if ($d =~ /^\./);
    1757         next if (-f "$ENV{'PBDESTDIR'}/$d");
    1758         pb_rm_rf("$ENV{'PBDESTDIR'}/$d") if (-d "$ENV{'PBDESTDIR'}/$d");
    1759     }
    1760     closedir(DIR);
    1761 }
    1762 if (! -d "$ENV{'PBDESTDIR'}") {
    1763     pb_mkdir_p($ENV{'PBDESTDIR'}) || die "Unable to recursively create $ENV{'PBDESTDIR'}";
    1764 }
    1765 
    1766 #
    1767 # Set build directory
    1768 #
    1769 $ENV{'PBBUILDDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/build";
    1770 if (! -d "$ENV{'PBBUILDDIR'}") {
    1771     pb_mkdir_p($ENV{'PBBUILDDIR'}) || die "Unable to recursively create $ENV{'PBBUILDDIR'}";
    1772 }
    1773 
    1774 pb_log(2,"PBBUILDDIR: $ENV{'PBBUILDDIR'}\n");
    1775 
    1776 pb_temp_init();
    1777 pb_log(2,"PBTMP: $ENV{'PBTMP'}\n");
    1778 
    1779 #
    1780 # The following part is only useful when in cms2something of newver
    1781 # In VMs/VEs we want to skip that by providing good env vars.
    1782 # return values in that case are useless
    1783 #
    1784 if (($action =~ /^cms2/) || ($action =~ /^newver$/)) {
    1785 
    1786     #
    1787     # Check pbconf cms compliance
    1788     #
    1789     pb_cms_compliant("pbconfdir",'PBCONFDIR',"$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/pbconf",$pbconf{$ENV{'PBPROJ'}},$pbinit);
    1790 
    1791     # Check where is our PBROOTDIR (release tag name can't be guessed the first time)
    1792     #
    1793     if (not defined $ENV{'PBROOTDIR'}) {
    1794         if (! -f ("$ENV{'PBDESTDIR'}/pbrc")) {
    1795             opendir(DIR,$ENV{'PBCONFDIR'}) || die "Unable to open directory $ENV{'PBCONFDIR'}: $!";
    1796             my $maxmtime = 0;
    1797             foreach my $d (readdir(DIR)) {
    1798                 pb_log(3,"Looking at \'$d\'...");
    1799                 next if ($d =~ /^\./);
    1800                 next if (! -d "$ENV{'PBCONFDIR'}/$d");
    1801                 my $s = stat("$ENV{'PBCONFDIR'}/$d");
    1802                 next if (not defined $s);
    1803                 pb_log(3,"KEEP\n");
    1804                 # Keep the most recent
    1805                 pb_log(2," $s->mtime\n");
    1806                 if ($s->mtime > $maxmtime) {
    1807                     $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$d";
    1808                     $maxmtime = $s->mtime;
    1809                 }
    1810             }
    1811             closedir(DIR);
    1812             die "No directory found under $ENV{'PBCONFDIR'}" if (not defined $ENV{'PBROOTDIR'});
    1813             pb_log(1,"WARNING: no pbroot defined, using $ENV{'PBROOTDIR'}\n");
    1814             pb_log(1,"         Please use -r release if you want to use another release\n");
    1815         } else {
    1816             my ($pbroot) = pb_conf_read_if("$ENV{'PBDESTDIR'}/pbrc","pbroot");
    1817             # That's always the environment variable that will be used
    1818             die "Please remove inconsistent $ENV{'PBDESTDIR'}/pbrc" if ((not defined $pbroot) || (not defined $pbroot->{$ENV{'PBPROJ'}}));
    1819             $ENV{'PBROOTDIR'} = $pbroot->{$ENV{'PBPROJ'}};
    1820         }
    1821     } else {
    1822         # transform in full path if relative
    1823         $ENV{'PBROOTDIR'} = "$ENV{'PBCONFDIR'}/$ENV{'PBROOTDIR'}" if ($ENV{'PBROOTDIR'} !~ /^\//);
    1824         pb_mkdir_p($ENV{'PBROOTDIR'}) if (defined $pbinit);
    1825         die "$ENV{'PBROOTDIR'} is not a directory" if (not -d $ENV{'PBROOTDIR'});
    1826     }
    1827 
    1828     return  if ($action =~ /^newver$/);
    1829 
    1830     my %version = ();
    1831     my %defpkgdir = ();
    1832     my %extpkgdir = ();
    1833     my %filteredfiles = ();
    1834     my %supfiles = ();
    1835    
    1836     if ((-f "$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") and (not defined $pbinit)) {
    1837         # List of pkg to build by default (mandatory)
    1838         my ($defpkgdir,$pbpackager, $pkgv, $pkgt) = pb_conf_get("defpkgdir","pbpackager","projver","projtag");
    1839         # List of additional pkg to build when all is called (optional)
    1840         # Valid version names (optional)
    1841         # List of files to filter (optional)
    1842         # Project version and tag (optional)
    1843         my ($extpkgdir, $version, $filteredfiles, $supfiles) = pb_conf_get_if("extpkgdir","version","filteredfiles","supfiles");
    1844         pb_log(2,"DEBUG: defpkgdir: ".Dumper($defpkgdir)."\n");
    1845         pb_log(2,"DEBUG: extpkgdir: ".Dumper($extpkgdir)."\n");
    1846         pb_log(2,"DEBUG: version: ".Dumper($version)."\n");
    1847         pb_log(2,"DEBUG: filteredfiles: ".Dumper($filteredfiles)."\n");
    1848         pb_log(2,"DEBUG: supfiles: ".Dumper($supfiles)."\n");
    1849         # Global
    1850         %defpkgdir = %$defpkgdir;
    1851         %extpkgdir = %$extpkgdir if (defined $extpkgdir);
    1852         %version = %$version if (defined $version);
    1853         %filteredfiles = %$filteredfiles if (defined $filteredfiles);
    1854         %supfiles = %$supfiles if (defined $supfiles);
    1855         #
    1856         # Get global Version/Tag
    1857         #
    1858         if (not defined $ENV{'PBPROJVER'}) {
    1859             if ((defined $pkgv) && (defined $pkgv->{$ENV{'PBPROJ'}})) {
    1860                 $ENV{'PBPROJVER'}=$pkgv->{$ENV{'PBPROJ'}};
    1861             } else {
    1862                 die "No projver found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    1863             }
    1864         }
    1865         die "Invalid version name $ENV{'PBPROJVER'} in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb" if (($ENV{'PBPROJVER'} !~ /[0-9.]+/) && (not defined $version) && ($ENV{'PBPROJVER'} =~ /$version{$ENV{'PBPROJ'}}/));
    1866        
    1867         if (not defined $ENV{'PBPROJTAG'}) {
    1868             if ((defined $pkgt) && (defined $pkgt->{$ENV{'PBPROJ'}})) {
    1869                 $ENV{'PBPROJTAG'}=$pkgt->{$ENV{'PBPROJ'}};
    1870             } else {
    1871                 die "No projtag found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    1872             }
    1873         }
    1874         die "Invalid tag name $ENV{'PBPROJTAG'} in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb" if ($ENV{'PBPROJTAG'} !~ /[0-9.]+/);
    1875    
    1876    
    1877         if (not defined $ENV{'PBPACKAGER'}) {
    1878             if ((defined $pbpackager) && (defined $pbpackager->{$ENV{'PBPROJ'}})) {
    1879                 $ENV{'PBPACKAGER'}=$pbpackager->{$ENV{'PBPROJ'}};
    1880             } else {
    1881                 die "No pbpackager found in $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    1882             }
    1883         }
    1884     } else {
    1885         if (defined $pbinit) {
    1886             my $ptr = pb_get_pkg();
    1887             my @pkgs = @$ptr;
    1888             @pkgs = ("pkg1") if (not @pkgs);
    1889    
    1890             open(CONF,"> $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb") || die "Unable to create $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    1891             print CONF << "EOF";
    1892 #
    1893 # Project Builder configuration file
    1894 # For project $ENV{'PBPROJ'}
    1895 #
    1896 # \$Id\$
    1897 #
    1898 
    1899 #
    1900 # What is the project URL
    1901 #
    1902 #pburl $ENV{'PBPROJ'} = svn://svn.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
    1903 #pburl $ENV{'PBPROJ'} = svn://svn+ssh.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
    1904 #pburl $ENV{'PBPROJ'} = cvs://cvs.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
    1905 #pburl $ENV{'PBPROJ'} = http://www.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
    1906 #pburl $ENV{'PBPROJ'} = ftp://ftp.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
    1907 #pburl $ENV{'PBPROJ'} = file:///src/$ENV{'PBPROJ'}-devel.tar.gz
    1908 #pburl $ENV{'PBPROJ'} = dir:///src/$ENV{'PBPROJ'}-devel
    1909 
    1910 # Check whether project is well formed
    1911 # (containing already a directory with the project-version name)
    1912 #pbwf $ENV{'PBPROJ'} = 1
    1913 
    1914 #
    1915 # Packager label
    1916 #
    1917 #pbpackager $ENV{'PBPROJ'} = William Porte <bill\@$ENV{'PBPROJ'}.org>
    1918 #
    1919 
    1920 # For delivery to a machine by SSH (potentially the FTP server)
    1921 # Needs hostname, account and directory
    1922 #
    1923 #sshhost $ENV{'PBPROJ'} = www.$ENV{'PBPROJ'}.org
    1924 #sshlogin $ENV{'PBPROJ'} = bill
    1925 #sshdir $ENV{'PBPROJ'} = /$ENV{'PBPROJ'}/ftp
    1926 #sshport $ENV{'PBPROJ'} = 22
    1927 
    1928 #
    1929 # For Virtual machines management
    1930 # Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
    1931 # followed by '-' and by release number
    1932 # followed by '-' and by architecture
    1933 # a .vmtype extension will be added to the resulting string
    1934 # a QEMU rhel-3-i286 here means that the VM will be named rhel-3-i386.qemu
    1935 #
    1936 #vmlist $ENV{'PBPROJ'} = mandrake-10.1-i386,mandrake-10.2-i386,mandriva-2006.0-i386,mandriva-2007.0-i386,mandriva-2007.1-i386,mandriva-2008.0-i386,redhat-7.3-i386,redhat-9-i386,fedora-4-i386,fedora-5-i386,fedora-6-i386,fedora-7-i386,fedora-8-i386,rhel-3-i386,rhel-4-i386,rhel-5-i386,suse-10.0-i386,suse-10.1-i386,suse-10.2-i386,suse-10.3-i386,sles-9-i386,sles-10-i386,gentoo-nover-i386,debian-3.1-i386,debian-4.0-i386,ubuntu-6.06-i386,ubuntu-7.04-i386,ubuntu-7.10-i386,mandriva-2007.0-x86_64,mandriva-2007.1-x86_64,mandriva-2008.0-x86_64,fedora-6-x86_64,fedora-7-x86_64,fedora-8-x86_64,rhel-4-x86_64,rhel-5-x86_64,suse-10.2-x86_64,suse-10.3-x86_64,sles-10-x86_64,gentoo-nover-x86_64,debian-4.0-x86_64,ubuntu-7.04-x86_64,ubuntu-7.10-x86_64
    1937 
    1938 #
    1939 # Valid values for vmtype are
    1940 # qemu, (vmware, xen, ... TBD)
    1941 #vmtype $ENV{'PBPROJ'} = qemu
    1942 
    1943 # Hash for VM stuff on vmtype
    1944 #vmntp default = pool.ntp.org
    1945 
    1946 # We suppose we can commmunicate with the VM through SSH
    1947 #vmhost $ENV{'PBPROJ'} = localhost
    1948 #vmlogin $ENV{'PBPROJ'} = pb
    1949 #vmport $ENV{'PBPROJ'} = 2222
    1950 
    1951 # Timeout to wait when VM is launched/stopped
    1952 #vmtmout default = 120
    1953 
    1954 # per VMs needed paramaters
    1955 #vmopt $ENV{'PBPROJ'} = -m 384 -daemonize
    1956 #vmpath $ENV{'PBPROJ'} = /home/qemu
    1957 #vmsize $ENV{'PBPROJ'} = 5G
    1958 
    1959 #
    1960 # For Virtual environment management
    1961 # Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
    1962 # followed by '-' and by release number
    1963 # followed by '-' and by architecture
    1964 # a .vetype extension will be added to the resulting string
    1965 # a chroot rhel-3-i286 here means that the VE will be named rhel-3-i386.chroot
    1966 #
    1967 #velist $ENV{'PBPROJ'} = fedora-7-i386
    1968 
    1969 # VE params
    1970 #vetype $ENV{'PBPROJ'} = chroot
    1971 #ventp default = pool.ntp.org
    1972 #velogin $ENV{'PBPROJ'} = pb
    1973 #vepath $ENV{'PBPROJ'} = /var/lib/mock
    1974 #veconf $ENV{'PBPROJ'} = /etc/mock
    1975 #verebuild $ENV{'PBPROJ'} = false
    1976 
    1977 #
    1978 # Global version/tag for the project
    1979 #
    1980 #projver $ENV{'PBPROJ'} = devel
    1981 #projtag $ENV{'PBPROJ'} = 1
    1982 
    1983 # Hash of valid version names
    1984 #version $ENV{'PBPROJ'} = devel,stable
    1985 
    1986 # Adapt to your needs:
    1987 # Optional if you need to overwrite the global values above
    1988 #
    1989 EOF
    1990        
    1991             foreach my $pp (@pkgs) {
    1992                 print CONF << "EOF";
    1993 #pkgver $pp = stable
    1994 #pkgtag $pp = 3
    1995 EOF
    1996             }
    1997             foreach my $pp (@pkgs) {
    1998                 print CONF << "EOF";
    1999 # Hash of default package/package directory
    2000 #defpkgdir $pp = dir-$pp
    2001 EOF
    2002             }
    2003    
    2004             print CONF << "EOF";
    2005 # Hash of additional package/package directory
    2006 #extpkgdir minor-pkg = dir-minor-pkg
    2007 
    2008 # List of files per pkg on which to apply filters
    2009 # Files are mentioned relatively to pbroot/defpkgdir
    2010 EOF
    2011             foreach my $pp (@pkgs) {
    2012                 print CONF << "EOF";
    2013 #filteredfiles $pp = Makefile.PL,configure.in,install.sh,$pp.8
    2014 #supfiles $pp = $pp.init
    2015 EOF
    2016             }
    2017             close(CONF);
    2018             pb_mkdir_p("$ENV{'PBROOTDIR'}/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter";
    2019             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/all.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/all.pbf";
    2020             print CONF << "EOF";
    2021 #
    2022 # \$Id\$
    2023 #
    2024 # Filter for all files
    2025 #
    2026 # PBSRC is replaced by the source package format
    2027 #filter PBSRC = ftp://ftp.$ENV{'PBPROJ'}.org/src/%{name}-%{version}.tar.gz
    2028 
    2029 # PBVER is replaced by the version (\$pbver in code)
    2030 filter PBVER = \$pbver
    2031 
    2032 # PBDATE is replaced by the date (\$pbdate in code)
    2033 filter PBDATE = \$pbdate
    2034 
    2035 # PBLOG is replaced by the changelog if value is yes
    2036 #filter PBLOG = yes
    2037 
    2038 # PBTAG is replaced by the tag (\$pbtag in code)
    2039 filter PBTAG = \$pbtag
    2040 
    2041 # PBREV is replaced by the revision (\$pbrev in code)
    2042 filter PBREV = \$pbrev
    2043 
    2044 # PBPKG is replaced by the package name (\$pbpkg in code)
    2045 filter PBPKG = \$pbpkg
    2046 
    2047 # PBPACKAGER is replaced by the packager name (\$pbpackager in code)
    2048 filter PBPACKAGER = \$pbpackager
    2049 
    2050 # PBDESC contains the description of the package
    2051 #filter PBDESC = "Bla-Bla"
    2052 
    2053 # PBURL contains the URL of the Web site of the project
    2054 #filter PBURL = http://www.$ENV{'PBPROJ'}.org
    2055 EOF
    2056             close(CONF);
    2057             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/rpm.pbf";
    2058             print CONF << "EOF";
    2059 #
    2060 # \$Id\$
    2061 #
    2062 # Filter for rpm build
    2063 #
    2064 
    2065 # PBGRP is replaced by the RPM group of apps
    2066 # Cf: http://fedoraproject.org/wiki/RPMGroups
    2067 #filter PBGRP = Applications/Archiving
    2068 
    2069 # PBLIC is replaced by the license of the application
    2070 # Cf: http://fedoraproject.org/wiki/Licensing
    2071 #filter PBLIC = GPL
    2072 
    2073 # PBDEP is replaced by the list of dependencies
    2074 #filter PBDEP =
    2075 
    2076 # PBSUF is replaced by the package suffix (\$pbsuf in code)
    2077 filter PBSUF = \$pbsuf
    2078 
    2079 # PBOBS is replaced by the Obsolete line
    2080 #filter PBOBS =
    2081 
    2082 EOF
    2083             close(CONF);
    2084             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/deb.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/deb.pbf";
    2085             print CONF << "EOF";
    2086 #
    2087 # \$Id\$
    2088 #
    2089 # Filter for debian build
    2090 #
    2091 # PBGRP is replaced by the group of apps
    2092 filter PBGRP = utils
    2093 
    2094 # PBLIC is replaced by the license of the application
    2095 # Cf:
    2096 #filter PBLIC = GPL
    2097 
    2098 # PBDEP is replaced by the list of dependencies
    2099 #filter PBDEP =
    2100 
    2101 # PBSUG is replaced by the list of suggestions
    2102 #filter PBSUG =
    2103 
    2104 # PBREC is replaced by the list of recommandations
    2105 #filter PBREC =
    2106 
    2107 EOF
    2108             close(CONF);
    2109             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/md.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/md.pbf";
    2110             print CONF << "EOF";
    2111 # Specific group for Mandriva for $ENV{'PBPROJ'}
    2112 # Cf: http://wiki.mandriva.com/en/Development/Packaging/Groups
    2113 #filter PBGRP = Archiving/Backup
    2114 
    2115 # PBLIC is replaced by the license of the application
    2116 # Cf: http://wiki.mandriva.com/en/Development/Packaging/Licenses
    2117 #filter PBLIC = GPL
    2118 
    2119 EOF
    2120             close(CONF);
    2121             open(CONF,"> $ENV{'PBROOTDIR'}/pbfilter/novell.pbf") || die "Unable to create $ENV{'PBROOTDIR'}/pbfilter/novell.pbf";
    2122             print CONF << "EOF";
    2123 # Specific group for SuSE for $ENV{'PBPROJ'}
    2124 # Cf: http://en.opensuse.org/SUSE_Package_Conventions/RPM_Groups
    2125 #filter PBGRP = Productivity/Archiving/Backup
    2126 
    2127 # PBLIC is replaced by the license of the application
    2128 # Cf: http://en.opensuse.org/Packaging/SUSE_Package_Conventions/RPM_Style#1.6._License_Tag
    2129 #filter PBLIC = GPL
    2130 
    2131 EOF
    2132             close(CONF);
    2133             foreach my $pp (@pkgs) {
    2134                 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/deb") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb";
    2135                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/control") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/control";
    2136                 print CONF << "EOF";
    2137 Source: PBPKG
    2138 Section: PBGRP
    2139 Priority: optional
    2140 Maintainer: PBPACKAGER
    2141 Build-Depends: debhelper (>= 4.2.20), PBDEP
    2142 Standards-Version: 3.6.1
    2143 
    2144 Package: PBPKG
    2145 Architecture: amd64 i386 ia64
    2146 Section: PBGRP
    2147 Priority: optional
    2148 Depends: \${shlibs:Depends}, \${misc:Depends}, PBDEP
    2149 Recommends: PBREC
    2150 Suggests: PBSUG
    2151 Description:
    2152  PBDESC
    2153  .
    2154  Homepage: PBURL
    2155 
    2156 EOF
    2157                 close(CONF);
    2158                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/copyright") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/copyright";
    2159                 print CONF << "EOF";
    2160 This package is debianized by PBPACKAGER
    2161 `date`
    2162 
    2163 The current upstream source was downloaded from
    2164 ftp://ftp.$ENV{'PBPROJ'}.org/src/.
    2165 
    2166 Upstream Authors: Put their name here
    2167 
    2168 Copyright:
    2169 
    2170    This package is free software; you can redistribute it and/or modify
    2171    it under the terms of the GNU General Public License as published by
    2172    the Free Software Foundation; version 2 dated June, 1991.
    2173 
    2174    This package is distributed in the hope that it will be useful,
    2175    but WITHOUT ANY WARRANTY; without even the implied warranty of
    2176    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2177    GNU General Public License for more details.
    2178 
    2179    You should have received a copy of the GNU General Public License
    2180    along with this package; if not, write to the Free Software
    2181    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
    2182    MA 02110-1301, USA.
    2183 
    2184 On Debian systems, the complete text of the GNU General
    2185 Public License can be found in /usr/share/common-licenses/GPL.
    2186 
    2187 EOF
    2188                 close(CONF);
    2189                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/changelog") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/changelog";
    2190                 print CONF << "EOF";
    2191 PBLOG
    2192 EOF
    2193                 close(CONF);
    2194                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/compat") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/compat";
    2195                 print CONF << "EOF";
    2196 4
    2197 EOF
    2198                 close(CONF);
    2199                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.dirs";
    2200                 print CONF << "EOF";
    2201 EOF
    2202                 close(CONF);
    2203                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/$pp.docs";
    2204                 print CONF << "EOF";
    2205 INSTALL
    2206 COPYING
    2207 AUTHORS
    2208 NEWS
    2209 README
    2210 EOF
    2211                 close(CONF);
    2212                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/deb/rules") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/deb/rules";
    2213                 print CONF << 'EOF';
    2214 #!/usr/bin/make -f
    2215 # -*- makefile -*-
    2216 # Sample debian/rules that uses debhelper.
    2217 # GNU copyright 1997 to 1999 by Joey Hess.
    2218 #
    2219 # $Id$
    2220 #
    2221 
    2222 # Uncomment this to turn on verbose mode.
    2223 #export DH_VERBOSE=1
    2224 
    2225 # Define package name variable for a one-stop change.
    2226 PACKAGE_NAME = PBPKG
    2227 
    2228 # These are used for cross-compiling and for saving the configure script
    2229 # from having to guess our platform (since we know it already)
    2230 DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
    2231 DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
    2232 
    2233 CFLAGS = -Wall -g
    2234 
    2235 ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
    2236         CFLAGS += -O0
    2237 else
    2238         CFLAGS += -O2
    2239 endif
    2240 ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
    2241         INSTALL_PROGRAM += -s
    2242 endif
    2243 config.status: configure
    2244         dh_testdir
    2245 
    2246         # Configure the package.
    2247         CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr
    2248  --mandir=\$${prefix}/share/man
    2249 
    2250 # Build both architecture dependent and independent
    2251 build: build-arch build-indep
    2252 
    2253 # Build architecture dependent
    2254 build-arch: build-arch-stamp
    2255 
    2256 build-arch-stamp:  config.status
    2257         dh_testdir
    2258 
    2259         # Compile the package.
    2260         $(MAKE)
    2261 
    2262         touch build-stamp
    2263 
    2264 # Build architecture independent
    2265 build-indep: build-indep-stamp
    2266 
    2267 build-indep-stamp:  config.status
    2268         # Nothing to do, the only indep item is the manual which is available as html in original source
    2269         touch build-indep-stamp
    2270 
    2271 # Clean up
    2272 clean:
    2273         dh_testdir
    2274         dh_testroot
    2275         rm -f build-arch-stamp build-indep-stamp #CONFIGURE-STAMP#
    2276         # Clean temporary document directory
    2277         rm -rf debian/doc-temp
    2278         # Clean up.
    2279         -$(MAKE) distclean
    2280         rm -f config.log
    2281 ifneq "$(wildcard /usr/share/misc/config.sub)" ""
    2282         cp -f /usr/share/misc/config.sub config.sub
    2283 endif
    2284 ifneq "$(wildcard /usr/share/misc/config.guess)" ""
    2285         cp -f /usr/share/misc/config.guess config.guess
    2286 endif
    2287 
    2288         dh_clean
    2289 
    2290 # Install architecture dependent and independent
    2291 install: install-arch install-indep
    2292 
    2293 # Install architecture dependent
    2294 install-arch: build-arch
    2295         dh_testdir
    2296         dh_testroot
    2297         dh_clean -k -s
    2298         dh_installdirs -s
    2299 
    2300         # Install the package files into build directory:
    2301         # - start with upstream make install
    2302         $(MAKE) install prefix=$(CURDIR)/debian/$(PACKAGE_NAME)/usr mandir=$(CURDIR)/debian/$(PACKAGE_NAME)/us
    2303 r/share/man
    2304         # - copy html manual to temporary location for renaming
    2305         mkdir -p debian/doc-temp
    2306         dh_install -s
    2307 
    2308 # Install architecture independent
    2309 install-indep: build-indep
    2310         dh_testdir
    2311         dh_testroot
    2312         dh_clean -k -i
    2313         dh_installdirs -i
    2314         dh_install -i
    2315 
    2316 # Must not depend on anything. This is to be called by
    2317 # binary-arch/binary-indep
    2318 # in another 'make' thread.
    2319 binary-common:
    2320         dh_testdir
    2321         dh_testroot
    2322         dh_installchangelogs ChangeLog
    2323         dh_installdocs
    2324         dh_installman
    2325         dh_link
    2326         dh_strip
    2327         dh_compress
    2328         dh_fixperms
    2329         dh_installdeb
    2330         dh_shlibdeps
    2331         dh_gencontrol
    2332         dh_md5sums
    2333         dh_builddeb
    2334 
    2335 # Build architecture independant packages using the common target.
    2336 binary-indep: build-indep install-indep
    2337         $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
    2338 
    2339 # Build architecture dependant packages using the common target.
    2340 binary-arch: build-arch install-arch
    2341         $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
    2342 
    2343 # Build architecture depdendent and independent packages
    2344 binary: binary-arch binary-indep
    2345 .PHONY: clean binary
    2346 
    2347 EOF
    2348                 close(CONF);
    2349                 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/rpm") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm";
    2350                 open(CONF,"> $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/rpm/$pp.spec";
    2351                 print CONF << 'EOF';
    2352 #
    2353 # $Id$
    2354 #
    2355 
    2356 Summary:        bla-bla
    2357 Summary(fr):    french bla-bla
    2358 
    2359 Name:           PBPKG
    2360 Version:        PBVER
    2361 Release:        PBTAGPBSUF
    2362 License:        PBLIC
    2363 Group:          PBGRP
    2364 Url:            PBURL
    2365 Source:         PBSRC
    2366 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -u -n)
    2367 #Requires:       PBDEP
    2368 
    2369 %description
    2370 PBDESC
    2371 
    2372 %description -l fr
    2373 french desc
    2374 
    2375 %prep
    2376 %setup -q
    2377 
    2378 %build
    2379 %configure
    2380 make %{?_smp_mflags}
    2381 
    2382 %install
    2383 %{__rm} -rf $RPM_BUILD_ROOT
    2384 make DESTDIR=$RPM_BUILD_ROOT install
    2385 
    2386 %clean
    2387 %{__rm} -rf $RPM_BUILD_ROOT
    2388 
    2389 %files
    2390 %defattr(-,root,root)
    2391 %doc ChangeLog
    2392 %doc INSTALL COPYING README AUTHORS NEWS
    2393 
    2394 %changelog
    2395 PBLOG
    2396 
    2397 EOF
    2398                 close(CONF);
    2399                 pb_mkdir_p("$ENV{'PBROOTDIR'}/$pp/pbfilter") || die "Unable to create $ENV{'PBROOTDIR'}/$pp/pbfilter";
    2400    
    2401                 pb_log(0,"\nDo not to forget to commit the pbconf directory in your CMS if needed\n");
    2402             }
    2403         } else {
    2404             die "Unable to open $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb";
    2405         }
    2406     }
    2407     umask 0022;
    2408     return(\%filteredfiles, \%supfiles, \%defpkgdir, \%extpkgdir);
    2409 } else {
    2410     # Setup the variables from what has been stored at the end of cms2build
    2411     my ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbroot");
    2412     $ENV{'PBROOTDIR'} = $var->{$ENV{'PBPROJ'}};
    2413 
    2414     ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projver");
    2415     $ENV{'PBPROJVER'} = $var->{$ENV{'PBPROJ'}};
    2416 
    2417     ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","projtag");
    2418     $ENV{'PBPROJTAG'} = $var->{$ENV{'PBPROJ'}};
    2419 
    2420     ($var) = pb_conf_read("$ENV{'PBDESTDIR'}/pbrc","pbpackager");
    2421     $ENV{'PBPACKAGER'} = $var->{$ENV{'PBPROJ'}};
    2422 
    2423     return;
    2424 }
    2425 }
    2426 
    2427 # Function which returns a pointer on a table
    2428 # corresponding to a set of values queried in the conf file
    2429 # and test the returned vaue as they need to exist in that case
    2430 sub pb_conf_get {
    2431 
    2432 my @param = @_;
    2433 my @return = pb_conf_get_if(@param);
    2434 
    2435</