Changeset 1903 in ProjectBuilder
- Timestamp:
- Oct 8, 2014, 1:35:10 PM (10 years ago)
- Location:
- devel
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
devel/pb-modules/etc/pb.conf
r1900 r1903 414 414 # When using docker some specific conf items 415 415 dockerregistry default = http://localhost:5000/pb 416 #dockeropt default = 417 # Some options to pass to the docker command such as IP conf when firewalled --bip=172.17.42.1/16 418 # used in addition with shorewall with a masq file having "eth0 172.17.0.0/16" 416 419 #dockerimage mageia-4-x86_64 = mageia-4-x86_64 417 420 #dockertag pb = pb … … 701 704 osrepo redhat-6.2 = 702 705 osrepo rpm = ftp://ftp.project-builder.org/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/pb.repo 706 osrepo mageia = ftp://ftp.project-builder.org/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/pb.addmedia 707 osrepo mandriva = ftp://ftp.project-builder.org/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/pb.addmedia 703 708 osrepo deb = ftp://ftp.project-builder.org/$pbos->{'name'}/$pbos->{'version'}/pb.sources.list 704 709 -
devel/pb-modules/etc/pb.conf.pod
r1900 r1903 111 111 Example: delivery mondorescue = prod 112 112 113 =item B<dockeropt> 114 115 Nature: Optional 116 Key: project (as defined in the -p option or PBPROJ environment variable) 117 Value: List of the options to call docker with 118 Conffile: project 119 Example: dockeropt default = --bip=172.16.42.1/16 120 113 121 =item B<dockerregistry> 114 122 -
devel/pb-modules/lib/ProjectBuilder/Base.pm
r1896 r1903 425 425 426 426 sub pb_temp_init { 427 428 my $pbkeep = shift || 0; # Do not keep temp files by default 427 429 428 430 if (not defined $ENV{'TMPDIR'}) { … … 450 452 pb_mkdir_p("$ENV{'TMPDIR'}/$template"); 451 453 } else { 452 if ( $pbdebug > 1) {454 if (($pbdebug > 1) || ($pbkeep == 1)) { 453 455 $ENV{'PBTMP'} = tempdir( "pb.XXXXXXXXXX", DIR => $ENV{'TMPDIR'}); 454 456 pb_log(2,"DEBUG: Creating a non-volatile temporary directory ($ENV{'PBTMP'})\n"); -
devel/pb-modules/lib/ProjectBuilder/VE.pm
r1902 r1903 16 16 use Carp 'confess'; 17 17 use English; 18 use File::Basename; 18 19 use ProjectBuilder::Version; 19 20 use ProjectBuilder::Base; … … 31 32 32 33 our @ISA = qw(Exporter); 33 our @EXPORT = qw(pb_ve_launch pb_ve_snap );34 our @EXPORT = qw(pb_ve_launch pb_ve_snap pb_ve_get_type pb_ve_docker_repo pb_ve_docker_get_image); 34 35 35 36 ($VERSION,$REVISION) = pb_version_init(); … … 66 67 sub pb_ve_launch { 67 68 68 my $v = shift || undef; 69 my $pbforce = shift || 0; # By default do not rebuild VE 70 my $locsnap = shift || 0; # By default do not snap VE 71 my $vetype = shift || undef; # By default no image 72 my $pbimage = shift || undef; # By default no image 69 my $v = shift; 70 my $pbscript = shift; 71 my $pbforce = shift; 72 my $pbstep= shift; # Which step are we in (0: create, 1: setup, 2: build, 3: use) 73 my $locsnap = shift; 74 my $vetype = shift; 75 my $pbimage = shift; 73 76 74 77 my $dockerregistry = undef; 75 78 my $docrepo = undef; # By default no repository for docker available 76 79 80 pb_log(2,"Entering pb_ve_launch at step $pbstep\n"); 77 81 # Get distro context 78 82 my $pbos = pb_distro_get_context($v); 79 83 80 # Get VE context 81 if (not defined $vetype) { 82 my ($ptr) = pb_conf_get("vetype"); 83 $vetype = $ptr->{$ENV{'PBPROJ'}}; 84 } 85 confess "No vetype defined for $ENV{PBPROJ}" unless (defined $vetype); 86 pb_log(1, "Using vetype $vetype for $ENV{PBPROJ}\n"); 84 $vetype = pb_ve_get_type($vetype); 87 85 my ($vepath) = pb_conf_get("vepath"); 88 86 … … 114 112 if ($EFFECTIVE_USER_ID != 0) { 115 113 $sudocmd ="sudo "; 116 foreach my $proxy (qw/http_proxy ftp_proxy/) {114 foreach my $proxy (qw/http_proxy ftp_proxy/) { 117 115 if (defined $ENV{$proxy}) { 118 116 open(CMD,"sudo sh -c 'echo \$$proxy' |") or die "can't run sudo sh?: $!"; … … 132 130 if (((((defined $verebuild) && ($verebuild->{$ENV{'PBPROJ'}} =~ /true/i)) || ($pbforce == 1)) && ($vetype ne "docker")) 133 131 # For docker we may have a reference image that we'll use 134 || (( (not defined $pbimage) || ($pbimage eq "")) && ($vetype eq "docker"))) {132 || (($vetype eq "docker") && ($pbstep == 0))) { 135 133 136 134 my ($verpmtype,$vedebtype) = pb_conf_get("verpmtype","vedebtype"); … … 275 273 ((defined $vesnap->{$ENV{'PBPROJ'}}) && ($vesnap->{$ENV{'PBPROJ'}} =~ /true/i))) && 276 274 ($locsnap eq 1) && 275 ($vetype ne "docker") && 277 276 (! -d "$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}")) { 278 277 my $cmd1 = pb_check_req("rm",0); … … 281 280 pb_system("$sudocmd $cmd1 -rf $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'} ; $sudocmd $cmd2 -p $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'} ; $sudocmd $cmd3 xz -C $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'} -f $root/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz","Extracting snapshot of $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz under $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}"); 282 281 } 283 284 # Fix modes to allow access to the VE for pb user 285 my $command = pb_check_req("chmod",0); 286 pb_system("$sudocmd $command 755 $root/$pbos->{'name'} $root/$pbos->{'name'}/$pbos->{'version'} $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}","Fixing permissions"); 282 283 if ($vetype ne "docker") { 284 # Fix modes to allow access to the VE for pb user 285 my $command = pb_check_req("chmod",0); 286 pb_system("$sudocmd $command 755 $root/$pbos->{'name'} $root/$pbos->{'name'}/$pbos->{'version'} $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}","Fixing permissions"); 287 } 287 288 288 289 # If docker, create the image and remove the now temp dir except if we had one already 289 if ($vetype eq "docker") { 290 if ((not defined $pbimage) || ($pbimage eq "")) { 291 # Snaphot the VE to serve as an input for docker 292 pb_ve_snap($pbos,$root); 293 # Create the docker image from the previous bootstrap 294 my $cmd1 = pb_check_req("docker",0); 295 $docrepo = pb_ve_docker_repo($dockerregistry->{$ENV{'PBPROJ'}}); 296 # Need sudo to be able to create all files correctly 297 pb_system("$sudocmd $cmd1 import - $docrepo:$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'} < $root/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz"); 298 pb_system("$cmd1 push $docrepo:$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}"); 299 #} else { 300 } 290 if (($vetype eq "docker") && ($pbstep == 0)) { 291 $docrepo = pb_ve_docker_repo($dockerregistry->{$ENV{'PBPROJ'}}); 292 my $cmd1 = pb_check_req("docker",0); 293 # step 0 : nothing at creation -> tag n-v-a (made below) 294 295 # Snaphot the VE to serve as an input for docker 296 pb_ve_snap($pbos,$root); 297 # Create the docker image from the previous bootstrap 298 # Need sudo to be able to create all files correctly 299 # TODO: check before that the image doesn't already exist in the docker registry 300 my $pbimage = "$docrepo:$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}"; 301 pb_system("$sudocmd $cmd1 import - $pbimage < $root/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz"); 302 pb_system("$cmd1 push $pbimage"); 301 303 } 302 304 … … 376 378 } 377 379 380 sub pb_ve_docker_get_image { 381 382 my $pbimage = shift || undef; 383 my $found = 0; 384 385 die "Unable to handle an undef docker image" if (not defined $pbimage); 386 387 # Check that this docker image exists 388 my $cmd1 = pb_check_req("docker",0); 389 open(CMD, "$cmd1 images |") || die "Unable to get docker image list"; 390 my ($repo, $tag, $id, $dummy); 391 while (<CMD>) { 392 ($repo, $tag, $id, $dummy) = split(/\s+/,$_,4); 393 $found = $id if ("$repo:$tag" eq $pbimage); 394 } 395 close(CMD); 396 return($found); 397 } 398 sub pb_ve_get_type { 399 400 my $vetype = shift || undef; 401 402 # Get VE context 403 if (not defined $vetype) { 404 my ($ptr) = pb_conf_get("vetype"); 405 $vetype = $ptr->{$ENV{'PBPROJ'}}; 406 } 407 confess "No vetype defined for $ENV{PBPROJ}" unless (defined $vetype); 408 pb_log(1, "Using vetype $vetype for $ENV{PBPROJ}\n"); 409 return($vetype); 410 } 411 412 378 413 =head1 WEB SITES 379 414 -
devel/pb/bin/pb
r1900 r1903 41 41 42 42 # Global variables 43 $Global::pb_stop_on_error = 0; # False by default 44 $Global::pb_show_sudo = 0; # False by default 45 46 my %opts; # CLI Options 47 my $action; # action to realize 48 my $test = "FALSE"; # Not used 49 my $pbforce = 0; # Force VE/VM rebuild 50 my $pbsnap = 0; # Do not use snapshot mode for VM/VE by default 51 my $pbkeep = 0; # keep temporary directory at the end 52 my $option = ""; # Not used 53 my @pkgs; # list of packages 54 my $pbtag; # Global Tag variable 55 my $pbver; # Global Version variable 56 my $pbscript; # Name of the script 57 my %pbver; # per package 58 my %pbtag; # per package 59 my $pbrev; # Global REVISION variable 60 my $pbaccount; # Login to use to connect to the VM/RM 61 my $pbtarget = undef; # Target os-ver-arch you want to build for 62 my $pbport; # Port to use to connect to the VM/RM 63 my $newver; # New version to create 64 my $pbimage = undef; # ISO image for the VM to create or docker image for the VE 65 my $vetype = undef; # Type of Virtual environment to deal with 43 $Global::pb_stop_on_error = 0; # False by default 44 $Global::pb_show_sudo = 0; # False by default 45 46 my %opts; # CLI Options 47 my $action; # action to realize 48 my $test = "FALSE"; # Not used 49 my $pbforce = 0; # Force VM stop 50 my $pbsnap = 0; # Do not use snapshot mode for VM/VE by default 51 my $pbkeep = 0; # keep temporary directory at the end 52 my $option = ""; # Not used 53 my @pkgs; # list of packages 54 my $pbtag; # Global Tag variable 55 my $pbver; # Global Version variable 56 my %pbscript; # Name of the scripts per V 57 my $pbrev; # Global REVISION variable 58 my $pbaccount; # Login to use to connect to the VM/RM 59 my $pbtarget = undef; # Target os-ver-arch you want to build for 60 my $pbport; # Port to use to connect to the VM/RM 61 my $newver; # New version to create 62 my $pbimage = undef; # ISO image for the VM to create or docker image for the VE 63 my $vetype = undef; # Type of Virtual environment to deal with 66 64 67 65 my @date = pb_get_date(); … … 740 738 } 741 739 if (defined $opts{'s'}) { 742 $pbscript = $opts{'s'};740 $pbscript{'default'} = $opts{'s'}; 743 741 } 744 742 if (defined $opts{'a'}) { 745 743 $pbaccount = $opts{'a'}; 746 die "option -a requires a -s script option" if (not defined $pbscript );744 die "option -a requires a -s script option" if (not defined $pbscript{'default'}); 747 745 } 748 746 if (defined $opts{'P'}) { … … 870 868 pb_build2v("vm","build"); 871 869 } elsif ($action =~ /^launchvm$/) { 872 my $pm; 873 my $all_ok = 1; 874 if (defined $pbparallel) { 875 $pm = new Parallel::ForkManager($pbparallel); 876 877 # Set which port the VM/RM will use to communicate 878 $pm->run_on_start(\&pb_set_port); 879 $pm->run_on_finish(sub { my ($pid, $code, $id, $signal, $dump) = @_; 880 $all_ok = 0 unless (($code == 0) && ($signal == 0) && ($dump == 0)); 881 }); 882 } 883 884 my $counter = 0; 885 foreach my $v (split(/,/,$ENV{'PBV'})) { 886 $counter++; 887 # Modulo 2 * pbparallel (to avoid synchronization problems) 888 $counter = 1 if ((defined $pbparallel) && ($counter > 2 * $pbparallel)); 889 $pm->start($counter) and next if (defined $pbparallel); 890 891 pb_launchv("vm",$v,0); 892 } 893 $pm->wait_all_children if (defined $pbparallel); 894 die "Aborting, one or more of the children failed." if ((not $all_ok) && ($Global::pb_stop_on_error)); 870 pb_parallel_launchv(undef,"vm",undef,3); 895 871 } elsif ($action =~ /^launchve$/) { 896 pb_ launchv("ve",$ENV{'PBV'},0);872 pb_parallel_launchv(undef,"ve",undef,3); 897 873 } elsif ($action =~ /^script2vm$/) { 898 pb_script2v($pbscript,"vm"); 874 die "action script2vm requires a -s script option" if (not defined $pbscript{'default'}); 875 pb_script2v(\%pbscript,"vm"); 899 876 } elsif ($action =~ /^script2ve$/) { 900 pb_script2v($pbscript,"ve"); 877 die "action script2ve requires a -s script option" if (not defined $pbscript{'default'}); 878 pb_script2v(\%pbscript,"ve"); 901 879 } elsif ($action =~ /^script2rm$/) { 902 pb_script2v($pbscript,"rm"); 880 die "action script2rm requires a -s script option" if (not defined $pbscript{'default'}); 881 pb_script2v(\%pbscript,"rm"); 903 882 } elsif ($action =~ /^newver$/) { 904 883 pb_newver(); 905 884 } elsif ($action =~ /^newve$/) { 906 pb_ launchv("ve",$ENV{'PBV'},1);885 pb_parallel_launchv(undef,"ve",undef,0); 907 886 } elsif ($action =~ /^newvm$/) { 908 pb_ launchv("vm",$ENV{'PBV'},1);887 pb_parallel_launchv(undef,"vm",undef,0); 909 888 pb_log(0, "Please ensure that sshd is running in your VM by default\n"); 910 889 pb_log(0, "and that it allows remote root login (PermitRootLogin yes in /etc/ssh/sshd_config)\n"); … … 978 957 my ($ptr2) = pb_conf_get("vmcmd"); 979 958 my $vmcmd = $ptr2->{$ENV{'PBPROJ'}}; 980 my ($v mexist,$vmmport) = pb_check_ps($vmcmd,$ENV{'PBV'});981 if (! $v mexist) {959 my ($vexist,$vmmport) = pb_check_ps($vmcmd,$ENV{'PBV'}); 960 if (! $vexist) { 982 961 pb_log(0,"No VM found for $ENV{'PBV'}\n"); 983 962 } else { 984 pb_log(0,"Found an existing VM for $ENV{'PBV'} PID: $v mexist - SSH port: $vmmport\n");963 pb_log(0,"Found an existing VM for $ENV{'PBV'} PID: $vexist - SSH port: $vmmport\n"); 985 964 } 986 965 } elsif ($action =~ /^sbx2webpkg$/) { … … 1930 1909 1931 1910 my $cmt = shift; 1911 my $pbscript = shift || undef; 1932 1912 my $v = shift || undef; 1933 my $v mexist = shift || 0; # 0 is FALSE1934 my $v mpid = shift || 0; # 0 is FALSE1913 my $vexist = shift || 0; # 0 is FALSE 1914 my $vpid = shift || 0; # 0 is FALSE 1935 1915 my $snapme = shift || 0; # 0 is FALSE 1936 1937 pb_log(2,"DEBUG: pb_send2target($cmt,".Dumper($v).",$vmexist,$vmpid)\n"); 1916 my $pbstep = shift || 3; # 3 is usage of container 1917 1918 pb_log(2,"DEBUG: pb_send2target($cmt,".Dumper($v).",$vexist,$vpid)\n"); 1938 1919 my $host = "sshhost"; 1939 1920 my $login = "sshlogin"; … … 2039 2020 2040 2021 if ($cmt =~ /(V[EM]|RM)build/) { 2041 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc $ ENV{'PBDESTDIR'}/pbscript.$$";2022 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc $pbscript{$v}"; 2042 2023 } elsif ($cmt =~ /(V[EM]|RM)Script/) { 2043 $src="$src $ ENV{'PBDESTDIR'}/pbscript.$$";2024 $src="$src $pbscript{$v}"; 2044 2025 } elsif ($cmt =~ /(V[EM]|RM)test/) { 2045 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc $ ENV{'PBDESTDIR'}/pbscript.$$$ENV{'PBDESTDIR'}/pbtest";2026 $src="$src $ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb $ENV{'PBDESTDIR'}/$ENV{'PBPROJVER'}-$ENV{'PBPROJTAG'}.pb $ENV{'PBETC'} $ENV{'PBDESTDIR'}/pbrc $pbscript{$v} $ENV{'PBDESTDIR'}/pbtest"; 2046 2027 } elsif (($cmt eq "Announce") || ($cmt eq "Web") || ($cmt eq "CPAN")) { 2047 2028 $src="$src $ENV{'PBTMP'}/pbscript"; … … 2052 2033 chomp($src); 2053 2034 close(KEEP); 2054 $src = "$src $ ENV{'PBBUILDDIR'}/pbscript.$$";2035 $src = "$src $pbscript{$v}"; 2055 2036 } 2056 2037 if (($cmt eq "Sources") || ($cmt eq "Packages") || ($cmt eq "CPAN")) { … … 2189 2170 # Prepare a script to ease urpmi setup 2190 2171 cat > $ENV{'PBPROJ'}$repotag.addmedia << EOT 2172 #rpm --import $pbrepo->{$ENV{'PBPROJ'}}/$repodir/$ENV{'PBPROJ'}.pubkey 2191 2173 urpmi.addmedia $ENV{'PBPROJ'}$repotag $pbrepo->{$ENV{'PBPROJ'}}/$repodir with media_info/hdlist.cz 2192 2174 EOT … … 2200 2182 genhdlist . 2201 2183 fi 2184 (cd media_info ; ln -sf ../$ENV{'PBPROJ'}.pubkey pubkey) 2202 2185 EOF 2203 2186 } … … 2367 2350 my $tpdir; 2368 2351 my $tp; 2352 my $docrepo; 2353 my $context = "$ENV{'PBTMP'}"; 2354 my %tag; 2369 2355 if ($cmt =~ /^VE/) { 2370 2356 $tp = pb_path_expand($vepath->{$ENV{'PBPROJ'}}); 2371 2357 $tpdir = pb_path_expand("$tp/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}"); 2372 if (not defined $vetype) { 2373 my ($ptr) = pb_conf_get("vetype"); 2374 $vetype = $ptr->{$ENV{'PBPROJ'}}; 2375 } 2358 $vetype = pb_ve_get_type($vetype); 2376 2359 my $arch = pb_get_arch(); 2377 2360 if ($vetype eq "chroot") { … … 2382 2365 } elsif ($vetype eq "docker") { 2383 2366 # docker manages the storage so rely on it 2384 $shcmdroot = "sudo /usr/bin/docker $tpdir "; 2385 $shcmd = "$shcmdroot /bin/su - $mac -c "; 2367 $shcmdroot = ""; 2368 my ($dockerregistry) = pb_conf_get("dockerregistry"); 2369 $docrepo = pb_ve_docker_repo($dockerregistry->{$ENV{'PBPROJ'}}); 2370 my $cmd1 = pb_check_req("docker",0); 2371 #my ($dockeropt) = pb_conf_get_if("dockeropt"); 2372 # pbimage is used for docker and is setup to the right name depending on the step: 2373 # TODO: This is not coded yet 2374 my $pbimage = undef; 2375 # step 0 : nothing at creation -> tag n-v-a (made below) 2376 # step 1 : n-v-a + setup -> tag n-v-a-pb 2377 # step 2 : n-v-a-pb + build -> tag n-v-a-pb-pbproj 2378 # step 3 : n-v-a-pb-pbproj at use 2379 if ((not defined $pbimage) || ($pbimage eq "")) { 2380 # If no image name given, create a naming convention 2381 $tag{1} = "$docrepo:$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}"; 2382 $tag{2} = "$tag{1}-pb"; 2383 $tag{3} = "$tag{2}-$ENV{'PBPROJ'}"; 2384 } else { 2385 # If we were given an image name, just use it 2386 $tag{1} = $pbimage; 2387 $tag{2} = $pbimage; 2388 $tag{3} = $pbimage; 2389 } 2390 # If we do not create the image, then use the one we should have 2391 my $found = pb_ve_docker_get_image($tag{$pbstep}); 2392 # Now we use that image to do what is needed 2393 # use a dockerfile to ease the creation of next images 2394 # the context is in an empty temp dir 2395 my $tmpd = "$context/Dockerfile"; 2396 open(DOCKER, "> $tmpd") || die "Unable to create the docker file $tmpd"; 2397 print DOCKER "FROM $tag{$pbstep}\n"; 2398 print DOCKER "MAINTAINER project-builder.org aka pb\n"; 2399 if ($pbstep == 1) { 2400 # setup done as root 2401 print DOCKER "USER root\n"; 2402 } else { 2403 print DOCKER "USER pb\n"; 2404 } 2405 $shcmd = "$cmd1 build -t $tag{$pbstep+1} $context"; 2406 #$shcmd = "$cmd1 build $dockeropt->{$ENV{'PBPROJ'}} -t $tag{$pbstep+1} $context"; 2386 2407 } 2387 2408 $shcmd = "setarch i386 $shcmd" if (($pbos->{'arch'} =~ /i[3456]86/) && ($arch eq 'x86_64')); 2388 2409 $cpcmd = "sudo /bin/cp -r "; 2389 # We need to get the home dir of the target account to deliver in the right place2390 open(PASS,"$tpdir/etc/passwd") || die "Unable to open $tpdir/etc/passwd: $!";2391 2410 my $homedir = ""; 2392 while (<PASS>) { 2393 my ($c1,$c2,$c3,$c4,$c5,$c6,$c7) = split(/:/); 2394 $homedir = $c6 if ($c1 =~ /^$mac$/); 2395 pb_log(3,"Homedir: $homedir - account: $c6\n"); 2396 } 2397 close(PASS); 2411 if (($cmt =~ /VE/) && ($vetype ne "docker")) { 2412 # We need to get the home dir of the target account to deliver in the right place 2413 open(PASS,"$tpdir/etc/passwd") || die "Unable to open $tpdir/etc/passwd: $!"; 2414 while (<PASS>) { 2415 my ($c1,$c2,$c3,$c4,$c5,$c6,$c7) = split(/:/); 2416 $homedir = $c6 if ($c1 =~ /^$mac$/); 2417 pb_log(3,"Homedir: $homedir - account: $c6\n"); 2418 } 2419 close(PASS); 2420 } 2398 2421 $cptarget = "$tpdir/$homedir/$tdir"; 2422 if ($vetype eq "docker") { 2423 $cptarget = "docker container $shcmd"; 2424 } 2399 2425 if ($cmt eq "VEbuild") { 2400 2426 $cp2target = "$tpdir/$homedir/$bdir"; … … 2436 2462 # Do not touch when just announcing 2437 2463 if (($cmt ne "Announce") && ($cmt ne "CPAN")) { 2438 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 -e\"","Preparing $tdir on $cptarget"); 2464 # For docker everything is done in the Dockerfile 2465 if (($cmt =~ /^VE/) && ($vetype eq "docker")) { 2466 print DOCKER "RUN mkdir -p $tdir\n"; 2467 print DOCKER "RUN cd $tdir ; for i in $basesrc; do if [ -f \$i ]; then rm -f \$i; fi; done\n"; 2468 print DOCKER "RUN $cmd\n" if ((defined $cmd) && ($cmd ne "")); 2469 } else { 2470 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 -e\"","Preparing $tdir on $cptarget"); 2471 } 2439 2472 } else { 2440 2473 $logres = "> "; 2441 2474 } 2442 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget"); 2475 # For docker everything is done in the Dockerfile 2476 if (($cmt =~ /^VE/) && ($vetype eq "docker")) { 2477 foreach my $f (split(/ +/,$src)) { 2478 copy("$f","$context"); 2479 print DOCKER "ADD ".basename($f)." $tdir/\n"; 2480 } 2481 } else { 2482 pb_system("cd $ENV{'PBBUILDDIR'} ; $cpcmd $src $cptarget 2> /dev/null","$cmt delivery in $cptarget"); 2483 } 2443 2484 2444 2485 # For VE we need to change the owner manually 2445 2486 if ($cmt =~ /^VE/) { 2446 my $sudomode = pb_distro_get_param($pbos,pb_conf_get("ossudoersmode")); 2447 my $res = pb_system("$shcmdroot sed -i '/requiretty/d' /etc/sudoers","Removing potential requiretty in sudoers","quiet"); 2448 pb_system("$shcmdroot sed '/requiretty/d' /etc/sudoers > /tmp/sudoers.new ; mv /tmp/sudoers.new $tpdir/tmp/sudoers.new ; $shcmdroot mv /tmp/sudoers.new /etc/sudoers ; $shcmdroot chown root:root /etc/sudoers ; $shcmdroot chmod $sudomode /etc/sudoers","Removing again potential requiretty in sudoers as sed -i failed") if (($res ne 0) && (-f "$tpdir/etc/sudoers")); 2449 pb_system("$shcmd \"sudo chown -R $mac $tdir\"","Adapt owner in $tdir to $mac"); 2487 if ($vetype ne "docker") { 2488 my $sudomode = pb_distro_get_param($pbos,pb_conf_get("ossudoersmode")); 2489 my $res = pb_system("$shcmdroot sed -i '/requiretty/d' /etc/sudoers","Removing potential requiretty in sudoers","quiet"); 2490 pb_system("$shcmdroot sed '/requiretty/d' /etc/sudoers > /tmp/sudoers.new ; mv /tmp/sudoers.new $tpdir/tmp/sudoers.new ; $shcmdroot mv /tmp/sudoers.new /etc/sudoers ; $shcmdroot chown root:root /etc/sudoers ; $shcmdroot chmod $sudomode /etc/sudoers","Removing again potential requiretty in sudoers as sed -i failed") if (($res ne 0) && (-f "$tpdir/etc/sudoers")); 2491 pb_system("$shcmd \"sudo chown -R $mac $tdir\"","Adapt owner in $tdir to $mac"); 2492 } 2450 2493 } 2451 2494 2452 2495 # Use the right script name depending on context 2453 my $pbscript ;2496 my $pbscript1; 2454 2497 if (($cmt =~ /^(V[EM]|RM)/) || ($cmt =~ /Packages/)){ 2455 $pbscript = "pbscript.$$";2498 $pbscript1 = "$pbscript{$v}"; 2456 2499 } else { 2457 $pbscript = "pbscript";2500 $pbscript1 = "pbscript"; 2458 2501 } 2459 2502 … … 2461 2504 my $shcmdbase = $shcmd; 2462 2505 if ($cmt ne "CPAN") { 2463 $shcmd .= " \"echo \'cd $tdir ; if [ -x $pbscript ]; then ./$pbscript; fi ; rm -f ./$pbscript\' | bash\""; 2506 if (($cmt =~ /^VE/) && ($vetype eq "docker")) { 2507 copy("$pbscript1","$context"); 2508 my $s = basename($pbscript1); 2509 print DOCKER "ADD $s $tdir/\n"; 2510 # sleep to avoid text file busy errors 2511 print DOCKER "RUN sleep 2\n"; 2512 print DOCKER "RUN cd $tdir ; chmod 755 $s ; ./$s ; if [ '$pbkeep' == '0' ]; then rm -f $s; fi\n"; 2513 close(DOCKER); 2514 } else { 2515 $shcmd .= " \"echo \'cd $tdir ; if [ -x $pbscript1 ]; then ./$pbscript1; fi ; if [ '$pbkeep' == '0' ]; then rm -f ./$pbscript1\'; fi | bash\""; 2516 } 2464 2517 } 2465 2518 my $cmdverb = "verbose"; … … 2469 2522 $cmdverb = "verbose_\[$v\] "; 2470 2523 } 2524 # this is where we lanch the execution 2471 2525 pb_system("$shcmd","Executing pbscript on $cptarget if needed",$cmdverb); 2526 2472 2527 if ($cmt =~ /^(V[EM]|RM)build/) { 2473 2528 # Get back info on pkg produced, compute their name and get them from the VM/RM … … 2509 2564 # We want to send them to the ssh account so overwrite what has been done before 2510 2565 undef $pbaccount; 2511 pb_log(2,"Before sending pkgs, v mexist: $vmexist, vmpid: $vmpid\n");2512 pb_send2target("Packages", $pbos->{'name'}."-".$pbos->{'version'}."-".$pbos->{'arch'},$vmexist,$vmpid);2566 pb_log(2,"Before sending pkgs, vexist: $vexist, vpid: $vpid\n"); 2567 pb_send2target("Packages","$ENV{'PBDESTDIR'}/pbscript.$$",$pbos->{'name'}."-".$pbos->{'version'}."-".$pbos->{'arch'},$vexist,$vpid); 2513 2568 pb_rm_rf("$ENV{'PBBUILDDIR'}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}"); 2514 2569 } 2515 2570 } 2516 unlink("$ ENV{'PBDESTDIR'}/pbscript.$$") if ((($cmt =~ /^(V[ME]|RM)/) || ($cmt =~ /Packages/)) && ($pbkeep eq 0));2517 2518 pb_log(2,"Before halt, v mexist: $vmexist, vmpid: $vmpid\n");2519 if ((! $v mexist) && ($cmt =~ /^VM/)) {2571 unlink("$pbscript{$v}") if ((($cmt =~ /^(V[ME]|RM)/) || ($cmt =~ /Packages/)) && ($pbkeep eq 0)); 2572 2573 pb_log(2,"Before halt, vexist: $vexist, vpid: $vpid\n"); 2574 if ((! $vexist) && ($cmt =~ /^VM/)) { 2520 2575 # If in setupvm then takes a snapshot just before halting 2521 2576 if ($snapme != 0) { … … 2550 2605 $hoption = "" ; 2551 2606 } 2552 pb_system("$shcmdbase \"sudo $hpath $hoption \"; $tm ; echo \'if [ -d /proc/$v mpid ]; then kill -9 $vmpid; fi \' | bash ; sleep 10","VM $v halt (pid $vmpid)");2607 pb_system("$shcmdbase \"sudo $hpath $hoption \"; $tm ; echo \'if [ -d /proc/$vpid ]; then kill -9 $vpid; fi \' | bash ; sleep 10","VM $v halt (pid $vpid)"); 2553 2608 } 2554 2609 if (($cmt =~ /^VE/) && ($snapme != 0)) { 2555 2610 pb_ve_snap($pbos,$tp); 2611 if ($vetype eq "docker") { 2612 foreach my $f (split(/ +/,$src)) { 2613 unlink("$context/$f"); 2614 } 2615 } 2556 2616 } 2557 2617 } 2558 2618 2559 2619 sub pb_script2v { 2560 my $pbscript=shift; 2561 my $vtype=shift; 2562 my $pbforce=shift || 0; # Force stop of VM. Default not. 2563 my $vm1=shift || undef; # Only that VM/VE/RM to treat. Default all. 2564 my $snapme=shift || 0; # Do we have to create a snapshot. Default not. 2565 my $vm; 2566 my $all; 2567 2568 pb_log(2,"DEBUG: pb_script2v($pbscript,$vtype,$pbforce,".Dumper($vm1).",$snapme)\n"); 2569 # Prepare the script to be executed on the VM/VE/RM 2570 # in $ENV{'PBDESTDIR'}/pbscript.$$ 2571 if ((defined $pbscript ) && ($pbscript ne "$ENV{'PBDESTDIR'}/pbscript.$$")) { 2572 copy($pbscript,"$ENV{'PBDESTDIR'}/pbscript.$$") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript.$$ from $pbscript"; 2573 chmod 0755,"$ENV{'PBDESTDIR'}/pbscript.$$"; 2574 } 2575 2576 if (not defined $vm1) { 2577 ($vm,$all) = pb_get2v($vtype); 2620 2621 my $pbscript=shift; 2622 my $vtype=shift; 2623 my $pbstep=shift; # Which step are we in (0: create, 1: setup, 2: build, 3: use) 2624 my $pbforce=shift || 0; # Force stop of VM. Default not. 2625 my $snapme=shift || 0; # Do we have to create a snapshot. Default not. 2626 my $pbimage=shift || undef; # Which image to use to start the VM/VE 2627 my $vm; 2628 my $all; 2629 2630 pb_log(2,"DEBUG: pb_script2v($vtype,$pbstep,$pbforce,$snapme)\n"); 2631 pb_log(2,"DEBUG: pb_script2v(pbscript: ".Dumper($pbscript)."\n"); 2632 pb_parallel_launchv($pbscript,$vtype,uc($vtype)."Script",$pbstep,$pbforce,$snapme,$pbsnap,$pbimage); 2633 } 2634 2635 sub pb_parallel_launchv { 2636 2637 my $pbscript=shift; 2638 my $vtype = shift; 2639 my $action = shift; # It an action is defined then use send2target 2640 my $pbstep=shift; # Which step are we in (0: create, 1: setup, 2: build 3: use) 2641 my $pbforce=shift || 0; # Force stop of VM. Default not. 2642 my $snapme = shift || 0; # By default do not snap a VM/VE/RM 2643 my $usesnap = shift || 1; # By default study the usage of the snapshot feature of VM/VE/RM 2644 my $pbimage=shift || undef; # Which image to use to start the VM/VE 2645 my $vm; 2646 my $all; 2647 2648 # Adapt // mode to memory size 2649 $pbparallel = pb_set_parallel($vtype); 2650 2651 pb_log(2,"DEBUG: pb_parallel_launch(vtype,step,force,snapme,usesnap: $vtype,$pbstep,$pbforce,$snapme,$usesnap)\n"); 2652 pb_log(2,"DEBUG: pb_parallel_launch(pbscript: ".Dumper($pbscript)."\n"); 2653 2654 my ($vexist,$vpid) = (undef,undef); 2655 my $pm; 2656 my $all_ok = 1; 2657 if (defined $pbparallel) { 2658 $pm = new Parallel::ForkManager($pbparallel); 2659 2660 # Set which port the VM/RM will use to communicate 2661 $pm->run_on_start(\&pb_set_port); 2662 $pm->run_on_finish(sub { my ($pid, $code, $id, $signal, $dump) = @_; 2663 unless ($code == 0 && $signal == 0 && $dump == 0) { 2664 $all_ok = 0; 2665 pb_log(0,"ERROR: pid $pid failed\n"); 2666 } 2667 }); 2668 } 2669 2670 # Determine on which V to work 2671 if (defined $ENV{'PBV'}) { 2672 @$vm = split(/,/,$ENV{'PBV'}); 2673 } else { 2674 ($vm,$all) = pb_get2v($vtype); 2675 } 2676 2677 my $counter = 0; 2678 foreach my $v (@$vm) { 2679 $counter++; 2680 # Modulo 2 * pbparallel (to avoid synchronization problems) 2681 $counter = 1 if ((defined $pbparallel) && ($counter > 2 * $pbparallel)); 2682 $pm->start($counter) and next if (defined $pbparallel); 2683 2684 # Launch a single operation 2685 my $pbscript = $pbscript->{$v} if (defined $pbscript->{$v}); 2686 $pbscript = $pbscript->{'default'} if (not defined $pbscript); 2687 die "No script defined so unable to launch it in $v" if (not defined $pbscript); 2688 ($vexist,$vpid) = pb_launchv($pbscript,$vtype,$v,$action,$pbstep,$pbforce,$snapme,$pbsnap,$pbimage); 2689 2690 # Skip that V if something went wrong 2691 if (($vpid == 0) && ($vexist == 0)) { 2692 $pm->finish if (defined $pbparallel); 2693 next; 2694 } 2695 $pm->finish if (defined $pbparallel); 2696 } 2697 $pm->wait_all_children if (defined $pbparallel); 2698 die "Aborting, one or more of the children failed." if ((not $all_ok) && ($Global::pb_stop_on_error)); 2699 } 2700 2701 sub pb_launchv { 2702 2703 my $pbscript=shift; 2704 my $vtype = shift; 2705 my $v = shift; # Only 1 VM/VE/RM treated here 2706 my $action = shift; # It an action is defined then use send2target 2707 my $pbstep=shift; # Which step are we in (0: create, 1: setup, 2: build 3: use) 2708 my $pbforce=shift || 0; # Force stop of VM. Default not. 2709 my $snapme = shift || 0; # By default do not snap a VM/VE/RM 2710 my $usesnap = shift || 1; # By default study the usage of the snapshot feature of VM/VE/RM 2711 my $pbimage=shift || undef; # Which image to use to start the VM/VE 2712 my $vexist = undef; 2713 my $vpid = undef; 2714 2715 # Check that v exists 2716 die "No VM/VE/RM defined, unable to launch" if (not defined $v); 2717 2718 # If creation or snapshot creation mode, no snapshot usable 2719 if (($pbstep == 0) || ($snapme == 1)) { 2720 $usesnap = 0; 2721 } 2722 2723 pb_log(2,"DEBUG: pb_launchv(script,vtype,v,step,force,snapme,usesnap: $pbscript,$vtype,$v,$pbstep,$pbforce,$snapme,$usesnap)\n"); 2724 pb_log(2,"DEBUG: pb_launchv(pbimage: $pbimage)\n") if (defined $pbimage); 2725 pb_log(2,"DEBUG: pb_launchv(action: $action)\n") if (defined $action); 2726 # Keep only the first VM in case many were given 2727 if ($v =~ /,/) { 2728 pb_log(0,"WARNING: pruning to just the first of several VM/VE/RMs listed ($v)\n"); 2729 $v =~ s/,.*//; 2730 } 2731 2732 my $pbos = pb_distro_get_context($v); 2733 2734 pb_apply_conf_proxy($pbos); 2735 2736 # Launch the VMs/VEs 2737 if ($vtype eq "vm") { 2738 die "-i image parameter needed" if (((not defined $pbimage) || ($pbimage eq "")) && ($pbstep == 0)); 2739 2740 my ($ptr,$ptr2,$vmpath,$vmport,$vms) = pb_conf_get("vmtype","vmcmd","vmpath","vmport","vmsize"); 2741 my ($vmopt,$vmmm,$vmtmout,$vmsnap,$vmbuildtm,$vmmonport) = pb_conf_get_if("vmopt","vmmem","vmtmout","vmsnap","vmbuildtm","vmmonport"); 2742 my $vmsize = pb_distro_get_param($pbos,$vms); 2743 2744 my $vmtype = $ptr->{$ENV{'PBPROJ'}}; 2745 my $vmcmd = $ptr2->{$ENV{'PBPROJ'}}; 2746 2747 if (defined $opts{'g'}) { 2748 if (($vmtype eq "kvm") || ($vmtype eq "qemu")) { 2749 $ENV{'PBVMOPT'} = "--nographic"; 2750 } 2751 } 2752 if (not defined $ENV{'PBVMOPT'}) { 2753 $ENV{'PBVMOPT'} = ""; 2754 } 2755 # Save the current status for later restoration 2756 $ENV{'PBOLDVMOPT'} = $ENV{'PBVMOPT'}; 2757 # Set a default timeout of 2 minutes 2758 if (not defined $ENV{'PBVMTMOUT'}) { 2759 $ENV{'PBVMTMOUT'} = "120"; 2760 } 2761 if (defined $vmopt->{$v}) { 2762 $ENV{'PBVMOPT'} .= " $vmopt->{$v}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$v}/); 2763 } elsif (defined $vmopt->{$ENV{'PBPROJ'}}) { 2764 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/); 2765 } 2766 2767 # How much memory to allocate for VMs 2768 if (defined $vmmm) { 2769 my $vmmem = pb_distro_get_param($pbos,$vmmm); 2770 if (defined $vmmem) { 2771 $ENV{'PBVMOPT'} .= " -m $vmmem"; 2772 } 2773 } 2774 2775 # Are we allowed to use snapshot feature 2776 if ($usesnap == 1) { 2777 if ((defined $vmsnap->{$v}) && ($vmsnap->{$v} =~ /true/i)) { 2778 $ENV{'PBVMOPT'} .= " -snapshot"; 2779 } elsif ((defined $vmsnap->{$ENV{'PBPROJ'}}) && ($vmsnap->{$ENV{'PBPROJ'}} =~ /true/i)) { 2780 $ENV{'PBVMOPT'} .= " -snapshot"; 2781 } elsif ($pbsnap eq 1) { 2782 $ENV{'PBVMOPT'} .= " -snapshot"; 2783 } 2784 } 2785 if ($snapme != 0) { 2786 if (($vmtype eq "kvm") || ($vmtype eq "qemu")) { 2787 # Configure the monitoring to automate the creation of the 'pb' snapshot 2788 $ENV{'PBVMOPT'} .= " -serial mon:telnet::$vmmonport->{$ENV{'PBPROJ'}},server,nowait" if ((defined $vmmonport) && (defined $vmmonport->{$ENV{'PBPROJ'}})); 2789 # In that case no snapshot call needed 2790 $ENV{'PBVMOPT'} =~ s/ -snapshot//; 2791 } 2792 } 2793 if (defined $vmtmout->{$v}) { 2794 $ENV{'PBVMTMOUT'} = $vmtmout->{$v}; 2795 } elsif (defined $vmtmout->{$ENV{'PBPROJ'}}) { 2796 $ENV{'PBVMTMOUT'} = $vmtmout->{$ENV{'PBPROJ'}}; 2797 } 2798 my $nport = pb_get_port($vmport,$pbos,$vtype); 2799 2800 my $cmd; 2801 my $vmm; # has to be used for pb_check_ps 2802 if (($vmtype eq "qemu") || ($vmtype eq "kvm")) { 2803 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu"; 2804 if (($pbstep == 0) || (defined $pbimage)) { 2805 $ENV{'PBVMOPT'} .= " -cdrom $pbimage -boot d"; 2806 } 2807 # Always redirect the network and always try to use a 'pb' snapshot 2808 #$cmd = "$vmcmd $ENV{'PBVMOPT'} -net nic,model=virtio -net user,hostfwd=tcp::$nport:22 -loadvm pb $vmm" 2809 #$cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm" 2810 $cmd = "$vmcmd $ENV{'PBVMOPT'} -net nic -net user,hostfwd=tcp:127.0.0.1:$nport-:22 $vmm" 2811 } elsif ($vmtype eq "xen") { 2812 } elsif ($vmtype eq "vmware") { 2578 2813 } else { 2579 @$vm = ($vm1); 2580 } 2581 my ($vmexist,$vmpid) = (undef,undef); 2582 2583 foreach my $v (@$vm) { 2584 # Launch VM/VE 2585 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0,$snapme,$pbsnap); 2586 2587 if ($vtype eq "vm") { 2588 pb_log(2,"DEBUG: After pb_launchv, vmexist: $vmexist, vmpid: $vmpid\n"); 2589 2590 # Skip that VM/RM if something went wrong 2591 next if (($vmpid == 0) && ($vmexist == 0)); 2592 2593 # If force stopping the VM then reset vmexist 2594 if ($pbforce == 1) { 2595 $vmpid = $vmexist; 2596 $vmexist = 0; 2597 } 2814 die "VM of type $vmtype not supported. Report to the dev team"; 2815 } 2816 # Restore the ENV VAR Value 2817 $ENV{'PBVMOPT'} = $ENV{'PBOLDVMOPT'}; 2818 2819 my ($tmpcmd,$void) = split(/ +/,$cmd); 2820 my $vmmport = undef; 2821 ($vexist,$vmmport) = pb_check_ps($tmpcmd,$vmm); 2822 my $vpid = 0; 2823 if (! $vexist) { 2824 if ($pbstep == 0) { 2825 die("Found an existing Virtual machine $vmm. Won't overwrite") if (-r $vmm); 2826 if (($vmtype eq "qemu") || ($vmtype eq "xen") || ($vmtype eq "kvm")) { 2827 my $command = pb_check_req("qemu-img",0); 2828 pb_system("$command create -f qcow2 $vmm $vmsize","Creating the QEMU VM"); 2829 } elsif ($vmtype eq "vmware") { 2830 } else { 2831 } 2832 } 2833 if (! -f "$vmm") { 2834 pb_log(0,"Unable to find VM $vmm\n"); 2598 2835 } else { 2599 #VE 2600 $vmexist = 0; 2601 $vmpid = 0; 2602 } 2603 2604 # Gather all required files to send them to the VM/VE/RM 2605 # and launch the build through pbscript 2606 pb_log(2,"DEBUG: Before send2target, vmexist: $vmexist, vmpid: $vmpid\n"); 2607 pb_send2target(uc($vtype)."Script","$v",$vmexist,$vmpid,$snapme); 2608 2609 } 2610 } 2611 2612 sub pb_launchv { 2613 my $vtype = shift; 2614 my $v = shift; 2615 my $create = shift || 0; # By default do not create a VM/VE/RM 2616 my $snapme = shift || 0; # By default do not snap a VM/VE/RM 2617 my $usesnap = shift || 1; # By default study the usage of the snapshot feature of VM/VE/RM 2618 2619 # If creation or snapshot creation mode, no snapshot usable 2620 if (($create == 1) || ($snapme == 1)) { 2621 $usesnap = 0; 2622 } 2623 2624 pb_log(2,"DEBUG: pb_launchv($vtype,$v,$create,$snapme,$usesnap)\n"); 2625 die "No VM/VE/RM defined, unable to launch" if (not defined $v); 2626 # Keep only the first VM in case many were given 2627 if ($v =~ /,/) { 2628 pb_log(0,"WARNING: pruning to just the first of several VM/VE/RMs listed ($v)\n"); 2629 $v =~ s/,.*//; 2630 } 2631 2836 # Is the SSH port free? if not kill the existing process using it after a build timeout period 2837 my ($vmssh,$void) = pb_check_ps($tmpcmd,$vmm); 2838 if ($vmssh) { 2839 my $buildtm = $ENV{'PBVMTMOUT'}; 2840 if (defined $vmbuildtm->{$v}) { 2841 $buildtm = $vmbuildtm->{$v}; 2842 } elsif (defined $vmbuildtm->{$ENV{'PBPROJ'}}) { 2843 $buildtm = $vmbuildtm->{$ENV{'PBPROJ'}}; 2844 } 2845 2846 sleep $buildtm; 2847 pb_log(0,"WARNING: Killing the process ($vmssh) using port $void (previous failed VM ?)\n"); 2848 kill 15,$vmssh; 2849 # Let it time to exit 2850 sleep 5; 2851 } 2852 pb_system("$cmd &","Launching the VM $vmm"); 2853 # Using system allows to kill it externaly if needed,sosupport that in the call 2854 pb_system("sleep $ENV{'PBVMTMOUT'}","Waiting $ENV{'PBVMTMOUT'} s for VM $v to come up","mayfail"); 2855 ($vpid,$void) = pb_check_ps($tmpcmd,$vmm); 2856 pb_log(0,"VM $vmm launched (pid $vpid)\n"); 2857 } 2858 } else { 2859 pb_log(0,"Found an existing VM $vmm (pid $vexist)\n"); 2860 # Set the correct port here based on what is done 2861 $pbport = $vmmport; 2862 $vpid = $vexist; 2863 } 2864 pb_log(2,"DEBUG: pb_launchv returns ($vexist,$vpid)\n"); 2865 2866 # Skip that VM/RM if something went wrong 2867 return($vexist,$vpid) if (($vpid == 0) && ($vexist == 0)); 2868 2869 # If force stopping the VM then reset vexist 2870 if ($pbforce == 1) { 2871 $vpid = $vexist; 2872 $vexist = 0; 2873 } 2874 } elsif ($vtype eq "ve") { 2875 # Force the creation of the VE and no snapshot usable 2876 $vetype = pb_ve_get_type($vetype); 2877 pb_ve_launch($v,$pbscript,$pbforce,$pbstep,$usesnap,$vetype,$pbimage); 2878 $vexist = 0; 2879 $vpid = 0; 2880 } else { 2881 # RM here 2882 # Get distro context 2632 2883 my $pbos = pb_distro_get_context($v); 2633 2634 pb_apply_conf_proxy($pbos); 2635 2636 # Launch the VMs/VEs 2637 if ($vtype eq "vm") { 2638 die "-i image parameter needed" if (((not defined $pbimage) || ($pbimage eq "")) && ($create != 0)); 2639 2640 my ($ptr,$ptr2,$vmpath,$vmport,$vms) = pb_conf_get("vmtype","vmcmd","vmpath","vmport","vmsize"); 2641 my ($vmopt,$vmmm,$vmtmout,$vmsnap,$vmbuildtm,$vmmonport) = pb_conf_get_if("vmopt","vmmem","vmtmout","vmsnap","vmbuildtm","vmmonport"); 2642 my $vmsize = pb_distro_get_param($pbos,$vms); 2643 2644 my $vmtype = $ptr->{$ENV{'PBPROJ'}}; 2645 my $vmcmd = $ptr2->{$ENV{'PBPROJ'}}; 2646 2647 if (defined $opts{'g'}) { 2648 if (($vmtype eq "kvm") || ($vmtype eq "qemu")) { 2649 $ENV{'PBVMOPT'} = "--nographic"; 2650 } 2651 } 2652 if (not defined $ENV{'PBVMOPT'}) { 2653 $ENV{'PBVMOPT'} = ""; 2654 } 2655 # Save the current status for later restoration 2656 $ENV{'PBOLDVMOPT'} = $ENV{'PBVMOPT'}; 2657 # Set a default timeout of 2 minutes 2658 if (not defined $ENV{'PBVMTMOUT'}) { 2659 $ENV{'PBVMTMOUT'} = "120"; 2660 } 2661 if (defined $vmopt->{$v}) { 2662 $ENV{'PBVMOPT'} .= " $vmopt->{$v}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$v}/); 2663 } elsif (defined $vmopt->{$ENV{'PBPROJ'}}) { 2664 $ENV{'PBVMOPT'} .= " $vmopt->{$ENV{'PBPROJ'}}" if ($ENV{'PBVMOPT'} !~ / $vmopt->{$ENV{'PBPROJ'}}/); 2665 } 2666 2667 # How much memory to allocate for VMs 2668 if (defined $vmmm) { 2669 my $vmmem = pb_distro_get_param($pbos,$vmmm); 2670 if (defined $vmmem) { 2671 $ENV{'PBVMOPT'} .= " -m $vmmem"; 2672 } 2673 } 2674 2675 # Are we allowed to use snapshot feature 2676 if ($usesnap == 1) { 2677 if ((defined $vmsnap->{$v}) && ($vmsnap->{$v} =~ /true/i)) { 2678 $ENV{'PBVMOPT'} .= " -snapshot"; 2679 } elsif ((defined $vmsnap->{$ENV{'PBPROJ'}}) && ($vmsnap->{$ENV{'PBPROJ'}} =~ /true/i)) { 2680 $ENV{'PBVMOPT'} .= " -snapshot"; 2681 } elsif ($pbsnap eq 1) { 2682 $ENV{'PBVMOPT'} .= " -snapshot"; 2683 } 2684 } 2685 if ($snapme != 0) { 2686 if (($vmtype eq "kvm") || ($vmtype eq "qemu")) { 2687 # Configure the monitoring to automate the creation of the 'pb' snapshot 2688 $ENV{'PBVMOPT'} .= " -serial mon:telnet::$vmmonport->{$ENV{'PBPROJ'}},server,nowait" if ((defined $vmmonport) && (defined $vmmonport->{$ENV{'PBPROJ'}})); 2689 # In that case no snapshot call needed 2690 $ENV{'PBVMOPT'} =~ s/ -snapshot//; 2691 } 2692 } 2693 if (defined $vmtmout->{$v}) { 2694 $ENV{'PBVMTMOUT'} = $vmtmout->{$v}; 2695 } elsif (defined $vmtmout->{$ENV{'PBPROJ'}}) { 2696 $ENV{'PBVMTMOUT'} = $vmtmout->{$ENV{'PBPROJ'}}; 2697 } 2698 my $nport = pb_get_port($vmport,$pbos,$vtype); 2699 2700 my $cmd; 2701 my $vmm; # has to be used for pb_check_ps 2702 if (($vmtype eq "qemu") || ($vmtype eq "kvm")) { 2703 $vmm = "$vmpath->{$ENV{'PBPROJ'}}/$v.qemu"; 2704 if (($create != 0) || (defined $pbimage)) { 2705 $ENV{'PBVMOPT'} .= " -cdrom $pbimage -boot d"; 2706 } 2707 # Always redirect the network and always try to use a 'pb' snapshot 2708 #$cmd = "$vmcmd $ENV{'PBVMOPT'} -net nic,model=virtio -net user,hostfwd=tcp::$nport:22 -loadvm pb $vmm" 2709 #$cmd = "$vmcmd $ENV{'PBVMOPT'} -redir tcp:$nport:10.0.2.15:22 $vmm" 2710 $cmd = "$vmcmd $ENV{'PBVMOPT'} -net nic -net user,hostfwd=tcp:127.0.0.1:$nport-:22 $vmm" 2711 } elsif ($vmtype eq "xen") { 2712 } elsif ($vmtype eq "vmware") { 2713 } else { 2714 die "VM of type $vmtype not supported. Report to the dev team"; 2715 } 2716 # Restore the ENV VAR Value 2717 $ENV{'PBVMOPT'} = $ENV{'PBOLDVMOPT'}; 2718 2719 my ($tmpcmd,$void) = split(/ +/,$cmd); 2720 my ($vmexist,$vmmport) = pb_check_ps($tmpcmd,$vmm); 2721 my $vmpid = 0; 2722 if (! $vmexist) { 2723 if ($create != 0) { 2724 die("Found an existing Virtual machine $vmm. Won't overwrite") if (-r $vmm); 2725 if (($vmtype eq "qemu") || ($vmtype eq "xen") || ($vmtype eq "kvm")) { 2726 my $command = pb_check_req("qemu-img",0); 2727 pb_system("$command create -f qcow2 $vmm $vmsize","Creating the QEMU VM"); 2728 } elsif ($vmtype eq "vmware") { 2729 } else { 2730 } 2731 } 2732 if (! -f "$vmm") { 2733 pb_log(0,"Unable to find VM $vmm\n"); 2734 } else { 2735 # Is the SSH port free? if not kill the existing process using it after a build timeout period 2736 my ($vmssh,$void) = pb_check_ps($tmpcmd,$vmm); 2737 if ($vmssh) { 2738 my $buildtm = $ENV{'PBVMTMOUT'}; 2739 if (defined $vmbuildtm->{$v}) { 2740 $buildtm = $vmbuildtm->{$v}; 2741 } elsif (defined $vmbuildtm->{$ENV{'PBPROJ'}}) { 2742 $buildtm = $vmbuildtm->{$ENV{'PBPROJ'}}; 2743 } 2744 2745 sleep $buildtm; 2746 pb_log(0,"WARNING: Killing the process ($vmssh) using port $void (previous failed VM ?)\n"); 2747 kill 15,$vmssh; 2748 # Let it time to exit 2749 sleep 5; 2750 } 2751 pb_system("$cmd &","Launching the VM $vmm"); 2752 # Using system allows to kill it externaly if needed,sosupport that in the call 2753 pb_system("sleep $ENV{'PBVMTMOUT'}","Waiting $ENV{'PBVMTMOUT'} s for VM $v to come up","mayfail"); 2754 ($vmpid,$void) = pb_check_ps($tmpcmd,$vmm); 2755 pb_log(0,"VM $vmm launched (pid $vmpid)\n"); 2756 } 2757 } else { 2758 pb_log(0,"Found an existing VM $vmm (pid $vmexist)\n"); 2759 # Set the correct port here based on what is done 2760 $pbport = $vmmport; 2761 $vmpid = $vmexist; 2762 } 2763 pb_log(2,"DEBUG: pb_launchv returns ($vmexist,$vmpid)\n"); 2764 return($vmexist,$vmpid); 2765 } elsif ($vtype eq "ve") { 2766 # Force the creation of the VE and no snapshot usable 2767 pb_ve_launch($v,$create,$usesnap,$vetype,$pbimage); 2768 } else { 2769 # RM here 2770 # Get distro context 2771 my $pbos = pb_distro_get_context($v); 2772 2773 # Get RM context 2774 my ($ptr,$rmpath) = pb_conf_get("rmtype","rmpath"); 2775 2776 # Nothing more to do for RM. No real launch 2777 # For the moment we support the RM is already running 2778 # For ProLiant may be able to power them on if needed later on as an example. 2779 } 2884 2885 # Get RM context 2886 my ($ptr,$rmpath) = pb_conf_get("rmtype","rmpath"); 2887 2888 # Nothing more to do for RM. No real launch 2889 # For the moment we support the RM is already running 2890 # For ProLiant may be able to power them on if needed later on as an example. 2891 $vexist = 0; 2892 $vpid = 0; 2893 } 2894 2895 # Gather all required files to send them to the VM/VE/RM 2896 # and launch the build through pbscript 2897 if (defined $action) { 2898 pb_log(2,"DEBUG: Before send2target, vexist: $vexist, vpid: $vpid, vtype: $vtype, v: $v, action: $action\n"); 2899 pb_send2target($action,$pbscript,$v,$vexist,$vpid,$snapme,$pbstep); 2900 } 2901 return($vexist,$vpid); 2780 2902 } 2781 2903 … … 2821 2943 my $vtype = shift; 2822 2944 my $action = shift || "build"; 2823 2945 my $pbstep = 2; 2946 my $pbforce=shift || 0; # Force stop of VM. Default not. 2947 2948 # We prepare scripts for all V of this vtype to allow sharing that part 2824 2949 my ($v,$all) = pb_get2v($vtype); 2825 2950 … … 2830 2955 $pbparallel = pb_set_parallel($vtype); 2831 2956 2832 my ($v mexist,$vmpid) = (undef,undef);2957 my ($vexist,$vpid) = (undef,undef); 2833 2958 my $pm; 2834 2959 my $all_ok = 1; … … 2854 2979 # Prepare the script to be executed on the VM/VE/RM 2855 2980 # in $ENV{'PBDESTDIR'}/pbscript.$$ 2856 open(SCRIPT,"> $ENV{'PBDESTDIR'}/pbscript.$$") || die "Unable to create $ENV{'PBDESTDIR'}/pbscript.$$"; 2981 # 2982 $pbscript{$v} = "$ENV{'PBDESTDIR'}/pbscript.$$"; 2983 open(SCRIPT,"> $pbscript{$v}") || die "Unable to create $pbscript{$v}"; 2857 2984 print SCRIPT "#!/bin/bash\n"; 2858 2985 … … 2884 3011 2885 3012 # VE needs a good /proc, tolerate one being potentially left around after a failure 2886 if ( $vtype eq "ve") {3013 if (($vtype eq "ve") && ($vetype ne "docker")) { 2887 3014 print SCRIPT "[ -d /proc/1 ] || sudo /bin/mount -t proc /proc /proc\n"; 2888 3015 } … … 2937 3064 print SCRIPT "pb $verbose -p $ENV{'PBPROJ'} $action"."2pkg $p\n"; 2938 3065 2939 if ( $vtype eq "ve") {3066 if (($vtype eq "ve") && ($vetype ne "docker")) { 2940 3067 print SCRIPT "sudo /bin/umount /proc\n"; 2941 3068 } … … 2954 3081 print SCRIPT "echo ==== End of script $$ for $vtype $v =====\n"; 2955 3082 close(SCRIPT); 2956 chmod 0755,"$ ENV{'PBDESTDIR'}/pbscript.$$";3083 chmod 0755,"$pbscript{$v}"; 2957 3084 2958 # Launch the VM/VE/RM2959 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0);2960 2961 2962 if ($vtype eq "vm") {2963 # Skip that VM if something went wrong2964 if (($vmpid == 0) && ($vmexist == 0)) {2965 $pm->finish if (defined $pbparallel);2966 next;2967 }2968 } else {2969 # VE/RM2970 $vmexist = 0;2971 $vmpid = 0;2972 }2973 # Gather all required files to send them to the VM/VE2974 # and launch the build through pbscript2975 pb_log(2,"Calling send2target $vtype,$v,$vmexist,$vmpid\n");2976 pb_send2target(uc($vtype).$action,"$v",$vmexist,$vmpid);2977 3085 $pm->finish if (defined $pbparallel); 2978 3086 } 2979 3087 $pm->wait_all_children if (defined $pbparallel); 2980 3088 die "Aborting, one or more of the children failed." if ((not $all_ok) && ($Global::pb_stop_on_error)); 3089 3090 # Launch the VM/VE/RM 3091 # docker image to use if needed 3092 # Gather all required files to send them to the VM/VE 3093 # and launch the build through pbscript 3094 pb_parallel_launchv(\%pbscript,$vtype,uc($vtype).$action,$pbstep,$pbforce,0,1,$pbimage); 2981 3095 } 2982 3096 … … 3145 3259 my $vtype = shift; 3146 3260 my $sbx = shift || undef; 3261 my $pbstep = 1; 3147 3262 3148 3263 my ($vm,$all) = pb_get2v($vtype); 3149 3150 # Script generated3151 my $pbscript = "$ENV{'PBDESTDIR'}/setupv.$$";3152 3264 3153 3265 # Adapt // mode to memory size … … 3168 3280 my $counter = 0; 3169 3281 foreach my $v (@$vm) { 3282 # Script generated - should be before the fork - after the %pbscript hash isn't updated correctly 3283 $pbscript{$v} = "$ENV{'PBDESTDIR'}/setupv-$v"; 3284 3170 3285 $counter++; 3171 3286 # Modulo 2 * pbparallel (to avoid synchronization problems) … … 3183 3298 my ($pbac) = pb_conf_get($vtype."login"); 3184 3299 my ($key,$zero0,$zero1,$zero2); 3185 my ($v mexist,$vmpid);3300 my ($vexist,$vpid); 3186 3301 3187 3302 # Prepare the script to be executed on the VM/VE/RM 3188 3303 # in $ENV{'PBDESTDIR'}/setupv 3189 open(SCRIPT,"> $pbscript") || die "Unable to create $pbscript"; 3304 3305 pb_log(2,"Preparing setup script for $v in $pbscript{$v}\n"); 3306 open(SCRIPT,"> $pbscript{$v}") || die "Unable to create $pbscript{$v}"; 3190 3307 3191 3308 print SCRIPT << 'EOF'; … … 3219 3336 3220 3337 EOF 3221 3222 # Launch the VM/VE/RM - Usage of snapshot disabled3223 ($vmexist,$vmpid) = pb_launchv($vtype,$v,0,0,0);3224 3338 3225 3339 my $keyfile; … … 3236 3350 3237 3351 # Skip that VM/RM if something went wrong 3238 next if (($v mpid == 0) && ($vmexist == 0));3352 next if (($vpid == 0) && ($vexist == 0)); 3239 3353 3240 3354 # Store the pub key part in a variable … … 3249 3363 # once this is done, we can do what we need on the VM/RM remotely 3250 3364 } elsif ($vtype eq "ve") { 3251 print SCRIPT << "EOF"; 3365 if ($vetype ne "docker") { 3366 print SCRIPT << "EOF"; 3252 3367 # For VE we first need to mount some FS 3253 3368 pb_system("mount -t proc /proc /proc") unless (-d "/proc/$$"); 3254 3369 EOF 3370 } 3371 print SCRIPT << "EOF"; 3255 3372 # For VE we need a good null dev 3256 3373 # Except for RedHat 6.2 where it's good and doesnt like being recreated … … 3565 3682 pb_system("pbdistrocheck",undef,"verbose"); 3566 3683 EOF 3567 if ($vtype eq "ve") { 3684 if ($vtype eq "ve"){ 3685 if ($vetype ne "docker") { 3568 3686 print SCRIPT << 'EOF'; 3569 3687 # For VE we need to umount some FS at the end 3570 3688 3571 3689 pb_system("umount /proc","Unmounting /proc","mayfail"); 3572 3690 EOF 3691 } 3692 print SCRIPT << 'EOF'; 3573 3693 # Create a basic network file if not already there 3574 3694 … … 3612 3732 EOF 3613 3733 close(SCRIPT); 3614 chmod 0755,"$pbscript ";3734 chmod 0755,"$pbscript{$v}"; 3615 3735 3616 3736 # That build script needs to be run as root and force stop of VM at end … … 3618 3738 3619 3739 # Force shutdown of VM except if it was already launched 3740 # TODO: FIX here as it doesn't work anymore 3620 3741 my $pbforce = 0; 3621 if ((! $v mexist) && ($vtype eq "vm")) {3742 if ((! $vexist) && ($vtype eq "vm")) { 3622 3743 $pbforce = 1; 3623 3744 } 3624 3745 3625 pb_script2v($pbscript,$vtype,$pbforce,$v);3626 3746 $pm->finish if (defined $pbparallel); 3627 3747 } 3628 3748 $pm->wait_all_children if (defined $pbparallel); 3629 3749 die "Aborting, one or more of the children failed." if ((not $all_ok) && ($Global::pb_stop_on_error)); 3750 3751 # Launch the VM/VE/RM 3752 pb_log(2,"DEBUG: before parallel launch, pbscript hash is:".Dumper(%pbscript)."\n"); 3753 pb_parallel_launchv(\%pbscript,$vtype,uc($vtype)."Script",$pbstep,$pbforce); 3630 3754 return; 3631 3755 } … … 3635 3759 3636 3760 my $vtype = shift; 3761 my $pbstep = 3; 3637 3762 3638 3763 my ($vm,$all) = pb_get2v($vtype); … … 3667 3792 # Force shutdown of VM/VE 3668 3793 # Force snapshot of VM/VE 3669 pb_script2v($pbscript,$vtype, 1,$v,1);3794 pb_script2v($pbscript,$vtype,$pbstep,1,$v,1); 3670 3795 } 3671 3796 return; … … 3676 3801 3677 3802 my $vtype = shift; 3803 my $pbstep = 2; 3678 3804 3679 3805 my ($vm,$all) = pb_get2v($vtype); … … 3697 3823 EOF 3698 3824 # VE needs a good /proc 3699 if ( $vtype eq "ve") {3825 if (($vtype eq "ve") && ($vetype ne "docker")) { 3700 3826 print SCRIPT "sudo /bin/mount -t proc /proc /proc\n"; 3701 3827 } 3702 3828 print SCRIPT "$pbos->{'update'}\n"; 3703 if ( $vtype eq "ve") {3829 if (($vtype eq "ve") && ($vetype ne "docker")) { 3704 3830 print SCRIPT "sudo /bin/umount /proc\n"; 3705 3831 } … … 3708 3834 3709 3835 # Force shutdown of VM except 3710 pb_script2v($pbscript,$vtype, 1,$v);3836 pb_script2v($pbscript,$vtype,$pbstep,1,$v); 3711 3837 } 3712 3838 return; … … 3854 3980 close(PBS); 3855 3981 chmod 0755,"$ENV{'PBTMP'}/pbscript"; 3856 pb_send2target("Announce" );3982 pb_send2target("Announce","$ENV{'PBTMP'}/pbscript"); 3857 3983 3858 3984 my $sl = "Project $ENV{'PBPROJ'} version $ENV{'PBPROJVER'} is now available"; … … 4211 4337 my $vmcmd = shift; 4212 4338 my $vmm = shift; 4213 my $v mexist = 0; # FALSE by default4339 my $vexist = 0; # FALSE by default 4214 4340 my $vmport = undef; # NONE by default 4215 4341 … … 4219 4345 next if (! /$vmm/); 4220 4346 my $void1; 4221 ($void1, $v mexist, $vmport) = split(/ +/,$_,3);4347 ($void1, $vexist, $vmport) = split(/ +/,$_,3); 4222 4348 pb_log(2,"pb_check_ps $vmport\n"); 4223 4349 $vmport =~ s/.*=tcp:127\.0\.0\.1:([0-9]+)-:22.*/$1/; 4224 4350 chomp($vmport); 4225 pb_log(2,"pb_check_ps found a VM $v mexist using port $vmport\n");4351 pb_log(2,"pb_check_ps found a VM $vexist using port $vmport\n"); 4226 4352 last; 4227 4353 } 4228 return($v mexist,$vmport);4354 return($vexist,$vmport); 4229 4355 } 4230 4356
Note:
See TracChangeset
for help on using the changeset viewer.