Professional Documents
Culture Documents
by Ethan McCallum 11/04/2004 Editor's note: Ethan has collected this series and other information into Managing RPM-Based Systems with Kickstart and Yum. This series concludes in Pre-patched Kickstart Installs.
In Hands-Off Fedora Installs with Kickstart, I provided an overview of the Kickstart process. This article is a collection of techniques that may interest people who want to do more with Kickstart. It covers Kickstart customization, scalability, and security, including:
dynamic ks.cfg storing ks.cfg on removable media default booting to kickstart pre- and postinstall scripts custom RPMs and package groups using Kickstart to upgrade
Dynamic ks.cfg
Most Kickstart experiments begin with a single ks.cfg file, though this approach is less suitable for large deployments. Even a farm of cloned hardware will require some settings unique to each host. That means you have either several one-use ks.cfgs, or one file to tweak for each Kickstart target. These methods are brittle because they bind two elements that may vary independently of one another: host-specific data (the IP address) and build-specific data (packages to install). When either one changes, the ad hoc edits to resync the two may introduce errors. You can avoid this hassle if you're programmatically inclined: pre-generate a series of ks.cfg, or generate the data on the fly. The latter requires that your Kickstart clients fetch ks.cfg via HTTP. Both approaches use the mail-merge concept: create a template ks.cfg with placeholders for the dynamic info, then merge that with a data source that contains one set of values for each host. A Perl or PHP template, for example, may include the following:
## ... other settings ... network --device ${network_device} --bootproto static --ip ${network_address} --netmask ${network_mask} --gateway ${network_gateway} --nameserver ${nameserver_1} --nameserver ${nameserver_2} --hostname ${hostname}
(We've split the above for readability; it is really one line.) Pre-generating files requires that you create one file per target host (the Kickstart client). Specify that host's file at the CD's boot: prompt. For example:
boot: linux ks=floppy:/ks.cfg floppy here is a device alias for fd0. Specify another partition's name to load ks.cfg from that device: boot: linux ks=hd:{partition}:/ks.cfg {partition} is an identifier from the /dev directory, such as sda1. (Remember: USB, FireWire, and other such
devices appear as SCSI devices.) The CD method requires slightly more work, because it creates a bootable CD. In the distribution, the isolinux directory represents the root directory of a boot CD. Copy it to a scratch space, and then copy your custom ks.cfg to {scratch space}/isolinux. Change to the directory above isolinux and call mkisofs to generate the ISO image:
(Note that the boot image file, isolinux/isolinux.bin, must be writable or mkisofs will fail.) Follow your standard procedure for burning this ISO to media. If you use VMWare as a Kickstart test platform, you can save a disc by specifying the ISO as the guest's CD-ROM device. Boot a test machine from the CD and fire off Kickstart using the local ks.cfg:
linux custom_kickstart
at the CD's boot: prompt to fire off a Kickstart. The operation will use the ks.cfg in the CD's root directory. Change the default directive to make this the default:
default kickstart
To be fancy, associate an explanatory message with an F-key:
F8 our_site.msg
(There are other directives in isolinux.cfg worthy of experiment, but they're beyond the scope of this article.) The specified ks.cfg needn't exist on the boot CD; you can specify other valid sources, such as a disk or a URL. If your dynamically generated ks.cfg doesn't require parameters to identify the target host, you can have a single boot CD for the entire shop, or at the least, one CD per OS version.
The preinstall script starts toward the end of ks.cfg under the %pre directive. The syntax is similar to that of an RPM spec file. At this early stage there is a bare-bones assortment of tools at your disposal, just enough to shuffle files around or mount NFS shares. The postinstall script (%post) has more potential. By this point, with the OS installed, the script defaults to running chrooted in the newly installed OS under /mnt/sysimage. You can disable this by using %post's --nochroot flag, by the way. Use this script to alter runtime services with chkconfig, install a rudimentary firewall rule set, or do anything else you'd rather take place before the machine reboots into full-service mode. Both the %pre and %post directives accept the --interpreter flag, which specifies an interpreter other than the default Bourne shell. You can choose only from the interpreters available at runtime, obviously; but likely the chrooted environment of the postinstall script will have a wider selection. Pre- and postinstall scripts certainly have their place, but they're easy to misuse, difficult to test, and require updates as your build environment evolves. Simplify your build by extracting %pre and %post script functionality into custom RPMs or formal update processes (such as cfengine and rsync wrappers). These have the added benefit of being usable (and testable) outside of the install process.
<group> <id>local_packages</id> <name>Local RPMs</name> <description>home-built RPMs</description> <uservisible>false</uservisible> <packagelist> <packagereq type="default">package1</packagereq> <packagereq type="default">package2</packagereq> <packagereq type="optional">package3</packagereq> </packagelist> </group>
I find it easiest to define new groups at the top of comps.xml, or better still to store them in a separate file and insert them into comps.xml as needed. The <id> tag is a unique identifier for the group. Specify this name in ks.cfg preceded by an @ symbol to install all of the group's packages:
<name xml:lang="fr">Trucs</name> ... <description xml:lang="fr">Les Trucs...</description> <packagelist> holds the list of this group's packages in <packagereq> tags. The type attribute reflects a package's status within the group: optional (addable), default (included by default), or mandatory
(unremovable). Don't rely on the filename for <packagereq>. If you're unsure, query the RPM itself for its internal name:
$ /usr/lib/anaconda-runtime/genhdlist \ --productpath Fedora \ {path} {path} is the fully-qualified path to the parent of the Fedora directory. For the curious, the header data goes in
Fedora/base/hdlist and hdlist2.
upgrade (as opposed to install) installation method (for example, url or nfs) installation language (lang) installed language support (langsupport)
device spec, if you need the device for the install ( device) installation process keyboard setup (keyboard) boot loader configuration (bootloader)
(Refer to the previous article in this series or the Kickstart documentation for detailed explanations of these directives.) The upgrade process ignores most other options, because it shouldn't change settings such as the time zone, the root password, or the network setup.
I've provided a sample upgrade, ks.cfg. It is very generic, and accordingly, you could have a single such file for an entire site. The upgrade operation otherwise functions similarly to the installation: boot from your preferred media, direct Anaconda to ks.cfg, and walk away. Please note that boot media has very strong ties to the OS revision; you must boot from the newer CDs to upgrade. However, the machine hosting the installation media needn't run the same OS version, nor even the same OS. My experience is that Kickstart's upgrade is nondestructive: while it doesn't delete any files or alter disk layouts, it installs new packages (including new kernels, though, so watch out if you rely on a custom kernel). That said, test the process before turning it loose on your environment.
Conclusion
There are several ways to customize the Kickstart process. Applying these techniques to your Kickstart infrastructure should take you closer to a completely hands-off process for installing and retasking machines.
Resources
Download the sample ks.cfg used for upgrades. Hands-Off Fedora Installs with Kickstart provides a general introduction to Kickstart. Chapter 7 of the Red Hat 9 Customization Guide gives Kickstart documentation. The Fedora team has information on tweaking comps.xml available on its web site. Based on my experience, adding the <package> tags to comps.xml is unnecessary. It would appear Anaconda pulls this information from the generated headers list. (Perhaps the documentation is out of date?) "Software Packaging with RPM" explains how to create custom RPMs.
Ethan McCallum grew from curious child to curious adult, turning his passion for technology into a career