source: ProjectBuilder/devel/rpmbootstrap/bin/rpmbootstrap@ 983

Last change on this file since 983 was 983, checked in by Bruno Cornec, 14 years ago
  • rpmbootstrap good up to package name identification
  • fedora-12 package list updated
File size: 8.0 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
8# Provided under the GPL v2
9
10# Syntax: see at end
11
12use strict 'vars';
13use Getopt::Long qw(:config auto_abbrev no_ignore_case);
14use Data::Dumper;
15use English;
16use LWP::UserAgent;
17#use File::Basename;
18#use File::Copy;
19use ProjectBuilder::Version;
20use ProjectBuilder::Base;
21use ProjectBuilder::Env;
22use ProjectBuilder::Conf;
23use ProjectBuilder::Distribution;
24
25# Global variables
26my %opts; # CLI Options
27
28=pod
29
30=head1 NAME
31
32rpmbootstrap - creates a chrooted RPM based distribution a la debootstrap, aka Virtual Environment (VE)
33
34=head1 DESCRIPTION
35
36rpmbootstrap creates a chroot environment (Virtual Environment or VE) with a minimal distribution in it,
37suited for building packages for example. It's very much like debootstrap but for RPM based distribution.
38It aims at supporting all distributions supported by project-builder;org (RHEL, RH, Fedora, OpeSUSE, SLES, Mandriva, ...)
39
40It is inspired by work done by Steve Kemp for rinse (http://www.steve.org.uk/), and similar to mock, but fully integrated with project-builder.org (which also supports rinse and mock).
41
42=head1 SYNOPSIS
43
44rpmbootstrap [-vhmqpdk][-s script][-i iso] distribution-version-arch [target-dir] [mirror [script]]
45
46pb [--verbose][--help][--man][--quiet][--print-rpms][--download-only][--keep][--include pkg1, pkg2, ...][--script script][--iso iso] distribution-version-arch [target-dir] [mirror [script]]
47
48=head1 OPTIONS
49
50=over 4
51
52=item B<-v|--verbose>
53
54Print a brief help message and exits.
55
56=item B<-h|--help>
57
58Print a brief help message and exits.
59
60=item B<--man>
61
62Prints the manual page and exits.
63
64=item B<-q|--quiet>
65
66Do not print any output.
67
68=item B<-p|--print-rpms>
69
70Print the packages to be installed, and exit. Note that a target directory must be specified so
71rpmbootstrap can determine which packages should be installed, and to resolve dependencies. The target directory will be deleted.
72
73=item B<-d|--download-only>
74
75Download packages, but don't perform installation.
76
77=item B<-k|--keep>
78
79Keep packages in the cache dir for later reuse. By default remove them.
80
81=item B<-s|--script script>
82
83Name of the script you want to execute on the related VEs after the installation.
84
85=item B<-i|--iso iso_image>
86
87Name of the ISO image of the distribution you want to install on the related VE.
88
89=back
90
91=head1 ARGUMENTS
92
93=item B<distribution-version-arch>
94
95Full name of the distribution that needs to be installed in the VE. E.g. fedora-11-x86_64.
96
97=item B<target-dir>
98
99This is the target directory under which the VE will be created. Created on the fly if needed. If none is given use the default directory hosting VE for project-builder.org (Cf: vepath parameter in $HOME/.pbrc)
100
101=head1 EXAMPLE
102
103To setup a Fedora 12 distribution with an i386 architecture issue:
104
105rpmbootstrap fedora-12-i386 /tmp/fedora/12/i386
106
107
108=head1 WEB SITES
109
110The 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/>.
111
112=head1 USER MAILING LIST
113
114Cf: L<http://www.mondorescue.org/sympa/info/pb-announce> for announces and L<http://www.mondorescue.org/sympa/info/pb-devel> for the development of the pb project.
115
116=head1 CONFIGURATION FILE
117
118Uses Project-Builder.org configuration file (/etc/pb/pb.conf or /usr/local/etc/pb/pb.conf)
119
120=head1 AUTHORS
121
122The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
123
124=head1 COPYRIGHT
125
126Project-Builder.org is distributed under the GPL v2.0 license
127described in the file C<COPYING> included with the distribution.
128
129=cut
130
131# ---------------------------------------------------------------------------
132
133my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
134my $appname = "rpmbootstrap";
135$ENV{'PBPROJ'} = $appname;
136
137# Initialize the syntax string
138
139pb_syntax_init("$appname Version $projectbuilderver-$projectbuilderrev\n");
140
141GetOptions("help|?|h" => \$opts{'h'},
142 "man|m" => \$opts{'man'},
143 "verbose|v+" => \$opts{'v'},
144 "quiet|q" => \$opts{'q'},
145 "log-files|l=s" => \$opts{'l'},
146 "script|s=s" => \$opts{'s'},
147 "print-rpms|p" => \$opts{'p'},
148 "download-only|d" => \$opts{'d'},
149 "keep|k" => \$opts{'k'},
150 "iso|i=s" => \$opts{'i'},
151 "version|V=s" => \$opts{'V'},
152) || pb_syntax(-1,0);
153
154if (defined $opts{'h'}) {
155 pb_syntax(0,1);
156}
157if (defined $opts{'man'}) {
158 pb_syntax(0,2);
159}
160if (defined $opts{'v'}) {
161 $pbdebug = $opts{'v'};
162}
163if (defined $opts{'q'}) {
164 $pbdebug=-1;
165}
166if (defined $opts{'l'}) {
167 open(pbLOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
168 $pbLOG = \*pbLOG;
169 $pbdebug = 0 if ($pbdebug == -1);
170 }
171pb_log_init($pbdebug, $pbLOG);
172#pb_display_init("text","");
173
174#if (defined $opts{'s'}) {
175#$pbscript = $opts{'s'};
176#}
177#if (defined $opts{'i'}) {
178#$iso = $opts{'i'};
179#}
180
181# Get VE name
182$ENV{'PBV'} = shift @ARGV;
183die pb_syntax(-1,1) if (not defined $ENV{'PBV'});
184
185die "Needs to be run as root" if ($EFFECTIVE_USER_ID != 0);
186
187#
188# Initialize distribution info from pb conf file
189#
190my ($name,$ver,$darch) = split(/-/,$ENV{'PBV'});
191chomp($darch);
192my ($ddir, $dver, $dfam, $dtype, $pbsuf, $dsuf, $dupd) = pb_distro_init($name,$ver,$darch);
193
194#
195# Check target dir
196# Create if not existent and use default if none given
197#
198pb_env_init_pbrc(); # to get content of HOME/.pbrc
199my $vepath = shift @ARGV;
200
201#
202# Check for command requirements
203#
204my ($req,$opt) = pb_conf_get_if("oscmd","oscmdopt");
205my ($req2,$opt2) = (undef,undef);
206$req2 = $req->{$appname} if (defined $req);
207$opt2 = $opt->{$appname} if (defined $opt);
208pb_check_requirements($req2,$opt2);
209
210if (not defined $vepath) {
211 my ($vestdpath) = pb_conf_get_if("vepath");
212 $vepath = "$vestdpath->{'default'}/$ddir/$dver/$darch";
213}
214
215die pb_log(0,"No target-dir specified and no default vepath found in $ENV{'PBETC'}\n") if (not defined $vepath);
216
217pb_mkdir_p($vepath) if (! -d $vepath);
218
219#
220# Get the package list to download, store them in a cache directory
221#
222my ($rbsmindep,$rbsmirrorsrv) = pb_conf_get("rbsmindep","rbsmirrorsrv");
223my ($rbscachedir) = pb_conf_get_if("rbscachedir");
224my $pkgs = pb_distro_get_param($ddir,$dver,$darch,$rbsmindep);
225my $mirror = pb_distro_get_param($ddir,$dver,$darch,$rbsmirrorsrv);
226
227my $cachedir = "/var/cache/rpmbootstrap";
228$cachedir = $rbscachedir->{'default'} if (defined $rbscachedir->{'default'});
229
230# Point to the right subdir and create it if needed
231$cachedir .= "/$ddir-$dver-$darch";
232pb_mkdir_p($cachedir) if (! -d $cachedir);
233
234# Get the complete package name from the mirror
235#
236my $ua = LWP::UserAgent->new;
237$ua->timeout(10);
238$ua->env_proxy;
239
240my $response = $ua->get($mirror);
241if (! $response->is_success) {
242 die "Unable to download packages from $mirror for $ddir-$dver-$darch";
243}
244pb_log(3,"Mirror $mirror gave answer: ".Dumper($response->dump(maxlength => 0))."\n");
245
246# Manages architectures specificities
247my $parch = $darch;
248$parch = "i?86" if ($darch eq "i386");
249
250# Get the list of packages and their URL in this hash
251my %url;
252foreach my $l (split(/\n/,$response->as_string())) {
253 # Find a href ref
254 if ($l =~ /<a href="(.*)">(.*)<\/a>/i) {
255 my $url = $1;
256 my $pkg = $1;
257 my $desc = $2;
258 pb_log(3,"Found desc URL $desc: ");
259 # find an rpm package ref name-ver-tag.arch.rpm
260 if ($pkg =~ /(.+)-([^-]+)-([^-]+)\.(noarch|$parch)\.rpm$/) {
261 pb_log(3,"package ($1 + $2 + $3 + $4)\n");
262 $url{$1} = "$mirror/$url";
263 } else {
264 pb_log(3,"not a package\n");
265 }
266 }
267}
268
269
270# For each package to process, get it, put it in the cache dir
271# and extract it in the target dir. If not asked to keep, remove it
272# Just download if asked so.
273
274my $warning = 0;
275my $lwpkg ="";
276foreach my $p (split(/,/,$pkgs)) {
277 pb_log(1,"Processing package $p ...\n");
278 # Just print packages names if asked so.
279 if ($opts{'p'}) {
280 if (defined $url{$p}) {
281 pb_log(0,"$url{$p}\n");
282 } else {
283 pb_log(0,"WARNING: unable to find URL for $p\n");
284 $warning++;
285 $lwpkg .= " $p";
286 }
287 next;
288 }
289}
290
291if ($warning ge 1) {
292 pb_log(0,"$warning WARNINGS found.\nMaybe you should review your package list for $ddir-$dver-$darch\nand remove$lwpkg\n");
293}
294
295# We Just printed packages names so now end
296if ($opts{'p'}) {
297 exit(0);
298}
Note: See TracBrowser for help on using the repository browser.