source: devel/rpmbootstrap/bin/rpmbootstrap @ 2279

Last change on this file since 2279 was 2279, checked in by bruno, 23 months ago

YAML support working for most distros

  • Fix rebase issues
  • Adds a pbsyncheck script for pre-commit check
  • Fix test deps for centos & fedora
  • update pbcl versions for deb build
File size: 24.3 KB
Line 
1#!/usr/bin/perl -w
2#
3# rpmbootstrap application, a debootstrap like for RPM distros
4#
5# $Id$
6#
7# Copyright B. Cornec 2010-2016
8# Eric Anderson's changes are (c) Copyright 2012 Hewlett Packard
9# Provided under the GPL v2
10
11# Syntax: see at end
12
13use strict 'vars';
14use Getopt::Long qw(:config auto_abbrev no_ignore_case);
15use Data::Dumper;
16use English;
17use LWP::UserAgent;
18use File::Basename;
19use File::Copy;
20use File::Find;
21use ProjectBuilder::Version;
22use ProjectBuilder::Base;
23use ProjectBuilder::Env;
24use ProjectBuilder::Conf;
25use ProjectBuilder::Distribution;
26
27# Global variables
28my %opts;                   # CLI Options
29
30=pod
31
32=head1 NAME
33
34rpmbootstrap - creates a chrooted RPM based distribution a la debootstrap, aka Virtual Environment (VE)
35
36=head1 DESCRIPTION
37
38rpmbootstrap creates a chroot environment (Virtual Environment or VE)
39with a minimal distribution in it, suited for building packages for example.
40It's very much like debootstrap but for RPM based distribution.
41It aims at supporting all distributions supported by project-builder.org
42(RHEL, RH, Fedora, OpeSUSE, SLES, Mandriva, ...)
43
44It is inspired by work done by Steve Kemp for rinse (http://www.steve.org.uk/),
45and similar to mock or febootstrap, but fully integrated with project-builder.org
46(which also supports rinse and mock). Contrary to these, rpmbootstrap creates
47an environment where the packages commands are usable after build, as described
48hereafter.
49
50rpmbootstrap works in 2 phases. The first one is used to download all
51the required packages to have a working package management system in the
52chroot working. This list of packages is stored in /etc/pb/pb.yml under
53the rbsmindep parameter (aka rpmbootstrap minimal dependencies). Once the
54packages have been downloaded from the mirror, they are extracted with
55rpm2cpio. At that point you should be able to use yum on Fedora, urpmi
56on Mandriva/Mageia and zypper on OpenSuSE.
57The second phase uses exactly the previous mentioned tools to install
58exactly the same package list to have a coherent RPM db at the end.
59
60rpmbootstrap has additional options to execute a post-install script
61(-s) or to add packages (-a). Then pb can use the chroot to perform even
62more actions in it.
63
64=head1 SYNOPSIS
65
66rpmbootstrap [-vhmqpdk][-s script][-i image][-a pkg1[,pkg2,...]] distribution-version-arch [target-dir] [mirror [script]]
67
68rpmbootstrap [--verbose][--help][--man][--quiet][--print-rpms][--download-only]
69[--keep][--script script][--image image][--add pkg1,[pkg2,...]] distribution-version-arch [target-dir] [mirror [script]]
70
71=head1 OPTIONS
72
73=over 4
74
75=item B<-v|--verbose>
76
77Print a brief help message and exits.
78
79=item B<-h|--help>
80
81Print a brief help message and exits.
82
83=item B<--man>
84
85Prints the manual page and exits.
86
87=item B<-q|--quiet>
88
89Do not print any output.
90
91=item B<-p|--print-rpms>
92
93Print the packages to be installed, and exit.
94Note that a target directory must be specified so rpmbootstrap can determine
95which packages should be installed, and to resolve dependencies.
96The target directory will be deleted.
97
98=item B<-d|--download-only>
99
100Download packages, but don't perform installation.
101
102=item B<-k|--keep>
103
104Keep packages in the cache dir for later reuse. By default remove them.
105
106=item B<-s|--script script>
107
108Name of the script you want to execute on the related VEs after the installation.
109It is executed in host environment.
110You can use the chroot command to execute actions in the VE.
111
112=item B<-i|--image image>
113
114Name of the ISO image or the docker image of the distribution you want to install on the related VE.
115
116=item B<-a|--add pkg1[,pkg2,...]>
117
118Additional packages to add from the distribution you want to install on the related VE
119at the end of the chroot build.
120
121=item B<--no-stop-on-error>
122
123Continue through errors with best effort.
124
125=back
126
127=head1 ARGUMENTS
128
129=over 4
130
131=item B<distribution-version-arch>
132
133Full name of the distribution that needs to be installed in the VE. E.g. fedora-11-x86_64.
134
135=item B<target-dir>
136
137This is the target directory under which the VE will be created.
138Created on the fly if needed.
139If none is given use the default directory hosting VE for project-builder.org
140(Cf: vepath parameter in $HOME/.pbrc.yml)
141
142=back
143
144=head1 EXAMPLE
145
146To setup a Fedora 12 distribution with an i386 architecture issue:
147
148rpmbootstrap fedora-12-i386 /tmp/fedora/12/i386
149
150=head1 WEB SITES
151
152The main Web site of the project is available at L<http://www.project-builder.org/>.
153Bug reports should be filled using the trac instance of the project at L<http://trac.project-builder.org/>.
154
155=head1 USER MAILING LIST
156
157Cf: L<http://www.mondorescue.org/sympa/info/pb-announce> for announces and
158L<http://www.mondorescue.org/sympa/info/pb-devel> for the development of the pb project.
159
160=head1 CONFIGURATION FILE
161
162Uses Project-Builder.org configuration file (/etc/pb/pb.yml or /usr/local/etc/pb/pb.yml)
163
164=head1 AUTHORS
165
166The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
167
168=head1 COPYRIGHT
169
170Project-Builder.org is distributed under the GPL v2.0 license
171described in the file C<COPYING> included with the distribution.
172
173=cut
174
175# ---------------------------------------------------------------------------
176
177$Global::pb_stop_on_error = 1;
178my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
179my $appname = "rpmbootstrap";
180$ENV{'PBPROJ'} = $appname;
181
182# Initialize the syntax string
183
184pb_syntax_init("$appname Version $projectbuilderver-$projectbuilderrev\n");
185pb_temp_init();
186
187GetOptions("help|?|h" => \$opts{'h'}, 
188    "man|m" => \$opts{'man'},
189    "verbose|v+" => \$opts{'v'},
190    "quiet|q" => \$opts{'q'},
191    "log-files|l=s" => \$opts{'l'},
192    "script|s=s" => \$opts{'s'},
193    "print-rpms|p" => \$opts{'p'},
194    "download-only|d" => \$opts{'d'},
195    "keep|k" => \$opts{'k'},
196    "image|i=s" => \$opts{'i'},
197    "add|a=s" => \$opts{'a'},
198    "version|V=s" => \$opts{'V'},
199    "stop-on-error!" => \$Global::pb_stop_on_error,
200) || pb_syntax(-1,0);
201
202if (defined $opts{'h'}) {
203    pb_syntax(0,1);
204}
205if (defined $opts{'man'}) {
206    pb_syntax(0,2);
207}
208if (defined $opts{'v'}) {
209    $pbdebug = $opts{'v'};
210}
211if (defined $opts{'q'}) {
212    $pbdebug=-1;
213}
214if (defined $opts{'l'}) {
215    open(pbLOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
216    $pbLOG = \*pbLOG;
217    $pbdebug = 0  if ($pbdebug == -1);
218}
219pb_log_init($pbdebug, $pbLOG);
220#pb_display_init("text","");
221
222#if (defined $opts{'s'}) {
223#$pbscript = $opts{'s'};
224#}
225#if (defined $opts{'i'}) {
226#$image = $opts{'i'};
227#}
228
229# Get VE name
230$ENV{'PBV'} = shift @ARGV;
231die pb_syntax(-1,1) if (not defined $ENV{'PBV'});
232
233die "Needs to be run as root" if ($EFFECTIVE_USER_ID != 0);
234
235#
236# Initialize distribution info from pb conf file
237#
238pb_log(0,"Starting VE build for $ENV{'PBV'}\n");
239my $pbos = pb_distro_get_context($ENV{'PBV'});
240
241#
242# Check target dir
243# Create if not existent and use default if none given
244#
245pb_env_init_pbrc(); # to get content of HOME/.pbrc.yml
246my $vepath = shift @ARGV;
247
248#
249# Check for command requirements
250#
251my ($req,$opt) = pb_conf_get_if("oscmd","oscmdopt");
252pb_check_requirements($req,$opt,$appname);
253
254if (not defined $vepath) {
255    my ($vestdpath) = pb_conf_get("vepath");
256    $vepath = pb_path_expand("$vestdpath->{'default'}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}") if (defined $vestdpath->{'default'});
257}
258
259die pb_log(0,"No target-dir specified and no default vepath found in $ENV{'PBETC'}\n") if (not defined $vepath);
260
261# Cleanup first
262if ( -d $vepath) {
263    pb_rm_rf($vepath);
264}
265pb_mkdir_p($vepath);
266
267#
268# Get the package list to download, store them in a cache directory
269#
270my ($rbscachedir) = pb_conf_get_if("cachedir");
271my ($pkgs,$mirror) = pb_distro_get_param($pbos,pb_conf_get("rbsmindep","rbsmirrorsrv"));
272my ($updater) = pb_distro_get_param($pbos,pb_conf_get_if("rbsmirrorupd"));
273die "No packages defined for $pbos->{name}-$pbos->{version}-$pbos->{arch}" unless $pkgs =~ /\w/;
274
275my $cachedir = "/var/cache/rpmbootstrap";
276$cachedir = $rbscachedir->{'default'} if (defined $rbscachedir->{'default'});
277$cachedir = $rbscachedir->{$appname} if (defined $rbscachedir->{$appname});
278
279# Point to the right subdir and create it if needed
280$cachedir .= "/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}";
281pb_mkdir_p($cachedir) if (! -d $cachedir);
282
283# Get the complete package name from the mirror
284#
285my $ua = LWP::UserAgent->new;
286$ua->timeout(10);
287$ua->env_proxy;
288
289die "No mirror defined for $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}" if ((not defined $mirror) || ($mirror =~ /^\t*$/));
290my $resp;
291my $repo;
292my %list_pkg;
293
294($repo,$resp) = rbs_mirror_response($mirror);
295foreach my $r (split(/\n/,$resp->as_string())) {
296    $list_pkg{$r} = $mirror;
297}
298
299# If an update source is availble add it after so that these pkgs update the main ones
300if (defined $updater) {
301    my $void;
302    ($void,$resp) = rbs_mirror_response($mirror.$updater);
303    foreach my $r (split(/\n/,$resp->as_string())) {
304        $list_pkg{$r} = $mirror.$updater;
305    }
306}
307
308# Manages architectures specificities
309my $parch = $pbos->{'arch'};
310$parch = "i[3456]86" if ($pbos->{'arch'} eq "i386");
311
312# Get the list of packages and their URL in this hash
313my %url;
314my %done;
315foreach my $l (keys %list_pkg) {
316    my ($url,$desc) = rbs_find_pkg($l,$parch,"pkg");
317    if (defined $url) {
318        $url{$url} = "$list_pkg{$l}/$desc";
319    } else {
320        pb_log(3,"not a package, maybe a dir containing packages\n");
321        ($url,$desc) = rbs_find_pkg($l,$parch,"dir");
322        if ((defined $desc) and (not defined $done{$desc})) {
323            my $response1 = $ua->get("$mirror/$desc");
324            # Check if we have a fedora 17/18 type of repo
325            if ($response1->is_success) {
326                $done{$desc} = "true";
327                foreach my $d (split(/\n/,$response1->as_string())) {
328                    my ($url2,$desc2) = rbs_find_pkg($d,$parch,"pkg");
329                    if (defined $url2) {
330                        # Here we have the dir in which are packages
331                        $url{$url2} = "$mirror/$desc/$desc2";
332                    } else {
333                        pb_log(3,"not a package, and not a dir containing packages\n");
334                    }
335                }
336            } else {
337            }
338        }
339    }
340}
341
342#
343# Prepare early the yum cache env for the VE in order to copy in it packages on the fly
344#
345my $oscachedir = "/tmp";
346my $osupdcachedir;
347my $osupdname = "";
348
349if ($pbos->{'install'} =~ /yum/) {
350    $oscachedir = "$vepath/var/cache/yum/core/packages/";
351    $osupdcachedir = "$vepath/var/cache/yum/updates-released/packages/";
352    $osupdname = "YUM";
353    # Recent Fedora release use a new yum cache dir
354    if (($pbos->{'name'} eq "fedora") && ($pbos->{'version'} > 8)) {
355        $oscachedir = "$vepath/var/cache/yum/$pbos->{'arch'}/$pbos->{'version'}/fedora/packages";
356        #$osupdcachedir = "$vepath/var/cache/yum/$pbos->{'arch'}/$pbos->{'version'}/updates/packages";
357        $osupdcachedir = "$vepath/var/cache/yum/updates-released/packages/";
358    }
359} elsif ($pbos->{'install'} =~ /dnf/) {
360    $osupdname = "DNF";
361    $oscachedir = "$vepath/var/cache/dnf/$pbos->{'arch'}/$pbos->{'version'}/fedora/packages";
362    $osupdcachedir = "$vepath/var/cache/dnf/updates-released/packages/";
363} elsif ($pbos->{'install'} =~ /zypper/) {
364    $oscachedir = "$vepath/var/cache/zypp/packages/opensuse/suse/$pbos->{'arch'}";
365    $osupdname = "Zypper";
366} elsif ($pbos->{'install'} =~ /urpmi/) {
367    $oscachedir = "$vepath/var/cache/urpmi/rpms";
368    $osupdname = "URPMI";
369}
370pb_log(1,"Setting up $osupdname cache in VE\n");
371pb_mkdir_p($oscachedir);
372pb_mkdir_p($osupdcachedir) if (defined $osupdcachedir);
373
374# For each package to process, get it, put it in the cache dir
375# and extract it in the target dir. If not asked to keep, remove it
376# Just download if asked so.
377
378my $warning = 0;
379my $lwpkg ="";
380my @installed_packages;
381
382# On systemd systems, the pkg needs to be first
383# to have the correct links made first
384if ($pkgs =~ /,filesystem,/) {
385    $pkgs =~ s/,filesystem,/,/;
386    $pkgs = "filesystem,".$pkgs;
387}
388
389foreach my $p (split(/,/,$pkgs)) {
390    $p =~ s/\s+//go;
391    pb_log(1,"Processing package $p ...\n");
392    # Just print packages names if asked so.
393    if (defined $url{$p}) {
394        if ($opts{'p'}) {
395            pb_log(0,"$url{$p}\n");
396            next;
397        } else {
398            # Now download if not already in cache
399            my $p1 = basename($url{$p});
400            if (! -f "$cachedir/$p1") {
401                pb_system("wget --tries=5 --quiet -O $cachedir/$p1-new $url{$p}","Downloading package $p1 ...");
402                rename("$cachedir/$p1-new", "$cachedir/$p1") || die "mv $cachedir/$p1-new $cachedir/$p1 failed: $!";
403            } else {
404                pb_log(1,"Package $p1 already in cache\n");
405            }
406       
407            # End if download only
408            if ($opts{'d'}) {
409                next;
410            }
411   
412            #
413            # Copy the cached .RPM files into the oscachedir directory, so that os doesn't need to download them again.
414            #
415            pb_log(1,"Link package into $oscachedir\n");
416            copy("$cachedir/$p1",$oscachedir) if (defined $oscachedir);
417            symlink("$oscachedir/$p1","$osupdcachedir/p1") if (defined $osupdcachedir);
418
419            # And extract it to the finale dir
420            pb_system("cd $vepath ; rpm2cpio $cachedir/$p1 | cpio -ivdum --extract-over-symlinks","Extracting package $p1 into $vepath");
421       
422            # Remove cached package if not asked to keep
423            if (! $opts{'k'}) {
424                unlink("$cachedir/$p1");
425            }
426            push(@installed_packages, $p);
427        }
428    } else {
429        pb_log(0,"WARNING: unable to find URL for $p\n");
430        $warning++;
431        $lwpkg .= " $p";
432    }
433}
434
435if ($warning ge 1) {
436pb_log(0,"$warning WARNINGS found.\nMaybe you should review your package list for $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}\nand remove$lwpkg\n");
437}
438
439# Stop here if we just print
440if ($opts{'p'}) {
441    pb_exit(0);
442}
443
444# Now executes the VE finalization steps required for it to work correctly
445pb_log(0,"VE post configuration\n");
446
447# yum needs that distro-release package be installed, so force it
448if (($pbos->{'install'} =~ /yum/) || ($pbos->{'install'} =~ /dnf/)) {
449    my $ddir = $pbos->{'name'};
450    foreach my $p1 (<$cachedir/($ddir|redhat)-release-*.rpm>) {
451        copy("$cachedir/$p1","$vepath/tmp");
452        pb_system("chroot $vepath rpm -ivh --force --nodeps /tmp/$p1","Forcing RPM installation of $p1");
453        unlink("$vepath/tmp/$p1");
454    }
455# RedHat 6.2 has a buggy termcap setup and doesn't support usage of setarch, so still returns x86_64 in a chroot
456} elsif (($pbos->{'name'} =~ /redhat/) && ( $pbos->{'version'} =~ /^6/)) {
457    pb_system("chroot $vepath ldconfig","Forcing ldconfig on $pbos->{'name'} $pbos->{'version'}");
458    pb_system("chroot $vepath echo 'arch_canon:     x86_64: x86_64  1' >> /etc/rpmrc","Forcing ldconfig on $pbos->{'name'} $pbos->{'version'}");
459    pb_system("chroot $vepath echo 'arch_compat: x86_64: i386' >> /etc/rpmrc","Forcing ldconfig on $pbos->{'name'} $pbos->{'version'}");
460    pb_system("chroot $vepath echo 'buildarch_compat: x86_64: i386' >> /etc/rpmrc","Forcing ldconfig on $pbos->{'name'} $pbos->{'version'}");
461    pb_system("chroot $vepath echo 'buildarchtranslate: x86_64: i386' >> /etc/rpmrc","Forcing ldconfig on $pbos->{'name'} $pbos->{'version'}");
462}
463#
464# Make sure there is a resolv.conf file present, such that DNS lookups succeed.
465#
466pb_log(1,"Creating resolv.conf\n");
467pb_mkdir_p("$vepath/etc");
468copy("/etc/resolv.conf","$vepath/etc/");
469
470#
471# BUGFIX:
472#
473if ((($pbos->{'name'} eq "centos") || ($pbos->{'name'} eq "rhel")) && ($pbos->{'version'} eq "5")) {
474    pb_log(1,"BUGFIX for centos-5\n");
475    pb_mkdir_p("$vepath/usr/lib/python2.4/site-packages/urlgrabber.skx");
476    foreach my $i (<$vepath/usr/lib/python2.4/site-packages/urlgrabber/keepalive.*>) {
477        move($i,"$vepath/usr/lib/python2.4/site-packages/urlgrabber.skx/");
478    }
479}
480
481#
482# /proc needed
483#
484pb_mkdir_p("$vepath/proc");
485pb_system("mount -o bind /proc $vepath/proc","Mounting /proc") unless (-d "$vepath/proc/$$");
486
487#
488# Some devices may be needed
489#
490pb_mkdir_p("$vepath/dev");
491chmod 0755,"$vepath/dev";
492pb_system("mknod -m 644 $vepath/dev/random c 1 8","Creating $vepath/dev/random") if (! -c "$vepath/dev/random");
493pb_system("mknod -m 644 $vepath/dev/urandom c 1 9","Creating $vepath/dev/urandom") if (! -c "$vepath/dev/urandom");
494pb_system("mknod -m 666 $vepath/dev/zero c 1 5","Creating $vepath/dev/zero") if (! -c "$vepath/dev/zero");
495pb_system("mknod -m 666 $vepath/dev/null c 1 3","Creating $vepath/dev/null") if (! -c "$vepath/dev/null");
496
497# Where is bash
498my $bash = "/usr/bin/bash";
499if (! -x "$vepath/$bash" ) {
500    $bash = "/bin/bash";
501    if (! -x "$vepath/$bash" ) {
502        die "No bash found in usual places. Please report to dev team";
503    }
504}
505   
506
507my $minipkglist;
508
509pb_log(1,"Adapting $osupdname repository entries\n");
510if (($pbos->{'install'} =~ /yum/) || ($pbos->{'install'} =~ /dnf/)) {
511    #
512    # Force the architecture for yum/dnf
513    # The goal is to allow i386 chroot on x86_64
514    #
515    # FIX: Not sufficient to have yum/dnf working
516    # mirrorlist is not usable
517    # $releasever also needs to be filtered
518    # yum.conf as well
519    foreach my $i (<$vepath/etc/yum.repos.d/*.repo>,"$vepath/etc/yum.conf","$vepath/etc/dnf/dnf.conf") {
520        pb_system("sed -i -e 's/\$basearch/$pbos->{'arch'}/g' $i","","quiet");
521        pb_system("sed -i -e 's/\$releasever/$pbos->{'version'}/g' $i","","quiet");
522        pb_system("sed -i -e 's/^mirrorlist/#mirrorlist/' $i","","quiet");
523        pb_system("sed -i -e 's/^metalink/#metalink/' $i","","quiet");
524        # rather use neutral separators here
525        pb_system("sed -i -e 's|^#baseurl.*\$|baseurl=$repo|' $i","","quiet");
526    }
527    my $pkgmgr = "";
528    if ($pbos->{'install'} =~ /yum/) {
529        $pkgmgr = "yum";
530    }
531    if ($pbos->{'install'} =~ /dnf/) {
532        $pkgmgr = "dnf";
533    }
534    $minipkglist = "ldconfig $pkgmgr passwd vim-minimal dhclient authconfig";
535} elsif ($pbos->{'install'} =~ /zypper/) {
536    pb_mkdir_p("$vepath/etc/zypp/repos.d");
537    open(REPO,"> $vepath/etc/zypp/repos.d/$pbos->{'name'}-$pbos->{'version'}") || die "Unable to create repo file";
538    my $baseurl = dirname(dirname($mirror));
539    # Setup the repo
540    if ($pbos->{'version'} eq "10.2") {
541        pb_system("chroot $vepath $bash -c \"yes | /usr/bin/zypper sa $baseurl $pbos->{'name'}-$pbos->{'version'}\"","Bootstrapping Zypper");
542    } else {
543        # don't care if remove fails if add succeeds.
544        pb_system("chroot $vepath $bash -c \"/usr/bin/zypper rr $pbos->{'name'}-$pbos->{'version'}\"","Bootstrapping Zypper","mayfail");
545        pb_system("chroot $vepath $bash -c \"/usr/bin/zypper ar $baseurl $pbos->{'name'}-$pbos->{'version'}\"","Bootstrapping Zypper");
546    }
547    #print REPO << "EOF";
548#[opensuse]
549#name=$pbos->{'name'}-$pbos->{'version'}
550#baseurl=$baseurl
551#enabled=1
552#gpgcheck=1
553#
554#EOF
555    close(REPO);
556    $minipkglist = "zypper aaa_base";
557    # TODO: Re-installing packages missing and necessary on opensuse 11.4 to get /etc/passwd created.
558} elsif ($pbos->{'install'} =~ /urpmi/) {
559    # Setup the repo
560    my $baseurl = dirname(dirname(dirname($mirror)));
561    pb_system("chroot $vepath $bash -c \"urpmi.addmedia --distrib $baseurl\"","Bootstrapping URPMI");
562    # TODO here too ?
563    $minipkglist = "ldconfig urpmi bash passwd vim-minimal dhcp-client";
564} elsif ($pbos->{'install'} =~ /\/rpm/) {
565    opendir(CDIR,$cachedir) || die "Unable to open directory $cachedir: $!";
566    foreach my $p (@installed_packages) {
567        foreach my $f (readdir(CDIR)) {
568            # find an rpm package ref name-ver-tag.arch.rpm
569            next if ($f =~ /^\./);
570            if ($f =~ /^$p-([^-]+)-([^-]+)\.(noarch|$parch)\.rpm$/) {
571                # Copy it to the chroot and reference it
572                copy("$cachedir/$f","$vepath/var/cache");
573                $minipkglist .= " /var/cache/$f"; 
574                last;
575            }
576        }
577        rewinddir(CDIR);
578    }
579    closedir(CDIR);
580}
581
582#
583# Run "install the necessary modules".
584# No need for sudo here
585#
586$pbos->{'install'} =~ s/sudo//g;
587if (((defined $ENV{http_proxy}) && ($ENV{http_proxy} ne '')) || ((defined $ENV{https_proxy}) && ($ENV{https_proxy} ne '')) || ((defined $ENV{ftp_proxy}) && ($ENV{ftp_proxy} ne ''))) {
588    if ($pbos->{'name'} eq "opensuse") {
589        # For opensuse 11.4 or 12.1 -- one of them didn't work with http_proxy or HTTP_PROXY set.
590        open(PROXY, "> $vepath/etc/sysconfig/proxy") || die "can't open $vepath/etc/sysconfig/proxy: $!";
591        print PROXY "HTTP_PROXY=$ENV{http_proxy}\n" if ((defined $ENV{http_proxy}) && ($ENV{http_proxy} ne ''));
592        print PROXY "HTTPS_PROXY=$ENV{https_proxy}\n" if ((defined $ENV{https_proxy}) && ($ENV{https_proxy} ne ''));
593        print PROXY "FTP_PROXY=$ENV{ftp_proxy}\n" if ((defined $ENV{ftp_proxy}) && ($ENV{ftp_proxy} ne ''));
594        close(PROXY);
595    }
596}
597
598# Keep redhat variants from destroying nis domain on install
599#pb_system("chroot $vepath $bash -e -c \"ln -snf /bin/true /bin/domainname\"");
600
601#if ($pbos->{'name'} =~ /fedora/i) { # hack to prevent fedora from destroying NIS settings on host
602#   open (AUTH, ">$vepath/etc/pam.d/system-auth-ac") || die "unable to open $vepath/etc/pam.d/system-auth-ac for write: $!";
603#   print AUTH "#pam_systemd -- will fix later in bootstrap\n";
604#   close(AUTH);
605#}
606pb_system("chroot $vepath $bash -c \"$pbos->{'install'} $minipkglist \"","Bootstrapping OS by running $pbos->{'install'} $minipkglist");
607
608# CentOS6 will replace the yum.repos.d files; oddly it will leave the yum.conf file alone and make the new one ".rpmnew"
609if (($pbos->{'name'} eq "centos") && ($pbos->{'version'} =~ /^6.*/)) {
610    pb_log(0,"Fixing $pbos->{'name'} $pbos->{'version'} bug for yum conf files");
611    foreach my $from (<$vepath/etc/yum.repos.d/*.rpmorig>) {
612        my $to = $from;
613        $to =~ s/.rpmorig$//;
614        pb_system("mv $from $to", "Recover $from");
615    }
616}
617
618#
619# make 'passwd' work.
620#
621pb_log(1,"Authfix\n");
622# TODO: Not generic enough to be done like that IMHO
623# In case it was changed during the install
624#pb_system("chroot $vepath $bash -e -c \"ln -snf /bin/true /bin/domainname\"");
625pb_system("chroot $vepath $bash -c \"if [ -x /usr/bin/authconfig ]; then /usr/bin/authconfig --enableshadow --update --nostart; fi\"","Calling authconfig");
626
627# Installed additional packages we were asked to
628if (defined $opts{'a'}) {
629    $opts{'a'} =~ s/,/ /g;
630    pb_system("chroot $vepath $bash -c \"$pbos->{'install'} $opts{'a'} \"","Adding packages to OS by running $pbos->{'install'} $opts{'a'}");
631}
632
633#
634# Clean up
635#
636pb_log(1,"Cleaning up\n");
637if ($pbos->{'install'} =~ /yum/) {
638    pb_system("chroot $vepath /usr/bin/yum clean all","Cleaning yum");
639}
640if ($pbos->{'install'} =~ /dnf/) {
641    pb_system("chroot $vepath /usr/bin/dnf clean all","Cleaning dnf");
642}
643pb_system("umount $vepath/proc","Unmounting /proc");
644find(\&unlink_old_conf, $vepath);
645
646# Executes post-install step if asked for
647if ($opts{'s'}) {
648    pb_system("$opts{'s'} $vepath","Executing the post-install script: $opts{'s'} $vepath");
649}
650
651if ($warning > 0) {
652    pb_log(0,"\n\n\n\n$warning WARNINGS found.\nMaybe you should review your package list for $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}\nand remove$lwpkg\n");
653    pb_log(0,"waiting 60 seconds to give you a chance to notice.\n");
654    sleep(60);
655}
656
657pb_exit();
658
659# Function for File::Find
660sub unlink_old_conf {
661
662    unlink($_) if ($_ =~ /\.rpmorig$/);
663    unlink($_) if ($_ =~ /\.rpmnew$/);
664}
665
666# Function to store packages found on Web pages
667
668sub rbs_find_pkg {
669
670my $l = shift;
671my $parch = shift;
672my $type = shift;
673
674pb_log(2,"Entering rbs_find_pkg with l=$l and parch=$parch\n");
675# Find a href ref in first pos
676if ($l =~ /<a href="([^<>]*)">([^<>]*)<\/a>/i) {
677    my $pkg = $1;
678    my $desc = $2;
679    pb_log(3,"Found desc URL $desc: ");
680    # find an rpm package ref name-ver-tag.arch.rpm
681    if (($type eq "pkg") && ($pkg =~ /(.+)-([^-]+)-([^-]+)\.(noarch|$parch)\.rpm$/)) {
682        pb_log(3,"package ($1 + $2 + $3 + $4)\n");
683        my $url = $1;
684        pb_log(2,"Exiting rbs_find_pkg with url=$url and desc=$desc\n");
685        return($url,$pkg);
686    } elsif (($type eq "dir") && ($pkg =~ /([0-z])\//)) {
687        my $url = $1;
688        pb_log(3,"dir ($1)\n");
689        return($url,$1);
690    } else {
691        pb_log(3,"not a package\n");
692    }
693}
694pb_log(2,"Exiting rbs_find_pkg with undef\n");
695return(undef,undef);
696}
697
698sub rbs_mirror_response {
699
700my $mirror = shift;
701
702pb_log(0,"Downloading package list from $mirror ...\n");
703my $response = $ua->get($mirror);
704if (! $response->is_success) {
705    if ($mirror =~ /i386/) {
706        # Some distro have an i586 or i686 mirror dir instead for i386
707        warn "Unable to download package from $mirror for $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}.".$response->status_line;
708        $mirror =~ s|/i386/|/i586/|;
709        pb_log(0,"Downloading now package list from $mirror ...\n");
710        $response = $ua->get($mirror);
711        if (! $response->is_success) {
712            die "Unable to download package from $mirror for $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}".$response->status_line;
713        }
714    }
715}
716pb_log(3,"Mirror $mirror gave answer: ".Dumper($response->dump(maxlength => 0))."\n");
717
718# Try to find where the repodata structure is for later usage
719my $repo = $mirror;
720my $found = 0;
721if (($pbos->{'install'} =~ /yum/) || ($pbos->{'install'} =~ /dnf/)) {
722    my $response1;
723    while ($found == 0) {
724        $response1 = $ua->get("$repo/repodata");
725        pb_log(2,"REPO analyzed: $repo\n");
726        if (! $response1->is_success) {
727            $repo = dirname($repo);
728
729            # There is a limit to the loop, when / is reached and nothing found
730            my ($scheme, $account, $host, $port, $path) = pb_get_uri($repo);
731            die "Unable to find the repodata structure of the mirror $mirror\nPlease check the URL or warn the dev team.\n" if (($path =~ /^[\/]+$/) || ($path =~ /^$/));
732       
733            # / not reached, so looping
734            next;
735        } else {
736            # repodata found $repo is correct
737            $found = 1;
738            pb_log(2,"REPO found: $repo\n");
739            last;
740        }
741    }
742}
743return($repo,$response);
744}
745
Note: See TracBrowser for help on using the repository browser.