Saturday, December 6, 2008

Remastering Red Hat Enterprise Linux 5 DVD

In my office, the Linux buzz is growing, with more and more engineers trying their hand at Qt programming. I've been helping people install Red Hat Enterprise Linux 5 (RHEL 5) and get started with Qt 4. RHEL 5.1 comes with older (aka stable, or proven, as we like to call in our industry) versions of Qt, KDevelop and GDB.

So, to make things easier, I set out to customise an RHEL 5 DVD. My original plan was to create a kick-start file for easier installation. Then I became too ambitious and decided to customise the whole damn thing. After several days of meddling with rpms and xml files, I'm happy to announce SUCCESS!!

This post is meant to be a guide to all those brave souls who wish to do the same. Fear not, comrades, it's not as difficult as it looks like. In fact, if you don't want to build any new RPMs, it's quite easy. You can reportedly use a tool called Revisor to easily customise a Fedora / Red Hat distribution. I'm no sure about the effectiveness of this tool for RHEL, since I want to update and add packages to the base distro. The manual method I describe here involves copying RPM files, editing some XML files (simple) and re-creating the ISO image.
Here we go..

Before we start

I guess it's possible to do this from another installed distro, Fedora for instance. Since I wanted to download additional packages and didn't know how to do that from another distro, I first installed RHEL 5.1 on my machine. All steps I describe were done within that installation.
If you want to add more packages to your custom RHEL, checkout EPEL and RPMForge repositories. You'll find the setup instructions in the repective sites. You'll also need yumdownloader tool from the yum-utils package to download RPM files from the repositories. To install, do:

yum install yum-utils

Similarly, install the following programs/packages:
createrepo - for re-creating the YUM repo information
mkisofs - for creating the ISO image
anaconda-runtime - for inserting the 'media check' checksum

The install media structure

Make a copy of the install media tree. You can either copy files from the DVD, or mount the ISO file and copy from it.
To mount the ISO file:

mount -o loop /path/to/iso/file /path/to/mount/point

Make sure you copy all files. Including the hidden ones. There's one file named .discinfo. Make sure you get that one, otherwise the installer will not recognise your DVD. I'll assume you 've copied all files to some directory named rhel_custom.
The RPMs are located in Client, VT and Workstation directories. The isolinux directory contains files for the boot. We have license for Workstation edition, and so I'll explain for Client and Workstation directories, and I believe the steps are same for VT as well.

The repository information

Let's consider the Client directory. You'll find a directory called repodata which contains the repository information for YUM. You can delete all files except comps-rhel5-client-core.xml from that directory. We will re-create the repo information once we are done customizing.
Open the comps-rhel5-client-core.xml file using a text editor. Don't let the multi-lingual stuff scare you. The file is fairly straight forward. Scan through the first 7-8 lines.
As you can see, this file describes what you see in the package selection step of the installer. the tag defines the group called admin-tools and whose name is Administration Tools. Sound familiar?
Scroll down the the list of translations of the name, and you'll see description, and further down, the default and uservisible values. If default is true, that group will be selected by default. uservisible decides whether the group is visible to the user installing the distro. You'll find that some groups have this set to false.

Now comes the packagelist. Here are two sample lines:

<packagereq type="default">authconfig-gtk</packagereq>
<packagereq type="conditional" requires="aspell">aspell-af</packagereq>

The possible values for type are "mandatory", "default", "optional" and conditional.
Mandatory packages are installed if the group is selected, and won't even show up in the list. Default packages are shown in the list, and selected by default. Optional ones are listed, but not selected by default. Conditional packages are selected if the required package is selected.

