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

Last change on this file since 1646 was 1646, checked in by Bruno Cornec, 12 years ago
  • Really use snapshot for launchve when needed. fix some parts of the condition which were wrong.
File size: 10.8 KB
Line 
1#!/usr/bin/perl -w
2#
3# Common functions for virtual environment
4#
5# Copyright B. Cornec 2007-2012
6# Eric Anderson's changes are (c) Copyright 2012 Hewlett Packard
7# Provided under the GPL v2
8#
9# $Id$
10#
11
12package ProjectBuilder::VE;
13
14use strict;
15use Data::Dumper;
16use Carp 'confess';
17use English;
18use ProjectBuilder::Version;
19use ProjectBuilder::Base;
20use ProjectBuilder::Conf;
21use ProjectBuilder::Distribution;
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 $locsnap = 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
79confess "No vetype defined for $ENV{PBPROJ}" unless (defined $vetype);
80pb_log(1, "Using vetype $vetype for $ENV{PBPROJ}\n");
81
82if (($vetype eq "chroot") || ($vetype eq "schroot")) {
83
84 # We need to avoid umask propagation to the VE
85 umask 0022;
86
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");
89
90 # Architecture consistency
91 my $arch = pb_get_arch();
92 if ($arch ne $pbos->{'arch'}) {
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"));
94 }
95
96 # If we are already root (from pbmkbm e.g.) don't use sudo, just call the command
97 my $sudocmd="";
98 if ($EFFECTIVE_USER_ID != 0) {
99 $sudocmd ="sudo ";
100 foreach my $proxy (qw/http_proxy ftp_proxy/) {
101 if (defined $ENV{$proxy}) {
102 open(CMD,"sudo sh -c 'echo \$$proxy' |") or die "can't run sudo sh?: $!";
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};
106 close(CMD);
107 }
108 }
109 }
110
111 # Handle cross arch on Intel based platforms
112 $sudocmd = "setarch i386 $sudocmd" if (($pbos->{'arch'} =~ /i[3456]86/) && ($arch eq 'x86_64'));
113
114 my $root = pb_path_expand($vepath->{$ENV{PBPROJ}});
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
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'}};
124 die "No verpmtype defined for $ENV{PBPROJ}" unless (defined $verpmstyle);
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);
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");
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");
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");
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
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");
236 # debootstrap doesn't create an /etc/hosts file
237 if (! -f "$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/etc/hosts" ) {
238 my $cmd = pb_check_req("cp",0);
239 pb_system("$sudocmd $cmd /etc/hosts $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/etc/hosts");
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
253 if ((-f "$root/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz") &&
254 (((defined $vesnap->{$v}) && ($vesnap->{$v} =~ /true/i)) ||
255 ((defined $vesnap->{$ENV{'PBPROJ'}}) && ($vesnap->{$ENV{'PBPROJ'}} =~ /true/i))) &&
256 ($locsnap eq 1) &&
257 (! -d "$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}")) {
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'}");
262 }
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
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.