A Detailed Look at the BuildInstallRoot Process

Introduction

This document attempts to provide an explanation of how the InstallRoot data is generated, using the /usr/sbin/buildinstallroot script. The script is part of the lcfg-buildinstallroot RPM, which also includes buildinstallroot documentation and the installroot run-time configuration files (boot.msg, isolinux.cfg, & lcfgng.lss). Note that the man page (in pod & man format) and other documentation for version n.nn.nn can be found in /usr/share/doc/lcfg-buildinstallroot-n.nn.nn). For example:

% rpm -qpl /pkgs/master/rpms/fc5/lcfg/lcfg-buildinstallroot-0.99.23-1.noarch.rpm
/usr/lib/lcfg/doc/pod/buildinstallroot.pod
/usr/sbin/buildinstallroot
/usr/share/doc/lcfg-buildinstallroot-0.99.23
/usr/share/doc/lcfg-buildinstallroot-0.99.23/ChangeLog
/usr/share/doc/lcfg-buildinstallroot-0.99.23/README
/usr/share/doc/lcfg-buildinstallroot-0.99.23/README.BUILD
/usr/share/man/man8/buildinstallroot.8.gz
/var/lcfg/conf/installroot
/var/lcfg/conf/installroot/boot.msg
/var/lcfg/conf/installroot/isolinux.cfg
/var/lcfg/conf/installroot/lcfgng.lss
% 
Be aware that the buildinstallroot script must be run as root in order to be able to run the rdxprof and mknod commands. Because of this requirement to run as root, the buildinstallroot should never be run on a server or other essential-service machine (to avoid even the possibility of doing "rm -rf /" or similar).

Overview

Several arguments can be passed from the command-line, modifying the default behaviour: When the buildinstallroot script is called, it downloads a list of RPMs to include, and creates a root directory into which it installs the RPMs. It also creates relevant admin files (fstab, inittab, etc), and the isolinux boot files (if an ISO image is being built).

The buildinstallroot Script

The buildinstallroot script contains 12 sub-routines (not including the top-level run() call, or the admin fail() and usage() routines):

In run order,these are:

  1. get_release()
    Sets $release variable based on contents of /etc/LCFG-RELEASE.

  2. fetch_profile()
    This downloads a given profile from a given URL using rdxprof. Defaults to using "installroot-" plus contents of /etc/LCFG-RELEASE (for example "fc5-stable") and http://lcfghost/profiles (both explicitly set in script if not overriden on command line).

  3. get_profile_info()
    This is called with the same profile name as in fetch_profile(), and uses LCFG::Resources to set RPM path and flags for updaterpms.

  4. cpp_rpm_cfg()
    This runs the C preprocessor over the RPM configuration template file /var/lcfg/conf/profile/rpmcfg/installroot-version, (where version is "fc5-stable", for example) to produce an interim file, /var/lcfg/tmp/installroot_rpmcfg.XXXX (where "XXXX" is a randomly generated 4-character string, not based on version), which is deleted upon completion.

  5. create_root()
    creates root directory in (specified) temporary location ($root), plus /etc & /dev, then creates RPM directory below $root, and touches (creates empty) /etc/fstab & /etc/mtab. Also makes devices for ram disks and terminal output under /dev.

  6. install_rpms()
    initialises RPM database and then runs updaterpms, specifying alternative (temporary) root location, plus location from which to download RPMs, and list of RPMs to install (created from template by cpp_rpm_cfg()). Once finished, removes $root/var/lib/rpm, as it takes too much space in the /var installroot.

  7. timestamp()
    Creates timestamp file in $root/build.timestamp.

  8. create_inittab()
    Creates $root/etc/inittab, which contains command to run on startup for installation.

    The following only apply if an ISO image is being built:

  9. check_kernel_count
    Checks number of kernel files (vmlinuz*) in $root/boot, and fails (exits) if more or less than just one.

  10. prepare_iso_linux()
    Creates directory $root/isolinux, and files below it:
    • boot.msg
      (using /var/lcfg/conf/installroot/boot.msg as template).
    • lcfgng.lss
      (copied from /var/lcfg/conf/installroot).
    • isolinux.bin
      (copied from /usr/lib/syslinux/isolinux.bin).
    • isolinux.cfg
      (copied from /var/lcfg/conf/installroot)

  11. install_kernel()
    Copies kernel (vmlinuz) from $root/boot to $root/isolinux/vmlinuz.

  12. build_image()
    Creates (specifically-named) ISO image using /usr/bin/mkisofs and script-specified parameters.

