oreilly.comSafari Books Online.Conferences.


Pre-Patched Kickstart Installs
Pages: 1, 2

Merging Updates with the Kickstart Tree

As long as you've downloaded the updated RPMs, you may as well fold them into the Kickstart process. In turn, newly Kickstarted machines will start their life with the updates already applied. To do this, you must put the latest RPMs under the Kickstart tree's Fedora/RPMS directory, copy the Fedora/base directory (from the original OS install media) to the Kickstart tree, and rebuild the hdlist files. As before, formalizing a directory structure and naming convention will help your repo scale.

Related Reading

Learning Red Hat Enterprise Linux & Fedora
By Bill McCarty

The first step is the toughest, because you can't simply download the RPM updates right into the Kickstart tree's os/Fedora/RPMS directory. Whereas yum downloads the latest RPMs, Anaconda (ergo Kickstart) doesn't gracefully handle situations in which there are multiple versions of a package in the install tree.

You must therefore replace old package versions in the install tree with their newer counterparts. Doing this by hand is for neither the faint of heart nor the lazy. Being a proud member of the latter category, I prefer to let code do the heavy lifting. The key is to use the RPM API to extract package header info and compare versions. Doing this based on RPM filenames alone is asking for a headache. (I've written a tool to do just this -- Novi.)

First, create a new directory to serve as the install tree. Using the directory structure outlined above, that is FC3-i386/dist under the document root. Put the latest packages under that directory, in Fedora/RPMS. (You can save space by hard-linking the RPMs from the install and update trees, if possible.) Copy the directory Fedora/base from the original OS media, too. You should have a directory structure similar to that of Figure 2.

Kickstart directories
Figure 2. Directory structure for a pre-updated Kickstart tree

Notice the dist directory has the same layout as the os directory, which holds the original install media. dist is essentially the os tree with newer RPMs.

Next, use genhdlist to rebuild the hdlist files. FC3 is a little pickier than FC2 and requires that you first generate a package order file:

$ PYTHONPATH=/usr/lib/anaconda \
  /usr/lib/anaconda-runtime/pkgorder \
  {path to FC2-i386/dist} \
  i386 Fedora > order.txt

$ /usr/lib/anaconda-runtime/genhdlist  \
  --withnumbers  \
  --fileorder order.txt  \
  --productpath Fedora  \
  {path to FC2-i386/dist}

FC2 requires only the genhdlist command, without the --withnumbers and --fileorder flags. Feel free to ignore pkgorder's warnings about ignore package name relation(s).

Point your Kickstart clients to the new install directory and add:

url --url http://{build-server}/FC2-i386/dist

to ks.cfg. You won't have to double back after the install to apply the updates.

Change Control: Having a Single Release Tree

Call yum-arch or createrepo on the Kickstart tree to let it do double duty as a yum repo. This creates a one-stop shop for your machines: whether you're installing the OS or just updating it, your entire shop will run the same set of RPMs.

Kickstart install tree
Figure 3. Pre-updated Kickstart install tree that doubles as a yum repo

Notice this is the same as the dist directory mentioned earlier, just with the headers (or repodata) directory for the RPM metadata.

This setup is far from perfect, though. In a large shop, you probably want to test new RPMs on a few machines before you install them everywhere. Then again, you want to take advantage of cron jobs to let yum do its work unattended.

I've spent my career near or in software teams, and as a result I tend to think in terms of release versions: What do we consider stable and production-quality? versus What are we still testing in the lab? and so on. If you had a designated stable build, you'd have no problem letting your production machines update from it automatically. Furthermore, having clear, labeled builds simplifies systems management because you can tell what "label build" a machine is running.

I applied some software development practices and devised a mix of directories and symbolic links to solve this problem. The trick is to create a new, labeled directory each time you fetch new updates from the public repos. I prefer to use dates as my labels in YYYYmmdd format. Figure 4 is an example of such a directory tree.

Figure 4. Labeled (dated) directories for combination Kickstart/yum trees

Populate the dated directory's Fedora/RPMS subdirectory with the latest RPMs. Copy the base directory from the original OS install media. In the end, the dated directory should resemble the os and dist directories described previously.

Then promote each build through a test cycle:

  1. Point designated scratch machines directly to the dated directories, such as:


    The scratch machines' Kickstart and yum configurations will change with every build, to point to the (new) dated directory.

  2. When a label has proven somewhat stable, release it to a wider audience. Designated test machines are integration areas for homegrown and third-party software. Your internal developers and QA staff will primarily use these.

    Create a symbolic link dist-testing that points to the dated build directory (dist-20050105 in this example). In turn, the test machines' Kickstart and yum configurations point to the symbolic link abstraction:


    The test machines' Kickstart and yum configurations don't change. They are free to update from this repo at leisure.

  3. After the build label has proven itself on the test machines, release it to the production hosts. Create a symbolic link, dist-stable, that points to the build's dated directory. Production hosts point to this designated "stable" URL:


Promote each build through this cycle to ensure RPM updates' stability and compatibilty with your environment. Of course, you're free to add more steps to the promotion cycle, or split your production machines into A/B groups that update on staggered schedules.


Running your own yum repo saves time and bandwidth, and gives you much more control than pointing your machines to the public repos. Folding this into the Kickstart process brings you closer to a shop that runs itself.

This article barely touched on yum client maintenance, such as the occasional cache cleansing. See Resources section for links to the yum documentation.


Q Ethan McCallum grew from curious child to curious adult, turning his passion for technology into a career.

Return to the Linux DevCenter.

Sponsored by: