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

Last change on this file since 1530 was 1530, checked in by bruno, 7 years ago
  • ossueminorrel option now initialized first, and correectly. Removes warnings.
  • other smaller fixes for CMD usage
File size: 10.3 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    }
[1519]110    # Handle cross arch on Intel based platforms
111    $sudocmd = "setarch i386 $sudocmd" if (($pbos->{arch} =~ /i?86/) && ($arch eq 'x86_64'));
[1348]112
[1506]113    my $root = pb_path_expand($vepath->{$ENV{PBPROJ}});
[1352]114    if (((defined $verebuild) && ($verebuild->{$ENV{'PBPROJ'}} =~ /true/i)) || ($pbforce == 1)) {
115        my ($verpmtype,$vedebtype) = pb_conf_get("verpmtype","vedebtype");
116        my ($rbsopt1) = pb_conf_get_if("rbsopt");
117
[1348]118        # We have to rebuild the chroot
119        if ($pbos->{'type'} eq "rpm") {
120   
121            # Which tool is used
122            my $verpmstyle = $verpmtype->{$ENV{'PBPROJ'}};
[1517]123            die "No verpmtype defined for $ENV{PBPROJ}" unless (defined $verpmstyle);
[1348]124   
125            # Get potential rbs option
126            my $rbsopt = "";
127            if (defined $rbsopt1) {
128                if (defined $rbsopt1->{$verpmstyle}) {
129                    $rbsopt = $rbsopt1->{$verpmstyle};
130                } elsif (defined $rbsopt1->{$ENV{'PBPROJ'}}) {
131                    $rbsopt = $rbsopt1->{$ENV{'PBPROJ'}};
132                } else {
133                    $rbsopt = "";
134                }
135            }
136   
137            my $postinstall = pb_ve_get_postinstall($pbos,$rbspi,$verpmstyle);
138            if ($verpmstyle eq "rinse") {
139                # Need to reshape the mirrors generated with local before-post-install script
140                my $b4post = "--before-post-install ";
141                my $postparam = pb_distro_get_param($pbos,$rbsb4pi);
142                if ($postparam eq "") {
143                    $b4post = "";
144                } else {
145                    $b4post .= $postparam;
146                }
147   
148                # Need to reshape the package list for pb
149                my $addpkgs;
150                $postparam = "";
151                $postparam .= pb_distro_get_param($pbos,$osmindep);
152                if ($postparam eq "") {
153                    $addpkgs = "";
154                } else {
155                    my $pkgfile = "$ENV{'PBTMP'}/addpkgs.lis";
156                    open(PKG,"> $pkgfile") || die "Unable to create $pkgfile";
157                    foreach my $p (split(/,/,$postparam)) {
158                        print PKG "$p\n";
159                    }
160                    close(PKG);
161                    $addpkgs = "--add-pkg-list $pkgfile";
162                }
163   
164                my $rinseverb = "";
165                $rinseverb = "--verbose" if ($pbdebug gt 0);
166                my ($rbsconf) = pb_conf_get("rbsconf");
167   
168                my $command = pb_check_req("rinse",0);
[1506]169                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]170            } elsif ($verpmstyle eq "rpmbootstrap") {
171                my $rbsverb = "";
172                foreach my $i (1..$pbdebug) {
173                    $rbsverb .= " -v";
174                }
175                my $addpkgs = "";
176                my $postparam = "";
177                $postparam .= pb_distro_get_param($pbos,$osmindep);
178                if ($postparam eq "") {
179                    $addpkgs = "";
180                } else {
181                    $addpkgs = "-a $postparam";
182                }
183                my $command = pb_check_req("rpmbootstrap",0);
184                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");
185            } elsif ($verpmstyle eq "mock") {
186                my ($rbsconf) = pb_conf_get("rbsconf");
187                my $command = pb_check_req("mock",0);
188                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'})");
189                # Once setup we need to install some packages, the pb account, ...
190                pb_system("$sudocmd $command --install --configdir=\"$rbsconf->{$ENV{'PBPROJ'}}\" -r $v su","Configuring the mock VE");
191            } else {
192                die "Unknown verpmtype type $verpmstyle. Report to dev team";
193            }
194        } elsif ($pbos->{'type'} eq "deb") {
195            my $vedebstyle = $vedebtype->{$ENV{'PBPROJ'}};
196       
197            my $codename = pb_distro_get_param($pbos,$oscodename);
198            my $postparam = "";
199            my $addpkgs;
200            $postparam .= pb_distro_get_param($pbos,$osmindep);
201            if ($postparam eq "") {
202                $addpkgs = "";
203            } else {
204                $addpkgs = "--include $postparam";
205            }
206            my $debmir = "";
207            $debmir .= pb_distro_get_param($pbos,$rbsmirrorsrv);
208   
209            # Get potential rbs option
210            my $rbsopt = "";
211            if (defined $rbsopt1) {
212                if (defined $rbsopt1->{$vedebstyle}) {
213                    $rbsopt = $rbsopt1->{$vedebstyle};
214                } elsif (defined $rbsopt1->{$ENV{'PBPROJ'}}) {
215                    $rbsopt = $rbsopt1->{$ENV{'PBPROJ'}};
216                } else {
217                    $rbsopt = "";
218                }
219            }
220   
221            # debootstrap works with amd64 not x86_64
222            my $debarch = $pbos->{'arch'};
223            $debarch = "amd64" if ($pbos->{'arch'} eq "x86_64");
224            if ($vedebstyle eq "debootstrap") {
225                my $dbsverb = "";
226                $dbsverb = "--verbose" if ($pbdebug gt 0);
227       
228                # Some perl modules are in Universe on Ubuntu
229                $rbsopt .= " --components=main,universe" if ($pbos->{'name'} eq "ubuntu");
230       
[1506]231                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");
[1348]232                # debootstrap doesn't create an /etc/hosts file
[1506]233                if (! -f "$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/etc/hosts" ) {
234                    pb_system("$sudocmd cp /etc/hosts $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}/etc/hosts");
[1348]235                }
236            } else {
237                die "Unknown vedebtype type $vedebstyle. Report to dev team";
238            }
239        } elsif ($pbos->{'type'} eq "ebuild") {
240            die "Please teach the dev team how to build gentoo chroot";
241        } else {
242            die "Unknown distribution type $pbos->{'type'}. Report to dev team";
243        }
244    }
245   
246    # Fix modes to allow access to the VE for pb user
[1506]247    pb_system("$sudocmd chmod 755 $root/$pbos->{'name'} $root/$pbos->{'name'}/$pbos->{'version'} $root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}","Fixing permissions");
[1348]248
249    # Test if an existing snapshot exists and use it if appropriate
250    # And also use it of no local extracted VE is present
[1506]251    if ((-f "$root/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.tar.gz") &&
[1348]252    (((defined $vesnap->{$v}) && ($vesnap->{$v} =~ /true/i)) ||
253        ((defined $vesnap->{$ENV{'PBPROJ'}}) && ($vesnap->{$ENV{'PBPROJ'}} =~ /true/i)) ||
254        ($pbsnap eq 1) ||
[1506]255        (! -d "$root/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}"))) {
256            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'}");
[1348]257    }
258    # Nothing more to do for VE. No real launch
259} else {
260    die "VE of type $vetype not supported. Report to the dev team";
261}
262}
263
264#
265# Return the postinstall line if needed
266#
267
268sub pb_ve_get_postinstall {
269
270my $pbos = shift;
271my $rbspi = shift;
272my $vestyle = shift;
273my $post = "";
274
275# Do we have a local post-install script
276if ($vestyle eq "rinse") {
277    $post = "--post-install ";
278} elsif ($vestyle eq "rpmbootstrap") {
279    $post = "-s ";
280}
281
282my $postparam = pb_distro_get_param($pbos,$rbspi);
283if ($postparam eq "") {
284    $post = "";
285} else {
286    $post .= $postparam;
287}
288return($post);
289}
290
291
292=head1 WEB SITES
293
294The 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/>.
295
296=head1 USER MAILING LIST
297
298None exists for the moment.
299
300=head1 AUTHORS
301
302The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
303
304=head1 COPYRIGHT
305
306Project-Builder.org is distributed under the GPL v2.0 license
307described in the file C<COPYING> included with the distribution.
308
309=cut
310
311
3121;
Note: See TracBrowser for help on using the repository browser.