source: ProjectBuilder/devel/pb-modules/lib/ProjectBuilder/VE.pm@ 1597

Last change on this file since 1597 was 1597, checked in by Bruno Cornec, 12 years ago
  • Adds option pbshowsudo (false by default) to check whether we display the detail of sudo commands (to match security requiremetns) or not (to have a nicer output)
  • Fix a template generation error in Env.pm for deb rules file (line was split)
  • In VE.pm fix modes of the chroot after the snapshot phase detection to avoid error which make the code die
  • In pb create the RPM build dirs before entering in the parallel loop as sometimes 2 identical were created simultaneously, leading to an error leading to a die
  • In pb revert the code added by Eric to check deb content creation as it was failing in my environement (naming issues). Could be added after 0.12.1 is out as an additional check, but anyway as the files are copied after, it's not that important.
  • Use full path of chown in sudo for pb
  • Make the test account a variable in pbtest
  • Start to add test case for a VM in pbtest
  • This patch makes pb build back in a debian 6 VE.
File size: 10.8 KB
RevLine 
[1348]1#!/usr/bin/perl -w
2#
3# Common functions for virtual environment
[1528]4#
5# Copyright B. Cornec 2007-2012
6# Eric Anderson's changes are (c) Copyright 2012 Hewlett Packard
7# Provided under the GPL v2
[1348]8#
9# $Id$
10#
11
12package ProjectBuilder::VE;
13
14use strict;
15use Data::Dumper;
[1506]16use Carp 'confess';
[1348]17use English;
18use ProjectBuilder::Version;
19use ProjectBuilder::Base;
20use ProjectBuilder::Conf;
[1350]21use ProjectBuilder::Distribution;
[1348]22
23# Global vars
24# Inherit from the "Exporter" module which handles exporting functions.
25
26use vars qw($VERSION $REVISION @ISA @EXPORT);
27use Exporter;
28
29# Export, by default, all the functions into the namespace of
30# any code which uses this module.
31
32our @ISA = qw(Exporter);
33our @EXPORT = qw(pb_ve_launch);
34
35($VERSION,$REVISION) = pb_version_init();
36
37=pod
38
39=head1 NAME
40
41ProjectBuilder::VE, part of the project-builder.org - module dealing with Virtual Environment
42
43=head1 DESCRIPTION
44
45This modules provides functions to deal with Virtual Environements (VE), aka chroot.
46
47=head1 SYNOPSIS
48
49 use ProjectBuilder::VE;
50
51 #
52 # Return information on the running distro
53 #
54 my $pbos = pb_ve_launch();
55
56=head1 USAGE
57
58=over 4
59
60=item B<pb_ve_launch>
61
62This function launch a VE, creating it if necessary using multiple external potential tools.
63
64=cut
65
66sub pb_ve_launch {
67
68my $v = shift || undef;
69my $pbforce = shift || 0; # By default do not rebuild VE
70my $pbsnap = shift || 0; # By default do not snap VE
71
72# Get distro context
73my $pbos = pb_distro_get_context($v);
74
75# Get VE context
76my ($ptr,$vepath) = pb_conf_get("vetype","vepath");
77my $vetype = $ptr->{$ENV{'PBPROJ'}};
78
[1506]79confess "No vetype defined for $ENV{PBPROJ}" unless (defined $vetype);
80pb_log(1, "Using vetype $vetype for $ENV{PBPROJ}\n");
81
[1352]82if (($vetype eq "chroot") || ($vetype eq "schroot")) {
[1348]83
[1352]84 # We need to avoid umask propagation to the VE
85 umask 0022;
[1348]86
[1352]87 # We can probably only get those params now we have the distro context
88 my ($rbsb4pi,$rbspi,$vesnap,$oscodename,$osmindep,$verebuild,$rbsmirrorsrv) = pb_conf_get_if("rbsb4pi","rbspi","vesnap","oscodename","osmindep","verebuild","rbsmirrorsrv");
[1348]89
90 # Architecture consistency
[1352]91 my $arch = pb_get_arch();
[1348]92 if ($arch ne $pbos->{'arch'}) {
[1506]93 die "Unable to launch a VE of architecture $pbos->{'arch'} on a $arch platform" unless (($pbos->{'arch'} =~ /i?86/o) && ($arch eq "x86_64"));
[1348]94 }
95
[1352]96 # If we are already root (from pbmkbm e.g.) don't use sudo, just call the command
97 my $sudocmd="";
[1527]98 if ($EFFECTIVE_USER_ID != 0) {
99 $sudocmd ="sudo ";
100 foreach my $proxy (qw/http_proxy ftp_proxy/) {
101 if (defined $ENV{$proxy}) {
[1530]102 open(CMD,"sudo sh -c 'echo \$$proxy' |") or die "can't run sudo sh?: $!";
[1527]103 $_ = <CMD>;
104 chomp();
105 die "sudo not passing through env var $proxy; '$ENV{$proxy}' != '$_'\nAdd line Defaults:`whoami` env_keep += \"$proxy\" to sudoers file?" unless $_ eq $ENV{$proxy};
[1530]106 close(CMD);
[1527]107 }
108 }
[1530]109 }
[1564]110
[1519]111 # Handle cross arch on Intel based platforms
[1564]112 $sudocmd = "setarch i386 $sudocmd" if (($pbos->{'arch'} =~ /i[3456]86/) && ($arch eq 'x86_64'));
[1348]113
[1506]114 my $root = pb_path_expand($vepath->{$ENV{PBPROJ}});
[1352]115 if (((defined $verebuild) && ($verebuild->{$ENV{'PBPROJ'}} =~ /true/i)) || ($pbforce == 1)) {
116 my ($verpmtype,$vedebtype) = pb_conf_get("verpmtype","vedebtype");
117 my ($rbsopt1) = pb_conf_get_if("rbsopt");
118
[1348]119 # We have to rebuild the chroot
120 if ($pbos->{'type'} eq "rpm") {
121
122 # Which tool is used
123 my $verpmstyle = $verpmtype->{$ENV{'PBPROJ'}};
[1517]124 die "No verpmtype defined for $ENV{PBPROJ}" unless (defined $verpmstyle);
[1348]125
126 # Get potential rbs option
127 my $rbsopt = "";
128 if (defined $rbsopt1) {
129 if (defined $rbsopt1->{$verpmstyle}) {
130 $rbsopt = $rbsopt1->{$verpmstyle};
131 } elsif (defined $rbsopt1->{$ENV{'PBPROJ'}}) {
132 $rbsopt = $rbsopt1->{$ENV{'PBPROJ'}};
133 } else {
134 $rbsopt = "";
135 }
136 }
137
138 my $postinstall = pb_ve_get_postinstall($pbos,$rbspi,$verpmstyle);
139 if ($verpmstyle eq "rinse") {
140 # Need to reshape the mirrors generated with local before-post-install script
141 my $b4post = "--before-post-install ";
142 my $postparam = pb_distro_get_param($pbos,$rbsb4pi);
143 if ($postparam eq "") {
144 $b4post = "";
145 } else {
146 $b4post .= $postparam;
147 }
148
149 # Need to reshape the package list for pb
150 my $addpkgs;
151 $postparam = "";
152 $postparam .= pb_distro_get_param($pbos,$osmindep);
153 if ($postparam eq "") {
154 $addpkgs = "";
155 } else {
156 my $pkgfile = "$ENV{'PBTMP'}/addpkgs.lis";
157 open(PKG,"> $pkgfile") || die "Unable to create $pkgfile";
158 foreach my $p (split(/,/,$postparam)) {
159 print PKG "$p\n";
160 }
161 close(PKG);
162 $addpkgs = "--add-pkg-list $pkgfile";
163 }
164
165 my $rinseverb = "";
166 $rinseverb = "--verbose" if ($pbdebug gt 0);
167 my ($rbsconf) = pb_conf_get("rbsconf");
168
169 my $command = pb_check_req("rinse",0);
[1506]170 pb_system("$sudocmd $command --directory \"$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}\" --arch \"$pbos->{'arch'}\" --distribution \"$pbos->{'name'}-$pbos->{'version'}\" --config \"$rbsconf->{$ENV{'PBPROJ'}}\" $b4post $postinstall $rbsopt $addpkgs $rinseverb","Creating the rinse VE for $pbos->{'name'}-$pbos->{'version'} ($pbos->{'arch'})", "verbose");
[1348]171 } elsif ($verpmstyle eq "rpmbootstrap") {
172 my $rbsverb = "";
173 foreach my $i (1..$pbdebug) {
174 $rbsverb .= " -v";
175 }
176 my $addpkgs = "";
177 my $postparam = "";
178 $postparam .= pb_distro_get_param($pbos,$osmindep);
179 if ($postparam eq "") {
180 $addpkgs = "";
181 } else {
182 $addpkgs = "-a $postparam";
183 }
184 my $command = pb_check_req("rpmbootstrap",0);
185 pb_system("$sudocmd $command $rbsopt $postinstall $addpkgs $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'} $rbsverb","Creating the rpmbootstrap VE for $pbos->{'name'}-$pbos->{'version'} ($pbos->{'arch'})", "verbose");
[1596]186 pb_system("$sudocmd /bin/umount $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/proc","Umounting stale /proc","mayfail") if (-f "$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/proc/cpuinfo");
[1348]187 } elsif ($verpmstyle eq "mock") {
188 my ($rbsconf) = pb_conf_get("rbsconf");
189 my $command = pb_check_req("mock",0);
190 pb_system("$sudocmd $command --init --resultdir=\"/tmp\" --configdir=\"$rbsconf->{$ENV{'PBPROJ'}}\" -r $v $rbsopt","Creating the mock VE for $pbos->{'name'}-$pbos->{'version'} ($pbos->{'arch'})");
191 # Once setup we need to install some packages, the pb account, ...
192 pb_system("$sudocmd $command --install --configdir=\"$rbsconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
193 } else {
194 die "Unknown verpmtype type $verpmstyle. Report to dev team";
195 }
196 } elsif ($pbos->{'type'} eq "deb") {
197 my $vedebstyle = $vedebtype->{$ENV{'PBPROJ'}};
198
199 my $codename = pb_distro_get_param($pbos,$oscodename);
200 my $postparam = "";
201 my $addpkgs;
202 $postparam .= pb_distro_get_param($pbos,$osmindep);
203 if ($postparam eq "") {
204 $addpkgs = "";
205 } else {
206 $addpkgs = "--include $postparam";
207 }
208 my $debmir = "";
209 $debmir .= pb_distro_get_param($pbos,$rbsmirrorsrv);
210
211 # Get potential rbs option
212 my $rbsopt = "";
213 if (defined $rbsopt1) {
214 if (defined $rbsopt1->{$vedebstyle}) {
215 $rbsopt = $rbsopt1->{$vedebstyle};
216 } elsif (defined $rbsopt1->{$ENV{'PBPROJ'}}) {
217 $rbsopt = $rbsopt1->{$ENV{'PBPROJ'}};
218 } else {
219 $rbsopt = "";
220 }
221 }
222
223 # debootstrap works with amd64 not x86_64
224 my $debarch = $pbos->{'arch'};
225 $debarch = "amd64" if ($pbos->{'arch'} eq "x86_64");
226 if ($vedebstyle eq "debootstrap") {
227 my $dbsverb = "";
228 $dbsverb = "--verbose" if ($pbdebug gt 0);
229
230 # Some perl modules are in Universe on Ubuntu
231 $rbsopt .= " --components=main,universe" if ($pbos->{'name'} eq "ubuntu");
232
[1588]233 my $cmd1 = pb_check_req("mkdir",0);
234 my $cmd2 = pb_check_req("debootstrap",0);
235 pb_system("$sudocmd $cmd1 -p $root/$pbos->{name}/$pbos->{version}/$pbos->{arch} ; $sudocmd $cmd2 $dbsverb $rbsopt --arch=$debarch $addpkgs $codename \"$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}\" $debmir","Creating the debootstrap VE for $pbos->{'name'}-$pbos->{'version'} ($pbos->{'arch'})", "verbose");
[1348]236 # debootstrap doesn't create an /etc/hosts file
[1506]237 if (! -f "$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/etc/hosts" ) {
[1588]238 my $cmd = pb_check_req("cp",0);
239 pb_system("$sudocmd $cmd /etc/hosts $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/etc/hosts");
[1348]240 }
241 } else {
242 die "Unknown vedebtype type $vedebstyle. Report to dev team";
243 }
244 } elsif ($pbos->{'type'} eq "ebuild") {
245 die "Please teach the dev team how to build gentoo chroot";
246 } else {
247 die "Unknown distribution type $pbos->{'type'}. Report to dev team";
248 }
249 }
250
251 # Test if an existing snapshot exists and use it if appropriate
252 # And also use it of no local extracted VE is present
[1506]253 if ((-f "$root/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz") &&
[1348]254 (((defined $vesnap->{$v}) && ($vesnap->{$v} =~ /true/i)) ||
255 ((defined $vesnap->{$ENV{'PBPROJ'}}) && ($vesnap->{$ENV{'PBPROJ'}} =~ /true/i)) ||
256 ($pbsnap eq 1) ||
[1506]257 (! -d "$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}"))) {
[1588]258 my $cmd1 = pb_check_req("rm",0);
259 my $cmd2 = pb_check_req("mkdir",0);
260 my $cmd3 = pb_check_req("tar",0);
261 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'}");
[1348]262 }
[1597]263
264 # Fix modes to allow access to the VE for pb user
265 my $command = pb_check_req("chmod",0);
266 pb_system("$sudocmd $command 755 $root/$pbos->{'name'} $root/$pbos->{'name'}/$pbos->{'version'} $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}","Fixing permissions");
267
[1348]268 # Nothing more to do for VE. No real launch
269} else {
270 die "VE of type $vetype not supported. Report to the dev team";
271}
272}
273
274#
275# Return the postinstall line if needed
276#
277
278sub pb_ve_get_postinstall {
279
280my $pbos = shift;
281my $rbspi = shift;
282my $vestyle = shift;
283my $post = "";
284
285# Do we have a local post-install script
286if ($vestyle eq "rinse") {
287 $post = "--post-install ";
288} elsif ($vestyle eq "rpmbootstrap") {
289 $post = "-s ";
290}
291
292my $postparam = pb_distro_get_param($pbos,$rbspi);
293if ($postparam eq "") {
294 $post = "";
295} else {
296 $post .= $postparam;
297}
298return($post);
299}
300
301
302=head1 WEB SITES
303
304The 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/>.
305
306=head1 USER MAILING LIST
307
308None exists for the moment.
309
310=head1 AUTHORS
311
312The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
313
314=head1 COPYRIGHT
315
316Project-Builder.org is distributed under the GPL v2.0 license
317described in the file C<COPYING> included with the distribution.
318
319=cut
320
321
3221;
Note: See TracBrowser for help on using the repository browser.