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 |
|
---|
12 | use strict 'vars';
|
---|
13 | use Getopt::Long qw(:config auto_abbrev no_ignore_case);
|
---|
14 | use Data::Dumper;
|
---|
15 | use English;
|
---|
16 | use LWP::UserAgent;
|
---|
17 | #use File::Basename;
|
---|
18 | #use File::Copy;
|
---|
19 | use ProjectBuilder::Version;
|
---|
20 | use ProjectBuilder::Base;
|
---|
21 | use ProjectBuilder::Env;
|
---|
22 | use ProjectBuilder::Conf;
|
---|
23 | use ProjectBuilder::Distribution;
|
---|
24 |
|
---|
25 | # Global variables
|
---|
26 | my %opts; # CLI Options
|
---|
27 |
|
---|
28 | =pod
|
---|
29 |
|
---|
30 | =head1 NAME
|
---|
31 |
|
---|
32 | rpmbootstrap - creates a chrooted RPM based distribution a la debootstrap, aka Virtual Environment (VE)
|
---|
33 |
|
---|
34 | =head1 DESCRIPTION
|
---|
35 |
|
---|
36 | rpmbootstrap creates a chroot environment (Virtual Environment or VE) with a minimal distribution in it,
|
---|
37 | suited for building packages for example. It's very much like debootstrap but for RPM based distribution.
|
---|
38 | It aims at supporting all distributions supported by project-builder;org (RHEL, RH, Fedora, OpeSUSE, SLES, Mandriva, ...)
|
---|
39 |
|
---|
40 | It 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 |
|
---|
44 | rpmbootstrap [-vhmqpdk][-s script][-i iso] distribution-version-arch [target-dir] [mirror [script]]
|
---|
45 |
|
---|
46 | pb [--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 |
|
---|
54 | Print a brief help message and exits.
|
---|
55 |
|
---|
56 | =item B<-h|--help>
|
---|
57 |
|
---|
58 | Print a brief help message and exits.
|
---|
59 |
|
---|
60 | =item B<--man>
|
---|
61 |
|
---|
62 | Prints the manual page and exits.
|
---|
63 |
|
---|
64 | =item B<-q|--quiet>
|
---|
65 |
|
---|
66 | Do not print any output.
|
---|
67 |
|
---|
68 | =item B<-p|--print-rpms>
|
---|
69 |
|
---|
70 | Print the packages to be installed, and exit. Note that a target directory must be specified so
|
---|
71 | rpmbootstrap 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 |
|
---|
75 | Download packages, but don't perform installation.
|
---|
76 |
|
---|
77 | =item B<-k|--keep>
|
---|
78 |
|
---|
79 | Keep packages in the cache dir for later reuse. By default remove them.
|
---|
80 |
|
---|
81 | =item B<-s|--script script>
|
---|
82 |
|
---|
83 | Name of the script you want to execute on the related VEs after the installation.
|
---|
84 |
|
---|
85 | =item B<-i|--iso iso_image>
|
---|
86 |
|
---|
87 | Name 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 |
|
---|
95 | Full 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 |
|
---|
99 | This 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 |
|
---|
103 | To setup a Fedora 12 distribution with an i386 architecture issue:
|
---|
104 |
|
---|
105 | rpmbootstrap fedora-12-i386 /tmp/fedora/12/i386
|
---|
106 |
|
---|
107 |
|
---|
108 | =head1 WEB SITES
|
---|
109 |
|
---|
110 | The 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 |
|
---|
114 | Cf: 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 |
|
---|
118 | Uses Project-Builder.org configuration file (/etc/pb/pb.conf or /usr/local/etc/pb/pb.conf)
|
---|
119 |
|
---|
120 | =head1 AUTHORS
|
---|
121 |
|
---|
122 | The 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 |
|
---|
126 | Project-Builder.org is distributed under the GPL v2.0 license
|
---|
127 | described in the file C<COPYING> included with the distribution.
|
---|
128 |
|
---|
129 | =cut
|
---|
130 |
|
---|
131 | # ---------------------------------------------------------------------------
|
---|
132 |
|
---|
133 | my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
|
---|
134 | my $appname = "rpmbootstrap";
|
---|
135 |
|
---|
136 | # Initialize the syntax string
|
---|
137 |
|
---|
138 | pb_syntax_init("$appname Version $projectbuilderver-$projectbuilderrev\n");
|
---|
139 |
|
---|
140 | GetOptions("help|?|h" => \$opts{'h'},
|
---|
141 | "man|m" => \$opts{'man'},
|
---|
142 | "verbose|v+" => \$opts{'v'},
|
---|
143 | "quiet|q" => \$opts{'q'},
|
---|
144 | "log-files|l=s" => \$opts{'l'},
|
---|
145 | "script|s=s" => \$opts{'s'},
|
---|
146 | "print-rpms|p" => \$opts{'p'},
|
---|
147 | "download-only|d" => \$opts{'d'},
|
---|
148 | "keep|k" => \$opts{'k'},
|
---|
149 | "iso|i=s" => \$opts{'i'},
|
---|
150 | "version|V=s" => \$opts{'V'},
|
---|
151 | ) || pb_syntax(-1,0);
|
---|
152 |
|
---|
153 | if (defined $opts{'h'}) {
|
---|
154 | pb_syntax(0,1);
|
---|
155 | }
|
---|
156 | if (defined $opts{'man'}) {
|
---|
157 | pb_syntax(0,2);
|
---|
158 | }
|
---|
159 | if (defined $opts{'v'}) {
|
---|
160 | $pbdebug = $opts{'v'};
|
---|
161 | }
|
---|
162 | if (defined $opts{'q'}) {
|
---|
163 | $pbdebug=-1;
|
---|
164 | }
|
---|
165 | if (defined $opts{'l'}) {
|
---|
166 | open(pbLOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
|
---|
167 | $pbLOG = \*pbLOG;
|
---|
168 | $pbdebug = 0 if ($pbdebug == -1);
|
---|
169 | }
|
---|
170 | pb_log_init($pbdebug, $pbLOG);
|
---|
171 | #pb_display_init("text","");
|
---|
172 |
|
---|
173 | #if (defined $opts{'s'}) {
|
---|
174 | #$pbscript = $opts{'s'};
|
---|
175 | #}
|
---|
176 | #if (defined $opts{'i'}) {
|
---|
177 | #$iso = $opts{'i'};
|
---|
178 | #}
|
---|
179 |
|
---|
180 | # Get VE name
|
---|
181 | $ENV{'PBV'} = shift @ARGV;
|
---|
182 | die pb_syntax(-1,1) if (not defined $ENV{'PBV'});
|
---|
183 |
|
---|
184 | die "Needs to be run as root" if ($EFFECTIVE_USER_ID != 0);
|
---|
185 |
|
---|
186 | #
|
---|
187 | # Initialize distribution info from pb conf file
|
---|
188 | #
|
---|
189 | my ($name,$ver,$darch) = split(/-/,$ENV{'PBV'});
|
---|
190 | chomp($darch);
|
---|
191 | my ($ddir, $dver, $dfam, $dtype, $pbsuf, $dsuf, $dupd) = pb_distro_init($name,$ver,$darch);
|
---|
192 |
|
---|
193 | #
|
---|
194 | # Check target dir
|
---|
195 | # Create if not existent and use default if none given
|
---|
196 | #
|
---|
197 | pb_env_init_pbrc(); # to get content of HOME/.pbrc
|
---|
198 | my $vepath = shift @ARGV;
|
---|
199 |
|
---|
200 | #
|
---|
201 | # Check for command requirements
|
---|
202 | #
|
---|
203 | my ($req,$opt) = pb_conf_get_if("oscmd","oscmdopt");
|
---|
204 | my ($req2,$opt2) = (undef,undef);
|
---|
205 | $req2 = $req->{$appname} if (defined $req);
|
---|
206 | $opt2 = $opt->{$appname} if (defined $opt);
|
---|
207 | pb_check_requirements($req2,$opt2);
|
---|
208 |
|
---|
209 | if (not defined $vepath) {
|
---|
210 | my ($vestdpath) = pb_conf_get_if("vepath");
|
---|
211 | $vepath = "$vestdpath->{'default'}/$ddir/$dver/$darch";
|
---|
212 | }
|
---|
213 |
|
---|
214 | die pb_log(0,"No target-dir specified and no default vepath found in $ENV{'PBETC'}\n") if (not defined $vepath);
|
---|
215 |
|
---|
216 | pb_mkdir_p($vepath) if (! -d $vepath);
|
---|
217 |
|
---|
218 | #
|
---|
219 | # Get the package list to download, store them in a cache directory
|
---|
220 | #
|
---|
221 | my ($rbsmindep,$rbsmirrorsrv) = pb_conf_get("rbsmindep","rbsmirrorsrv");
|
---|
222 | my ($rbscachedir) = pb_conf_get_if("rbscachedir");
|
---|
223 | my $pkgs = pb_distro_get_param($ddir,$dver,$darch,$rbsmindep);
|
---|
224 | my $mirror = pb_distro_get_param($ddir,$dver,$darch,$rbsmirrorsrv);
|
---|
225 |
|
---|
226 | my $cachedir = "/var/cache/rpmbootstrap";
|
---|
227 | $cachedir = $rbscachedir->{'default'} if (defined $rbscachedir->{'default'});
|
---|
228 |
|
---|
229 | # Point to the right subdir and create it if needed
|
---|
230 | $cachedir .= "/$ddir-$dver-$darch";
|
---|
231 | pb_mkdir_p($cachedir) if (! -d $cachedir);
|
---|
232 |
|
---|
233 | # Get the complete package name from the mirror
|
---|
234 | #
|
---|
235 | my $ua = LWP::UserAgent->new;
|
---|
236 | $ua->timeout(10);
|
---|
237 | $ua->env_proxy;
|
---|
238 |
|
---|
239 | my $response = $ua->get($mirror);
|
---|
240 | if (! $response->is_success) {
|
---|
241 | die "Unable to download packages from $mirror for $ddir-$dver-$darch";
|
---|
242 | }
|
---|
243 | pb_log(3,"Mirror $mirror gave answer: $response->dump(maxlength => 0)\n");
|
---|
244 |
|
---|
245 | # Just print packages names if asked so.
|
---|
246 | if ($opts{'p'}) {
|
---|
247 | pb_log(0,"Should process package list: $pkgs\n");
|
---|
248 | exit(0);
|
---|
249 | }
|
---|
250 |
|
---|
251 | # For each package to process, get it, put it in the cache dir
|
---|
252 | # and extract it in the target dir. If not asked to keep, remove it
|
---|
253 | # Just download if asked so.
|
---|
254 |
|
---|
255 | foreach my $p (split(/,/,$pkgs)) {
|
---|
256 | pb_log(1,"Processing package $p ...\n")
|
---|
257 | }
|
---|