AddThis Social Bookmark Button


Advanced Linux Installations and Upgrades with Kickstart

by Q Ethan McCallum

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=http://server/ks_configs/host5.cfg

While this method certainly works, it requires you to remove the generated files later (or leave them around forever). By comparison, the web-based method requires no such cleanup, since the data lasts only as long as the HTTP request. Clients specify a unique identifier in the URL:

boot: linux ks=http://server/

This identifier is a key to the rest of that host's data, which the script uses to populate the template.

A completely automated solution would detect the target host's identity rather than rely on URL parameters. For example, it could mine DHCP data to match the incoming IP to a MAC address. This sort of solution would require a hardware inventory system that I suspect is quite rare, though.

Neither method relies on a particular implementation: use PHP, Java, Perl, or whatever you fancy. Perl fans have the Template Toolkit. A Java solution could use Apache's Velocity. These last two have the added bonus of being usable in both web (on the fly) and command-line (pre-generated) scenarios. Most programming languages provide built-in support for a variety of data formats, so you have your choice of storing the machine data in flat files, XML, an RDBMS, or whatever else comes to mind.

Storing ks.cfg on Removable Media

ks.cfg contains the root password, and as such, sensitive shops may not want it to cross the wire via HTTP or FTP. You can trade the convenience of clients downloading ks.cfg for the added security of storing it on removable media, such as a disk, a CD, or an external drive.

The disk route is the easiest: copy the file to the root directory of a formatted disk. When you boot the target host from the CD, enter:

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:

$ mkisofs -o boot-ks.iso -r -b isolinux.bin \
        -c -no-emul-boot -boot-load-size 4  \
        -boot-info-table -R -J -v -T isolinux/

(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:

boot: linux ks=cdrom:/ks.cfg

There are, of course, trade-offs here. Disks tend to have shorter and less predictable life spans than CDs and require you to have a boot CD handy. Then again, CDs and CD-RWs are good for a limited number of writes. Furthermore, because of the strong ties between the boot media and the target OS revision, your boot CDs become coasters at the next upgrade rollout. Using other removable media requires that your boot medium's kernel support your SCSI (or USB, or FireWire) adapter.

Whatever the case, you needn't limit yourself to a single config file. You could copy a series of pre-generated config files to the disk or CD, then specify the target host's file at the boot: prompt:

linux ks=hd:sdb5:/ks-host5.cfg linux ks=floppy:/ks-host5.cfg

As ks.cfg is just a few K in size, space shouldn't be a problem.

There's no right answer here. Arguably, storing ks.cfg on removable media works best for small or medium shops or for large one-offs such as clone farms. If your goal is to make sure sensitive Kickstart data doesn't cross the normal network, set up a private build network using a portable switch and serve Kickstart data from a laptop.

Default Booting to Kickstart

Whether you're building a clone farm or repeatedly testing a Kickstart setup, you'll tire of entering linux ks=... each time you start a build. (Maybe that's just me; people have accused me of selective laziness.) You can create a boot CD that automatically loads your ks.cfg, making Kickstart a true fire-and-forget process.

The key to this magic is isolinux/isolinux.cfg. To start, define a new boot selection by adding a new stanza:

label custom_kickstart
  kernel vmlinuz
  append initrd=initrd.img ramdisk_size=8192 ks=cdrom:/ks.cfg

This lets you enter:

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.

Pre- and Postinstall Scripts

Kickstart does a lot of host customization for you--setting the root password, the time zone, and so on--but it won't do certain other tweaks, such as disabling services via chkconfig or setting up site-specific directory structures. You can automate these tasks using the pre- and postinstall scripts. (There is one of each.) Per their names, these scripts run before and after the installation, respectively.

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.

Pages: 1, 2

Next Pagearrow