Remastering a Debian 5.0.3 (Lenny) CD for use in an Unattended Install

I want to create an attended Debian installation based on a standard Debian 5.0 (Lenny) CD for use with VirtualBox. This is part of an overall project to make all my servers similar and maintain them with Puppet.

At the core of an unattended debian install is a preseed.cfg file. The preseed.cfg file contains the answers to all the questions asked during the installation and is capable of performing additional package installs and running commands post installation. The whole trick is preseed.cfg must be in the root of the initrd.gz on the ISO used to run the install. Here is how I did it, after a lot of struggling, and searching.

Here is an preseed.cfg.

To start download just the first CD debain-503-amd64-CD-1.iso. This allows you to get a minimal installation installed without needing to download the internet for each vm. At this point I assume there exists a preseed.cfg to use during the unattended install

Then the high level process is as follows:

  1. Unpack the iso image
  2. Unpack the initrd.gz
  3. Put the preseed.cfg into the root of the unpacked initrd.gz
  4. Pack the initrd.gz
  5. Replace the original initrd.gz in the unpacked iso image
  6. Rebuild the iso image
  7. Boot the iso and start the unattended install

Unpacking the iso Image

Unpack the iso image in a directory called debian-503. At this point I assume the debian-503-amd64-CD-1.iso has been downloaded.

$ rm -fr debian-503
$ mkdir debian-503
$ bsdtar -C debian-503 -xf debian-503-amd64-CD-1.iso

Note I remove any existing debian-503 folder as typically it takes a couple of tries to get all the steps correct.

Unpack the initrd.gz

Depending on the version and linux os the initrd.gz might be one of: a gziped cpio archive, or a gziped file containing a cramfs partition. In the case of Debian 5.0.3 (Lenny) it is a gziped cpio archive.

First create a backup of the existing initrd.gz. This avoids having to unpack the iso image again (if you mess up the initrd.gz). Note that when the iso image is unpacked none of the existing files or directories are writeable, hence the chmod commands.

$ cd debian-503
debian-503 $ chmod u+w install.amd
debian-503 $ cp install.amd/initrd.gz install.amd/initrd.gz.org
debian-503 $ chmod u-w install.amd install.amd/initrd.gz.org
debian-503 $ cd ..
$

Next unpack the initrd.gz.org.

$ rm -fr debian-503-initrd
$ mkdir debian-503-initrd
$ cd debian-503-initrd
debian-503-initrd $ gunzip -c ../debian-503/install.amd/initrd.gz.org | cpio -id
debian-503-initrd $ cd ..
$

Note: I had two errors reported by cpio when it tried to create dev/null and dev/console I was able to safely ignore theseā€¦

Drop in preseed.cfg

In the root of the unpacked initrd.gz (debian-503-initrd) copy in the preseed.cfg. I kept the master preseed.cfg in the same directory as debian-503 and debian-503-initrd.

$ cp preseed.cfg debian-503-initrd

Repack initrd.gz

This is actually where I made the most mistakes. It took a long time to get the exact commands correct. Typically I created corrupt initrd.gzs resulting in 'Kernel panic VFS: unable to mount root fs on unknown wn=block' during the boot of the vmlinuz kernel in isolinux.

$ cd debian-503-initrd
debian-503-initrd $ find . | cpio --create --format='newc' | \
                       gzip  > ../debian-503-initrd.gz
debian-503-initrd $ cd ..
$

Replace the original initrd.gz

Replace the existing initrd.gz on the iso image with the new initrd debian-503-initrd.gz. It is worthwhile to make sure that the new initrd includes preseed.cfg in its root folder.

$ cd debian-503
debian-503 $ chmod u+w install.amd install.amd/initrd.gz
debian-503 $ cp ../debian-503-initrd.gz install.amd/initrd.gz
debian-503 $ chmod u-w install.amd install.amd/initrd.gz
debian-503 $ cd ..
$

Note: Again watch out for permission issues.

Rebuild the iso image

The final step is to rebuild the iso image. In this case the new iso is called debian-503-amd64-CD-1-preseed.iso.

$ rm debian-503-amd64-CD-1-preseed.iso
$ mkisofs -o debian-503-amd64-CD-1-preseed.iso  \
          -r -J -no-emul-boot -boot-load-size 4 \
          -b isolinux/isolinux.bin              \
          -c isolinux/boot.cat ./debian-503 2> /dev/null
$

Note: I remove any existing debian-503-amd64-CD-1-preseed.iso, because I assume this may exist from a previous attempt.

Automation

I ended up writing a small bash script to perform all the above steps, because it also took a couple of tries to get the master preseed.cfg file correct. Each time you need to change the preseed.cfg you need to run through most of the steps above.

Improvements

These are some improvements or thoughts I had, if I was going to do this again.

  • Try a PXE network install this would avoid having to rebuild the iso images.
  • Change the menus in the CD isolinux to select automated install after a timeout
  • Change the menus in the CD isolinux to use a different initrd.gz image (avoids backing up the original).