Customize RedHat 7 Installation


Table of Contents

Make your own perfect RedHat installation 
Introduction 
Install the system 
Creat you own kickstart configuration file 
Organize the directory 
Get the lasted copy of RedHat updates 
Pick the rpms you want 
Updates our rpms 
Working on the comps file 
Prepare your own installation disk 
Configure post installations 
Creating a bootable CD 
Next step 
Troubleshooting 
References 
cmd:kickstart 
Kickstart Simple Install 
ksconfig usage help 
partition handling sample 
Helpful tip 
Bare bone RedHat 7 Customised Installer 
The RULE Project 
Introduction 
Step 1 - Prepare the build system 
Step 2 - Prepare the build source tree 
Step 3 - Generate a new hdlist file 
Step 5 - Generate a package order file (optional) 
Step 8 - Create the iso9660 filesystem images 
Burning your own updated RedHat CD 
Anatomy of the Red Hat FTP site 
The "RedHat" directory — the core of the distribution 
Incorporating the updates 
At last: burning the CD 
extract a list of rpms from the /RedHat/RPMS directory 

Make your own perfect RedHat installation 

Introduction 

My goal is to customize the RedHat installation CD from their 7.3 official release:

  • Create a cdrom that already has all the update packages included
  • Have the Linux installation automatically follows my pre-determined settings
  • Specify a customized list of RPMs to install
  • Able to customize the virgin system further at the end of the installation
  • Do it all on one (1) CD.

Credit 

This article is built on top of all the articles listed in the reference section. You are strongly recommended to go over all of them before go on reading this article.

Special thanks to Gray Watson, author of "Customized RedHat Linux Kickstart Installation Cdrom" and Tony Nugent ("The (unofficial) RedHat 7 Customised Installer mini-HOWTO"). Without their renovative experience, there won't be this article. More over, I've "borrowed" lots of materials from their article, sometimes even the whole paragraph is copied over. :-) If you don't have much time, you should at least read Gray's "Customized RedHat Linux Kickstart Installation Cdrom" first. It is the most clear and concise article I've read so far.

Install the system 

First of all, if you download the CD images from the Internet, do not burn any CD yet, instead, install Linux from a hard drive first.

Making Installation Diskettes 

In Linux 

mounted the cd at /mnt/cdrom

cd /mnt/cdrom/images
dd if=boot.img of=/dev/fd0
# OR if you are installing off the net
dd if=bootnet.img of=/dev/fd0
In Dos 

To make a diskette using MS-DOS, use the rawrite utility included on the Red Hat Linux CD-ROM in the dosutils directory.

rawrite asks you for the filename of a diskette image; enter the directory and name of the image you wish to write. Then rawrite asks for a diskette drive to write the image to; enter a:. Finally, rawrite asks for confirmation that a formatted diskette is in the drive you have selected.

Note 

Red Hat suggestes to use updated diskette images obtained from its Linux errata page:

http://www.redhat.com/apps/support/errata/

For more information, refer to the instructions on making the boot disk at http://www.redhat.com/docs/manuals/linux/RHL-7.3-Manual/install-guide/s1-steps-install-cdrom.html#S2-STEPS-MAKE-DISKS

install from a hard drive 

Choose "Hard Drive" option to install Red Hat Linux from a hard drive. Two text entry boxes for hard drive partition and hard drive directory will appear. Enter the hard drive partition that contains the ISO images (for example, /dev/hda1) in the Hard Drive Partition text box, and enter the directory that contains the ISO images in the Hard Drive Directory text box.

If you don't have enough space on your PC, the next mininum-hassle solution is to find a Linux box, loop mount the disk images and make them accessible from http. All decent Linux distro have loop mount and web server features ready for use. But a PC with a big empty HD space is strongly recommended. The following paragraph assumes that you have enough empty spaces on HD (~3G).

Caution, RH7.3 has a bug in its installation. I have no problem installing from hard drive using hda1. But when I try to reinstall the second time, RedHat refuses to list /dev/hda1. All I can choose is the Linux partitions. Darn! What sense it makes if the only places I can pick the images are those I am going to destroy?

So I recommend that you make at least two Linux volumes. One for root volume, and the other for the /export volumn. Copy the image files into the /export volumn right after the installation, in case you need to reinstall again. And preserve the /export in the following installations.

