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

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