Now it must be fairly simple to add a new package. For example, let's say we want to include kchmviewer, a CHM file viewer, to the distro.
We first download the RPM file (I assume you've setup EPEL and RPMForge correctly, and have yum-utils installed).

yumdownloader --resolve kchmviewer

This fetched the kchmviewer-3.1-1.el5.rf.i386.rpm file from RPMForge repo. Depending on your system configuration, it might pull other rpms also. make note of the files downloaded.
Copy the RPM file to the Client directory. If the RPM had dependencies, make sure you copy those files as well. Sometimes, an older version of the same package might be available on the DVD. In that case, you need to delete the old ones and copy the new ones. In short, make sure you don't violate any dependencies. Don't forget to check the Workstation directory too. You'll find that the devel packages for several libraries are available in the Workstation directory.

Once you've copied all necessary RPM file, edit the XML file to add the new package listing. Identify the group to which the package should belong. Select a group, and add an entry in the packagelist, selecting "mandatory", "default" or "optional". The XML file is supposed to be sorted. But don't worry about that now. We'll do an automatic cleanup later.

Sorting the XML files

Once you have a consistent RPM setup and XML files (in Client, Workstation and VT directories), it's time to do cleanup. You'll need a file comps-cleanup.xsl for doing cleanup. Download from
To prepare Client, copy the file to Client/repodata folder, and in a terminal, type:

xsltproc --novalid -o sorted-file.xml comps-cleanup.xsl comps-rhel5-client-core.xml

This will generate sorted-file.xml from the original XML file, printing some information as well. If everything is OK, you can backup the original XML file and rename the sorted file to comps-rhel5-client-core.xml. Delete all other files in 'repodata'.

Repeat the steps for Workstation and VT directories, if you've modified something there too. Note that the XML filenames are different for each directory.

Re-creating the repository information

cd to the Client directory, and do:
createrepo -g repodata/comps-rhel5-client-core.xml .

Repeat the same for Workstation and VT directories (again, note that the XML filenames are different). If all is OK, move on..

Creating the ISO image

All right! Move to the root directory (rhel_custom). Make sure .discinfo file is available there. Issue the following commands:

chmod a+w isolinux/isolinux.bin
find -name TRANS.TBL -exec rm '{}' \;

(Not sure if it is really necessary to delete TRANS.TBL file).

mkisofs -J -T -o ../rhel5_custom.iso -b isolinux/isolinux.bin -c isolinux/ -no-emul-boot -boot-load-size 4 -boot-info-table -R -m TRANS.TBL .

../rhel5_custom.iso is obviously the output image file. Change the path if you need to.

Once you have the image file, move to the directory containing the image. Now we need to insert MD5 checksum in to this image. The Anaconda 'media check' feature uses this checksum to verify the integrity of the DVD. If you skip this step, media check will not be available.

/usr/lib/anaconda-runtime/implantisomd5 rhel5_custom.iso


That's it. Your very own RHEL 5 is ready. Before you burn to a DVD, it's better to test the image using a virtualized environment. Checkout Sun VirtualBox if you've never used one. This way, you need not use physical DVDs to test your distro.

Good luck.


  1. Nice to see this. Does it hold good for the new version RedHat 6 also ?

  2. @Sudhir
    I haven't tried with RHEL 6 yet. I guess Revisor should be easier.

  3. Hi there,
    Very nice indeed and works well with RH6 as well with minor modifications, thanks so much.
    I've a question though: I'm not able to have packages installed from other architectures (for instance having an i686 package added on a x86_64 RHEL6), I tried by adding field arch='i686' in the xml but I didn't succeed even if the package exists on the iso image.

    line added in xml file:

    I'd appreciate if you could comment on this,

    1. Oups xml part was filtered out ...
      I added arch='i686' in xml file for e2fsprogs-devel

    2. @Alain
      Good to know that it works with EL6 too. I was about to start customizing Centos6.4 but was worried if the same method would work. Could you tell me what minor modifications were needed for el6?

      As for multilib support, I've never tried it myself. But try using the suffix ".i586" (or whatever is appropriate for your arch) to the package name.

    3. @Alain
      There might even be some multilib rpms in the original DVD. If so, see how they are listed in the XML files.

    4. Hi Syam,
      1) here are the minor changes.

      -> xml filenames are encoded with some sort of hash code.

      xlstproc -> no change but I use /usr/share/doc/comps-extras-17.8/comps-cleanup.xsl

      - rm all files in repodata and Server/repodata
      - copy output of xlstpoc into repodata and Server/repodata (e.g. comps-server.xml)

      call createrepo twice (works, but not sure it's optimal) :
      createrepo path_to_clone/Server -g repodata/comps-Server.xml
      createrepo path_to_clone -g repodata/comps-Server.xml

      mkisofs: no change but I do not rm TRANS.TBL as apparently it is not rebuilt.

      I added a few packages and tested it with vmplayer, it worked fine.

      2) about multilib a few comments: yes they are in the original DVD, but I'm not able (yet) to have them installed as I need.

      - only x86_64 and noarch are installed by default even if i686 packages are there, and for instance crontabs which is "noarch" is simply listed under "<packagereq type=mandatory>crontabs< /packagreq>" without any arch specified

      - I tried removing the x86_64 version of a package and tadaaa the i686 version is installed instead -> does not really help, I often need both i686 and x86_64 for a given package

      - comps-cleanup remove duplicate entries even if arch is different

      - replacing i686 with i586 does not change the behavior: I guess arch is either not used or misplaced

      - setting the full name of the package does not work either

      still searching, maybe I missed something :)

    5. Have you tried putting the arch as a suffix to the package name? That's how one installs a multi lib package using yum.

      I.e. try using e2fsprogs-devel.i686 as the package name.

    6. nice try ... but does not work.

      anaconda.yum.log:[2013-08-27 01:32:46,210] DEBUG : No package named e2fsprogs-devel.i686 available to be installed
      anaconda.yum.log:[2013-08-27 01:32:46,210] DEBUG : No package named e2fsprogs-devel.x86_64 available to be installed

  4. does not work either:

    anaconda.yum.log:[2013-08-27 01:32:46,210] DEBUG : No package named e2fsprogs-devel.i686 available to be installed
    anaconda.yum.log:[2013-08-27 01:32:46,210] DEBUG : No package named e2fsprogs-devel.x86_64 available to be installed

  5. Don't know why, last comment is not visible ...

    Anyway I tried and got this in anaconda.yum.log

    anaconda.yum.log:[2013-08-27 01:32:46,210] DEBUG : No package named e2fsprogs-devel.i686 available to be installed
    anaconda.yum.log:[2013-08-27 01:32:46,210] DEBUG : No package named e2fsprogs-devel.x86_64 available to be installed