This is what I've been doing. Several small (2G) volumes for various flavor/version of Linux, and one big /export volume to share my home accross all of them. It also makes upgrading/testing the OS quite easy.

Creat you own kickstart configuration file 

It is high time to create you own kickstart configuration file now. Kickstart allows you totally automate an installation while giving a very high degree of control over what the installer does (how partitions are created, what filesystem types to use, what packages are selected, how the box is configured, etc) by providing installer directives and hooks to run customised scripts and so on. Once you've have it, you can do reinstall whenever you want, hassle free.

Organize the directory 

The following paragraphs assumes the following directory structure is used, which is the same as mirroring the latest RedHat ftp site.

.../linux/7.3/en/os/i386
.../linux/updates/7.3/en/os/i386

This assumes that we Download lasted RedHat updates into …/linux/updates/7.3/en/os/i386, and work on our customized CD image in …/linux/7.3/en/os/i386. Please note, do not mirror/update our working directory (…/linux/7.3/en/os/i386) from the Internet. Otherwise, our work will be revoked back to the original.

Personally, I choose /export as their root directory. In the following paragraphs, I'll use the following directories for the explanation:

/export/linux/7.3/en/os/i386
/export/linux/updates/7.3/en/os/i386

Get the lasted copy of RedHat updates 

I know all the people are complaining the lousy update agent that RedHat has. My experience is really dramatic: The speed I downloaded the RedHat ISO images was about 4.2Mbps. But when I was trying to use the RedHat update agent, it took my a whole day downloading 87% of the XFree86 package. Then I could not get back onto RedHat update system any more. More over, I learnt that the whole day downloading was well wasted because RedHat update agent was not able to make use of the already downloaded 87% of the XFree86 package. Further, as of May 2002, the total size of the all the i386 update packages for rh72 had bloated to almost 1100Mb (including the .src.rpms). And less than two weeks out from its official release, there are already 191Mb of updates to redhat 7.3 (kernel, evolution updates). You can't win the war in RedHat update agent. Instead, here we will never need to start the fight.

The trick is to download them, instead of updating them!

Pick the rpms you want 

"trim down" approach 

Gray Watson suggested to use "trim down" approach to select your own rpms:

Boot into Linux, loop mount the installation ISO images. Copy each of of them into the same place that you've picked.

# Load the first CD into the drive
mount -o loop /sourcepath/valhalla-i386-disc1.iso /mnt/cdrom
mkdir /somepath/cdrom_files
cd /mnt/cdrom
tar -cf - . | ( cd /somepath/cdrom_files ; tar -xvpf - )
cd /somepath/cdrom_files
umount /mnt/cdrom
# Repeat the above steps for disk2 & 3.
mount -o loop /sourcepath/valhalla-i386-disc2.iso /mnt/cdrom

He then went on:

"The next stage of the process is to trim down the list of packages until you get below the 700mb that will fit onto one CD. In general, I sorted the RedHat/RPMS directory by size and started at the top and moved down removing the rpms that I knew I did not need. You need to be careful here because there are dependencies between packages that aren't always expected. Someone probably has a tool to resolve dependencies but I don't know about it…

"If you rebuild the hdlist file, make the CD, and try to install and it prompts for the 2nd CD in the set then you missed a dependency. I'm not sure if or how you can tell which package is the specific problem. "

"add up" approach 

Resolve RedHat rpms' dependencies had always been a painful headache to me. More over, I haven't been paying close attention what rpm packages had been install on my system before, and what rpms I do not need. For example, I didn't know if I need the following rpms or not up until very recently: specspo, cyrus-sasl, ORBit or cURL.

So, what I did basically is to carefully select what I need during RedHat installation and include all the installed rpms in my customized CD:

