Table of Contents
My goal is to customize the RedHat installation CD from their 7.3 official release:
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.
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.
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
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.
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
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.
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.
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
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!
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. "
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.
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.
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.
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... }
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 | ...
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.
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.
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"
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
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
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
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
dumphdrlist.py /mnt/iso1/RedHat/base/hdlist > /export/baks/hdlist.o1 dumphdrlist.py /mnt/iso1/RedHat/base/hdlist2 > /export/baks/hdlist.o2
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
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.
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/
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
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.
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.
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).
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.
Kickstart Presentation
http://www.muug.mb.ca/meetings/Kickstart-presentation-dec-11.pdf
KickStart HOWTO
http://www.redhat.com/mirrors/LDP/HOWTO/KickStart-HOWTO.html
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
Burning a RedHat CD HOWTO
http://imsb.au.dk/~mok/linux/doc/RedHat-CD.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/
Mark's Kickstart Examples
http://www.gnujobs.com/mark/articles/Kickstart.html
Redhat Kickstart Manual
http://www.redhat.com/docs/manuals/linux/RHL-7.3-Manual/custom-guide/ch-kickstart2.html
http://www.redhat.com/docs/manuals/linux/RHL-7.3-Manual/custom-guide/ch-ksconfig.html
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
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