[1341] | 1 | #!/usr/bin/perl -w
|
---|
| 2 | #
|
---|
| 3 | # pbmkbm, a project-builder.org utility to make boot media
|
---|
| 4 | #
|
---|
| 5 | # $Id$
|
---|
| 6 | #
|
---|
| 7 | # Copyright B. Cornec 2011
|
---|
| 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 File::Basename;
|
---|
| 17 | use File::Copy;
|
---|
| 18 | use ProjectBuilder::Version;
|
---|
| 19 | use ProjectBuilder::Base;
|
---|
| 20 | use ProjectBuilder::Env;
|
---|
| 21 | use ProjectBuilder::Conf;
|
---|
| 22 | use ProjectBuilder::Distribution;
|
---|
| 23 |
|
---|
| 24 | # Global variables
|
---|
| 25 | my %opts; # CLI Options
|
---|
| 26 |
|
---|
| 27 | =pod
|
---|
| 28 |
|
---|
| 29 | =head1 NAME
|
---|
| 30 |
|
---|
| 31 | pbmkbm - a project-builder.org utility to make boot media
|
---|
| 32 |
|
---|
| 33 | =head1 DESCRIPTION
|
---|
| 34 |
|
---|
| 35 | pbmkbm creates a bootable media (CD/DVD, USB device, Network, tape, ...)
|
---|
| 36 | with a minimal distribution in it, suited for building packages for example.
|
---|
| 37 | It aims at supporting all distributions supported by project-builder.org
|
---|
| 38 | (RHEL, RH, Fedora, OpeSUSE, SLES, Mandriva, ...)
|
---|
| 39 |
|
---|
| 40 | It is inspired by work done by Jean-Marc André around the HP SSSTK and
|
---|
| 41 | aim at replacing the mindi project (http://www.mondorescue.org), but
|
---|
| 42 | fully integrated with project-builder.org
|
---|
| 43 |
|
---|
| 44 | pbmkbm works in different phases. The first one is to check all
|
---|
| 45 |
|
---|
| 46 | pbmkbm needs to gather a certain number of components that could come
|
---|
| 47 | from various sources and could be put on a different target media.
|
---|
| 48 | We need a kernel, an initrd/initramfs for additional modules and init script,
|
---|
| 49 | a root filesystem and a boot configuration file.
|
---|
| 50 | Kernel, modules could come either from the local installed system
|
---|
| 51 | (typically for disaster recovery context) or from a kernel package of a
|
---|
| 52 | given configuration.
|
---|
| 53 | Utilities could come from busybox, local utilities or set of packages.
|
---|
| 54 | The root filesystem is made with them.
|
---|
| 55 | The initrd/initramfs could be made internaly or by calling dracut.
|
---|
| 56 | THe boot config file is generated from analysis content or provided externally.
|
---|
| 57 |
|
---|
| 58 | =head1 SYNOPSIS
|
---|
| 59 |
|
---|
| 60 | pbmkbm [-vhq][-t boot-media-type [-d device]][-m os-ver-arch]
|
---|
| 61 | [-s script][-a pkg1[,pkg2,...]] [target-dir]
|
---|
| 62 |
|
---|
| 63 | pbmkbm [--verbose][--help][--man][--quiet][--type boot-media-type [-device device]]
|
---|
| 64 | [--script script][--iso iso][--add pkg1,[pkg2,...]][target-dir]
|
---|
| 65 |
|
---|
| 66 | =head1 OPTIONS
|
---|
| 67 |
|
---|
| 68 | =over 4
|
---|
| 69 |
|
---|
| 70 | =item B<-v|--verbose>
|
---|
| 71 |
|
---|
| 72 | Print a brief help message and exits.
|
---|
| 73 |
|
---|
| 74 | =item B<-h|--help>
|
---|
| 75 |
|
---|
| 76 | Print a brief help message and exits.
|
---|
| 77 |
|
---|
| 78 | =item B<--man>
|
---|
| 79 |
|
---|
| 80 | Prints the manual page and exits.
|
---|
| 81 |
|
---|
| 82 | =item B<-q|--quiet>
|
---|
| 83 |
|
---|
| 84 | Do not print any output.
|
---|
| 85 |
|
---|
| 86 | =item B<-s|--script script>
|
---|
| 87 |
|
---|
| 88 | Name of the script you want to execute on the related VEs after the installation.
|
---|
| 89 | It is executed in host environment.
|
---|
| 90 | You can use the chroot command to execute actions in the VE.
|
---|
| 91 |
|
---|
| 92 | =item B<-a|--add pkg1[,pkg2,...]>
|
---|
| 93 |
|
---|
| 94 | Additional packages to add from the distribution you want to install on the related VE
|
---|
| 95 | at the end of the chroot build.
|
---|
| 96 |
|
---|
| 97 | =back
|
---|
| 98 |
|
---|
| 99 | =head1 ARGUMENTS
|
---|
| 100 |
|
---|
| 101 | =over 4
|
---|
| 102 |
|
---|
| 103 | =item B<target-dir>
|
---|
| 104 |
|
---|
| 105 | This is the target directory under which the VE will be created.
|
---|
| 106 | Created on the fly if needed.
|
---|
| 107 | If none is given use the default directory hosting VE for project-builder.org
|
---|
| 108 | (Cf: vepath parameter in $HOME/.pbrc)
|
---|
| 109 |
|
---|
| 110 | =back
|
---|
| 111 |
|
---|
| 112 | =head1 EXAMPLE
|
---|
| 113 |
|
---|
| 114 | To setup a USB boot media on the /dev/sdb device for a Fedora 12 distribution with an i386 architecture issue:
|
---|
| 115 |
|
---|
| 116 | pbmkbm -t usb -d /dev/sdb -m fedora-12-i386
|
---|
| 117 |
|
---|
| 118 | =head1 WEB SITES
|
---|
| 119 |
|
---|
| 120 | The main Web site of the project is available at L<http://www.project-builder.org/>.
|
---|
| 121 | Bug reports should be filled using the trac instance of the project at L<http://trac.project-builder.org/>.
|
---|
| 122 |
|
---|
| 123 | =head1 USER MAILING LIST
|
---|
| 124 |
|
---|
| 125 | Cf: L<http://www.mondorescue.org/sympa/info/pb-announce> for announces and
|
---|
| 126 | L<http://www.mondorescue.org/sympa/info/pb-devel> for the development of the pb project.
|
---|
| 127 |
|
---|
| 128 | =head1 CONFIGURATION FILE
|
---|
| 129 |
|
---|
| 130 | Uses Project-Builder.org configuration file (/etc/pb/pb.conf or /usr/local/etc/pb/pb.conf)
|
---|
| 131 |
|
---|
| 132 | =head1 AUTHORS
|
---|
| 133 |
|
---|
| 134 | The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
|
---|
| 135 |
|
---|
| 136 | =head1 COPYRIGHT
|
---|
| 137 |
|
---|
| 138 | Project-Builder.org is distributed under the GPL v2.0 license
|
---|
| 139 | described in the file C<COPYING> included with the distribution.
|
---|
| 140 |
|
---|
| 141 | =cut
|
---|
| 142 |
|
---|
| 143 | # ---------------------------------------------------------------------------
|
---|
| 144 |
|
---|
| 145 | my ($projectbuilderver,$projectbuilderrev) = pb_version_init();
|
---|
| 146 | my $appname = "pbmkbm";
|
---|
| 147 | $ENV{'PBPROJ'} = $appname;
|
---|
| 148 |
|
---|
| 149 | # Initialize the syntax string
|
---|
| 150 |
|
---|
| 151 | pb_syntax_init("$appname Version $projectbuilderver-$projectbuilderrev\n");
|
---|
| 152 | pb_temp_init();
|
---|
| 153 |
|
---|
| 154 | GetOptions("help|?|h" => \$opts{'h'},
|
---|
| 155 | "man|m" => \$opts{'man'},
|
---|
| 156 | "verbose|v+" => \$opts{'v'},
|
---|
| 157 | "quiet|q" => \$opts{'q'},
|
---|
| 158 | "log-files|l=s" => \$opts{'l'},
|
---|
| 159 | "script|s=s" => \$opts{'s'},
|
---|
| 160 | "machine|m=s" => \$opts{'m'},
|
---|
| 161 | "add|a=s" => \$opts{'a'},
|
---|
| 162 | "version|V=s" => \$opts{'V'},
|
---|
| 163 | ) || pb_syntax(-1,0);
|
---|
| 164 |
|
---|
| 165 | if (defined $opts{'h'}) {
|
---|
| 166 | pb_syntax(0,1);
|
---|
| 167 | }
|
---|
| 168 | if (defined $opts{'man'}) {
|
---|
| 169 | pb_syntax(0,2);
|
---|
| 170 | }
|
---|
| 171 | if (defined $opts{'v'}) {
|
---|
| 172 | $pbdebug = $opts{'v'};
|
---|
| 173 | }
|
---|
| 174 | if (defined $opts{'q'}) {
|
---|
| 175 | $pbdebug=-1;
|
---|
| 176 | }
|
---|
| 177 | if (defined $opts{'l'}) {
|
---|
| 178 | open(pbLOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
|
---|
| 179 | $pbLOG = \*pbLOG;
|
---|
| 180 | $pbdebug = 0 if ($pbdebug == -1);
|
---|
| 181 | }
|
---|
| 182 | pb_log_init($pbdebug, $pbLOG);
|
---|
| 183 |
|
---|
| 184 | # Get VE name
|
---|
| 185 | $ENV{'PBV'} = $opts{'m'};
|
---|
| 186 | die pb_syntax(-1,1) if (not defined $ENV{'PBV'});
|
---|
| 187 |
|
---|
| 188 | die "Needs to be run as root" if ($EFFECTIVE_USER_ID != 0);
|
---|
| 189 |
|
---|
| 190 | #
|
---|
| 191 | # Initialize distribution info from pb conf file
|
---|
| 192 | #
|
---|
| 193 | pb_log(0,"Starting VE build for $ENV{'PBV'}\n");
|
---|
| 194 | my $pbos = pb_distro_get_context($ENV{'PBV'});
|
---|
| 195 |
|
---|
| 196 | #
|
---|
| 197 | # Check target dir
|
---|
| 198 | # Create if not existent and use default if none given
|
---|
| 199 | #
|
---|
| 200 | pb_env_init_pbrc(); # to get content of HOME/.pbrc
|
---|
| 201 | my $vepath = shift @ARGV;
|
---|
| 202 |
|
---|
| 203 | #
|
---|
| 204 | # Check for command requirements
|
---|
| 205 | #
|
---|
| 206 | my ($req,$opt) = pb_conf_get_if("mkbmcmd","mkbmcmdopt");
|
---|
| 207 | pb_check_requirements($req,$opt,$appname);
|
---|
| 208 |
|
---|
| 209 | if (not defined $vepath) {
|
---|
| 210 | my ($vestdpath) = pb_conf_get("vepath");
|
---|
| 211 | $vepath = "$vestdpath->{'default'}/$pbos->{'name'}/$pbos->{'version'}/$pbos->{'arch'}" if (defined $vestdpath->{'default'});
|
---|
| 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 ($mkbmcachedir) = pb_conf_get_if("mkbmcachedir");
|
---|
| 222 | my ($pkgs,$mirror) = pb_distro_get_param($pbos,pb_conf_get("mkbmmindep","mkbmmirrorsrv"));
|
---|
| 223 |
|
---|
| 224 | my $cachedir = "/var/cache/pbmkbm";
|
---|
| 225 | $cachedir = $mkbmcachedir->{'default'} if (defined $mkbmcachedir->{'default'});
|
---|
| 226 |
|
---|
| 227 | # Point to the right subdir and create it if needed
|
---|
| 228 | $cachedir .= "/$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}";
|
---|
| 229 | pb_mkdir_p($cachedir) if (! -d $cachedir);
|
---|
| 230 |
|
---|
| 231 | #
|
---|
| 232 | # /proc needed
|
---|
| 233 | #
|
---|
| 234 | pb_system("mount -o bind /proc $vepath/proc","Mounting /proc");
|
---|
| 235 |
|
---|
| 236 | # Installed additional packages we were asked to
|
---|
| 237 | if (defined $opts{'a'}) {
|
---|
| 238 | $opts{'a'} =~ s/,/ /g;
|
---|
| 239 | pb_system("chroot $vepath /bin/bash -c \"$pbos->{'install'} $opts{'a'} \"","Adding packages to OS by running $pbos->{'install'} $opts{'a'}");
|
---|
| 240 | }
|
---|
| 241 |
|
---|
| 242 | #
|
---|
| 243 | # Clean up
|
---|
| 244 | #
|
---|
| 245 | pb_log(1,"Cleaning up\n");
|
---|
| 246 | pb_system("umount $vepath/proc","Unmounting /proc");
|
---|
| 247 |
|
---|
| 248 | # Executes post-install step if asked for
|
---|
| 249 | if ($opts{'s'}) {
|
---|
| 250 | pb_system("$opts{'s'} $vepath","Executing the post-install script: $opts{'s'} $vepath");
|
---|
| 251 | }
|
---|