cd /mnt
mkdir iso{1,2,3,4,5} rpms-org rpms-pck
mount -o loop /export/rh73/valhalla-i386-disc1.iso /mnt/iso1
mount -o loop /export/rh73/valhalla-i386-disc2.iso /mnt/iso2
mount -o loop /export/rh73/valhalla-i386-disc3.iso /mnt/iso3
cd rpms-org
ln -s ../iso1/RedHat/RPMS/*.rpm .
ln -s ../iso2/RedHat/RPMS/*.rpm .
ln -s ../iso3/RedHat/RPMS/*.rpm .
cd ../rpms-pck
rpm -qa | sed 's|^|ln -s ../rpms-org/|; s/\s*$/*.rpm ./'
!! | sh
cd ..
tar -h -czf rpms-pck.tgz rpms-pck

Now, I've got all the installed rpms on my system in rpms-pck.tgz file.

In practice, I hand-crafted my own kickstart configuration file to select the very rpms that I really need. For example, all tools from the "Software Development" package group, but not any "-devel" rpms from it. If you don't want to go this far (to be so prefect), following my above steps would be definitely enough.

Updates our rpms 

The "add-rpm.py" in the reference section should be the perfect tool for this job, since it came out (almost) directly from RedHat anaconda. But I just couldn't make it going, even after opening up and reading the code.

So I hacked a Perl tool to update the rpms. It helps to merge RedHat official updates into our perfect RedHat installation disk. It is at http://xpt.sf.net/techdocs/linuxsm/CustomizeInstallation/tools/updateMirror.pl

Usage:

cd /export/linux
updateMirror.pl i386 > updates.sh 2> updates.log

The "updates.log" shows what rpms are to be updated, and the "updates.sh" holds the actual commands to carry out the updating.

Now execute it:

sh updates.sh 2> updates.log

Now the updates.log holds the error log. It should be empty. Check with:

ls -l updates.log

If everything went on smoothly, you can remove the apt archives if you like:

rm /var/cache/apt/archives/*.rpm

If you want to backup the to-be-removed rpms, or gather would-be-copied rpms to somewhere else, refer to the program help for illustrations.

Working on the comps file 

This step in optional, if you don't want a prefectly clean installation disk. At least you can safely ingore this section during your first attempt.

Intorduction to comps file 

In the RedHat/base directory on the 1st CD is the comps file which is what anaconda reads when it displays the various packages of RPMs. It is also used used by the %packages section of the ks.cfg file. An example the comps file is:

4
1 Base {
  MAKEDEV
  anacron
  ...
}
0 --hide Network Server {
  @ Network Support
  (arch !i386): vnc
  finger-server
  ? X Window System {
    i386: compat-libstdc++
    libpcap
  }
  ...
}

The leading 4 means the format version of the comps file.

The "1 Base {" defines a collection of RPMs associated with the Base package. The 1 means that it is enabled by default. The "0 —hide Network Server {" defines the Network Server package which is off by default. The "—hide" means that it should be hidden from the user's package selection tool in anaconda.

The "@ Network Support" line means that the "Network Server" package includes the "Network Support" package. The "(arch !i386") line allows certain packages to be installed if (or in this case if not) installing on specific architecture. The "? X Window System {" line means that if X windows is installed then the packages in subsection are included in Network Server package.

In any case, by looking at this file, you can see which RPMs you use when you install a Network Workstation and which ones are candidates for removal if you don't install X11 stuff.

Further tuning can be done, for example to add an entry for any extra rpms that you specifically want to install:

0 --hide Extras {
   numlock
   xcdroast
   taper
   etc...
}

Formal definition of comps file 

From "Building a kernel for AARNet Dell machines" http://www.aarnet.edu.au/redhat/build.txt

The "comps" file format is not documented, but is reasonably obvious. The mysterious "4" at the top of the file is a version number for the file format. The sections are of the basic form

<wanted> <options> <component> {
  <dependency>
  ...
  <package>
  ...
  <optionalpackage>
  ...
}

Where <wanted> is 1 where the package defaults to being installed, 0 otherwise. <package> is the RPM package.

<options> ::= <nil>
<options> ::= --hide
<dependency> ::= <nil>
<dependency> ::= @ <component>
<optionalpackage> ::= ? <dependency> {
                        <package>
                        ...
                      }

All lines appear to have the form

<condition>: <text>
<condition> ::= <nil>
<condition> ::= !<condition>
<condition> ::= <architecture>:
<condition> ::= (<expr>):
<expr> ::= <term>
<expr> ::= <term> and <term>
<term> ::= arch <architecture>
<term> ::= arch !<architecture>
<term> ::= lang <language>
<term> ::= lang !<language>
<architecture> ::= i386 | ia64 | sparc | alpha
<language> ::= <lang>[_<region>[.<codeset>]]
<lang> ::= ja | cs | pl | ro | sl | sk | tr | uk | ru | ...
<region> ::= BR | CN | HK | TW | GB | CA | ES | ...
<codeset> ::= gb2312 | ...

Update the comps file according to your pick 

I've hacked another Perl tool, to clearn out from the comps file the packages that you have not selected. It is at http://xpt.sf.net/techdocs/linuxsm/CustomizeInstallation/tools/compsClean.pl. Again, this might not be necessary, Gray Watson didn't do it when building his own RH7.2.

The usage is simple:

compsClean.pl [architecture] [comps file] [path to rpms]

For example:

compsClean.pl i386 RedHat/base/comps /export/rpms/rpms-pck > /tmp/comps.new

Then you can copy the "comps.new" over the old "comps", of course after doing a diff on them.

Prepare your own installation disk 

The iso image can not be modified/updated. So we need to duplicate the first CD, and optionally do some cleaning up along the way:

cd /mnt/iso1
find . | grep -E '/(README|RELEASE-NOTES|fips[12]|images/|TRANS.TBL)'
find . | grep -Ev '/(README|RELEASE-NOTES|fips[12]|images/|TRANS.TBL)' | cpio -vpdm /export/linux/7.3/en/os/i386

The file TRANS.TBL in each directory on the CDROM is used for non-Rock Ridge capable systems (e.g., MS DOS) to help establish the correct file names. They can be safely removed.

Checking the integrity of the rpm packages 

Do this to check the internal md5 checksum of each rpm package to make sure that they are all intact:

cd /export/linux/7.3/en/os/i386/RedHat/RPMS
rpm -K  --nopgp --nogpg *.rpm | grep "NOT OK"

Get the genhdlist ready 

In the base directory, there is the hdlist file containing most of the header fields from all the RPMs in the RPMS directory. This means that all the interdependencies among RPM packages can be determined just by reading hdlist without having to read all the RPM packages which is quite convenient especially during FTP installs.

Another use of hdlist is mapping package names to file name, eg. perl to perl-5.004-6.i386.rpm. This means that if you want to incorporate updates from RedHat or add your own packages to the RPMS directory, you need to update hdlist.

Once you have removed certain RPMs from the directory and done updating rpms, you will need to rebuild the hdlist file. The file hdlist lists which RPMs are available on the first CD, and the file hdlist2 is for the second CD. You will need to build the genhdlist utility which is included in the anaconda source release. Available from any redhat mirror site, at

/…/ftp.redhat.com/linux/7.3/en/os/i386/SRPMS/anaconda-7.3-7.src.rpm

rpm -ih anaconda-7.3-7.src.rpm
cd /usr/src/redhat/SOURCES
tar -xjf anaconda-7.3.tar.bz2

In the utils directory in the source tarball, should be the genhdlist.c which should be buildable with make genhdlist.

cd anaconda-7.3/utils/
make genhdlist

Rebuilding the hdlist File 

Once you've built the genhdlist tool, go to the root path of your future cdrom system:

cd /export/linux/7.3/en/os/i386
rm -f RedHat/base/hdlist*
genhdlist --withnumbers --hdlist RedHat/base/hdlist `pwd`
ls -l RedHat/base/hdlist*

Please note

  • removing previous copy of hdlist* is vitally important. I first tried to play it safe and renamed them, but that cause me a lot of trouble.
  • If your pick is more than once CD, make sure to list them all, like this:

    genhdlist --withnumbers --hdlist RedHat/base/hdlist `pwd` /mnt/iso2 /mnt/iso3

Compare the result 

This is optional. It requires a tools listed in the later "Helpful tools" part. I include them here to show how I did the test. The reason doing this is that hdlists are binary files. You can't compare them directly.

dumphdrlist.py RedHat/base/hdlist | less
old list 
dumphdrlist.py /mnt/iso1/RedHat/base/hdlist > /export/baks/hdlist.o1
dumphdrlist.py /mnt/iso1/RedHat/base/hdlist2 > /export/baks/hdlist.o2
new list 
dumphdrlist.py /export/linux/7.3/en/os/i386/RedHat/base/hdlist > /export/baks/hdlist.n1
dumphdrlist.py /export/linux/7.3/en/os/i386/RedHat/base/hdlist2 > /export/baks/hdlist.n2
compare 
diff -wu /export/baks/hdlist.o1 /export/baks/hdlist.n1 | less
diff -wu /export/baks/hdlist.o2 /export/baks/hdlist.n2 | less

Configure post installations 

This is probably the best feature of all, and something which there is no direct equivalent to in the manual installation process. What we can do here is specify a sequence of shell level commands which should be executed after the main installation (disk partitioning, package installation, and so on) is complete.

step 1 

If you need to copy files off of the install media to the new installation then you'll need to do something like the following:

%post --nochroot
# the --nochroot is necessary to not change root into the new installation
# cp /mnt/source/dir/file /mnt/sysimage/dir/file
# where /mnt/source is the install media
# and /mnt/sysimage is the new installation
# Use my very own profile
cp /mnt/source/customized/profile /mnt/sysimage/etc/profile
# My extra can't-live-without tools
cp /mnt/source/customized/opt.tgz /mnt/sysimage/

step 2 

The beginning of this section is signified by the %post directive in the KickStart config file. In what follows you can take advantage of all of the utilities which have been installed on your newly built Linux system, and operated on the real root file system.

For example, setup crontab jobs by creating root crontab entries as files in one or more of the directories /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly.

Mine is:

%post
# turn off packages that we don't want running
echo Turning off some packages
/sbin/chkconfig --level 0123456 isdn off
/sbin/chkconfig --level 0123456 nfslock off
echo Turning on some packages
/sbin/chkconfig --level 345 httpd on
/sbin/chkconfig --level 345 postgresql on
/sbin/chkconfig --level 345 rsync on
/sbin/chkconfig --level 345 wu-ftpd on
echo Change firewall from ipchains to iptables
chkconfig --level 12345 ipchains off
chkconfig --level 345 iptables on
/bin/bash -c 'rm -f /root/.bash_logout'
/bin/echo "/opt/bin/guide &" >> /etc/rc.d/rc.local

Creating a bootable CD 

Create iso9660 disk image 

Refer to Tony's article for a full script creating iso9660 disk images. Also available at my local copy "Bare bone RedHat 7 Customised Installer" http://xpt.sf.net/techdocs/linuxsm/CustomizeInstallation/linuxsm01.003.html#section-1.

Note, mkisofs will show the following warning:

Warning: creating filesystem that does not conform to ISO-9660.
Using XFREE000.RPM for  RedHat/RPMS/XFree86-ISO8859-15-100dpi-fonts-4.2.0-8.i386.rpm (XFree86-100dpi-fonts-4.2.0-8.i386.rpm)
Using XFREE001.RPM for  RedHat/RPMS/XFree86-100dpi-fonts-4.2.0-8.i386.rpm (XFree86-4.2.0-8.i386.rpm)

This is normal, because we are generating Joliet directory records in addition to regular iso9660 file names. Also, we will have long file names on CD (e.g., XFree86-100dpi-fonts-4.2.0-8.i386.rpm) instead of short ones like XFREE000.RPM. Use the technique in the next topic to verify it.

Test the image 

If you're paranoid you can test your new disk image by mounting it. If you forgot to fix the file permissions or set the rock ridge extensions then the error will be obvious here since the file names and directory structure will be wrong.

mount -t iso9660 -o ro,loop=/dev/loop0 /tmp/redhat.img /mnt/cdrom

When you're done, don't forget to unmount it.

Next step 

You might want at some point to make a full distribution CDROM set that contains all tools from RedHat official distribution, while having all new rpms updated. If so, go on to read Tony Nugent's "The (unofficial) RedHat 7 Customised Installer mini-HOWTO", listed in the following reference section. You may also want to check out my local copy "Bare bone RedHat 7 Customised Installer" if you find his a bit overwhelming at first. http://xpt.sf.net/techdocs/linuxsm/CustomizeInstallation/linuxsm01.003.html#section-1.

But for me, those "ten easy steps" are still too difficult. I dare not to try. Instead, I put all the remaining rpms on another CDROM, and make it also bootable. As Tony said, "why waste a useful feature of a cdrom? If there is space (and not much is needed), there is no reason why you couldn't manually add your own cdrom boot images to them."

I chose the "Tom's Root Boot Disk" (http://www.toms.net/rb/), a self-contained floppy-based linux mini-bootdisk that is useful for running a basic linux system on just about any computer (for rescue, recovery, hardware examination or all sorts of other purposes).

Troubleshooting 

Although this article comes as a whole, it does not mean that you have to take all the steps at once. Instead, you are strongly suggested to take steps as minimum as possible. For example, try make your kickstart configuration file, and test it with the installation first. Actually this is a BIG step already. I spent over a week to make my perfect kickstart configuration file. Try the out of box anaconda-ks.cfg without any modification first. Then make your modification step by step, and keep the copy of all the versions, in order to be able to roll back on failure.

You can't be more careful when doing this, because you've entered the most buggy world of RedHat. Be prepared for it. You are warned.

If you do meet with problems, ask youself if you have made the best effort to kept you step minimum. Can it be split even further? When it can boil down to only one single change, you chance to find out what is wrong will be bigger.

You can also browse all the collections I've made. It will save you a lot of time trying to find them. I think I've covered at least 90% of the related articles from the web and newsgroups by the time this article is prepared. If you meet with some problem that is not covered here, you might be doing something wrong. I can't help you with your specific problem. Please refer to the previous paragraph for the solution. Or better, bug the RedHat for the solution. :-) Last by not least, people in the comp.os.linux.misc newsgroup are generally helpful. You are welcome to fire up open discussions in it. I watch this newsgroup closely.

References 

Web pages 

Customized RedHat Linux Kickstart Installation Cdrom
http://256.com/gray/docs/rh_boot/

The (unofficial) RedHat 7 Customised Installer mini-HOWTO
http://www.linuxworks.com.au/redhat-installer-howto.html

How to make a new kickstart Redhat bootdisk
http://www.reptechnic.com.au/kickstart.html

Kickstart Installation of Red Hat Linux
http://www-personal.umich.edu/~myers/linux/kickstart/

Kickstart Article From Linuxgazette
http://www.linuxgazette.com/issue43/nielsen.kickstart.html

Note,

If any of above links does not work by the time you read this article, you can find a local copy here:

http://xpt.sf.net/techdocs/linuxsm/CustomizeInstallation/mirrored

Other tools 

Joshua Sarro <mthed@shore.net> has contributed a perl script called updateMirror.pl that copies all files from the update directory to the RPMS directory. The script uses some nifty rpm tricks to determine what packages in directory. The "kernel" packages that come in several flavors are also preserved (Certain RPMs, specifically the kernel and kernel-smp packages, include the platform in the filename but not in the package name). You can fetch it here: http://imsb.au.dk/~mok/linux/doc/updateMirror.pl.

Also, Anaconda offers some tools that help to ensure that things are ok.

The python script /usr/lib/anaconda-runtime/check-repository.py can be used to check the RedHat/base/comps file to ensure that it is consistent with the contents of the RedHat/RPMS/ directory. However, comment out the "import todo" entry (around line 38) before you use it. (Thanks to Forrest Taylor <forrestx.taylor@ intel.com> for this hint).

Seth has some more gems available at http://www.dulug.duke.edu/treetools/…

comps-check.pl is "not terribly pretty but it seems to work… for MOST situations. You pass it an architecture a comps file and a dir of rpms - it hands you back whats in the comps file thats missing from the dir of rpms for that arch. http://www.dulug.duke.edu/treetools/comps-check.pl http://www.linuxworks.com.au/comps-check.pl.txt

the add-rpm.py adds updated rpms to an install tree. http://www.dulug.duke.edu/treetools/add-rpm.py http://www.linuxworks.com.au/add-rpm.py.txt

depchecktree.py just takes the dirs you give it, look for all the rpms and tells you if they fully satisfy their dependencies. http://www.dulug.duke.edu/treetools/depchecktree.py http://www.linuxworks.com.au/depchecktree.py.txt

dumphdrlist.py is a python script written by Jeremy Katz (<katzj@redhat.com>) that looks at the RedHat/base/hdlist file and lists which installation disk a particular rpm is on. From Jeremy: "Usage is simple enough — 'dumphdrlist.py /path/to/hdlist' and it will then print the NEVRA of all of the packages as well as the disc it's on in the format" http://www.linuxworks.com.au/dumphdrlist.py.txt