Example

On an FC5 machine, the buildinstallroot script might be run as follows:
# /usr/sbin/buildinstallroot --verbose -o /tmp/installroot.img
- this will download a list of RPMs (in XML format) using "rdxprof -u http://lcfghost/profiles installroot-fc5-stable" (to be used to construct the basic root filesystem):
Fetching profile installroot-fc5-stable from http://lcfghost/profiles
Profile fetch OK.
- which creates:
/var/lcfg/conf/profile/dbm/installroot-fc5-stable.DB2.db
/var/lcfg/conf/profile/rpmcfg/installroot-fc5-stable
/var/lcfg/conf/profile/xml/installroot-fc5-stable.xml+
/var/lcfg/conf/profile/xml/installroot-fc5-stable.xml
and the list of RPMs contained in these files includes the initial set of components.

The just-downloaded profile is parsed to extract the search path for RPMs, and further tweaking is done using cpp:

rpmpath is http://master.rpms.inf.ed.ac.uk/master/rpms/fc5/base,
  http://master.rpms.inf.ed.ac.uk/master/rpms/fc5/updates,
  http://master.rpms.inf.ed.ac.uk/master/rpms/fc5/extras,
  http://master.rpms.inf.ed.ac.uk/master/rpms/fc5/lcfg,
Preprocessing rpmcfg file
- the temporary root directory is then created (or recreated if the "--force" option is used):
Checking for existing root /r
Creating new root /r
Creating new rpm dir /var/lib/rpm
mkdir /r/var
mkdir /r/var/lib
mkdir /r/var/lib/rpm
Creating /etc
Creating /dev
Creating empty /etc/fstab
Creating empty /etc/mtab
Creating /dev/console
Creating /dev/null
Creating /dev/ram1
Creating /dev/ram2
Creating /dev/tty2
Creating /dev/ttyS0
- and the initial set of base RPMs is installed within this structure:
Initializing RPM database
Running updaterpms
[INFO] /usr/sbin/updaterpms: 245 installs, 0 removals
[INFO] /usr/sbin/updaterpms: Flagging perl-W3C-SAX-XmlParser-0.99-3 for installing
[INFO] /usr/sbin/updaterpms: Flagging python-elementtree-1.2.6-4.2.1 for installing
[INFO] /usr/sbin/updaterpms: Flagging perl-W3C-Util-Basekit-0.91-3 for installing
...
[INFO] /usr/sbin/updaterpms: Flagging db4-4.3.29-8.fc5 for installing
[INFO] /usr/sbin/updaterpms: Flagging ed-0.3-0.fc5 for installing
[INFO] /usr/sbin/updaterpms: Flagging bc-1.06-19.2.1 for installing
[INFO] /usr/sbin/updaterpms: (1/245) installing libgcc-4.1.1-51.fc5
[INFO] /usr/sbin/updaterpms: (2/245) installing setup-2.5.49-1
[INFO] /usr/sbin/updaterpms: (3/245) installing filesystem-2.3.7-1.2.1.lcfg.1
...
[INFO] /usr/sbin/updaterpms: (243/245) installing netdump-0.7.14-1.2.1
[INFO] /usr/sbin/updaterpms: (244/245) installing bind-9.3.4-1.fc5
[INFO] /usr/sbin/updaterpms: (245/245) installing kbd-1.12-13.2
Removing /r/var/lib/rpm
- and finally, a little housekeeping and then the ISO image is created (ready to burn to CD or make available over the network):
Timestamping root
Creating /etc/inittab
Checking kernel count
Preparing isolinux
Installing kernel into isolinux
Making the ISO image /tmp/installroot.img
...
#
For naming conventions, image locations, and hints on writing CDs and DVDs, see the MPU Wiki page.