Many thanks for the assistance from the list, especially Philip Rowlands
and James Martin. My "buildIso" script is now working under both FC2
and RHEL3u2. It may even work to cross-target RHEL from an FC2
environment -- I don't have time left today to check, but since my
problems were tracking 1 for 1 between targeting RHEL from RHEL and
targeting RHEL from FC2, I think it's likely.
For the record, using --withnumbers on the genhdlist command got me past
the "/mnt/source" problem but ultimately grub failed at stage 1. Using
the pkgorder command got me past the grub problem.
I am enclosing the buildIso script for those interested. It is still a
work in progress but is reasonably functional. It requires some
supporting files which I will explain as I go. This would work a WHOLE
lot better as an html message with attachments, but I don't know how
well that would encapsulate in the digest or to all list members with
plain mail clients. So let me apologize in advance for the lengthy
plain text message. It seemed the most portable if not the most elegant.
The heart of the script looks at the packages section of the ks.cfg file
and expands it into a list of rpms, using the comps.xml file to expand
package names into the corresponding rpms. It does NOT recursively find
packages within packages. Along the way I found that both FC2 and RHEL3
have a sizeable list of rpms that are included "automagically" even in a
minimal install -- even though they don't belong to any packages and
aren't even listed in comps.xml. The script looks for the list of
implicit rpms in the files "implicit.Fedora" and "implicit.RedHat"
respectively. BTW, I obtained the list by doing a minimal install and
running "rpm --query --all" and comparing the results to what I was
extracting for the Base, Core and Dialup Networking Support packages. I
don't know if there are other implicit RPMs for other packages. For my
purposes I am always building off a minimal install. If anyone knows a
more direct way to obtain this list I'd be interested in learning it.
The rpms should be listed one per line, but I will join them together a
bit here to save some space:
The implicit.Fedora file contains:
beecrypt bind-libs bzip2-libs chkconfig comps cracklib cracklib-dicts
cyrus-sasl cyrus-sasl-md5 db4 dev device-mapper elfutils elfutils-libelf
findutils gawk
gdbm glib glib2 glibc-common gmp gnupg grep groff gzip
hesiod hwdata info iptables isdn4k-utils kernel-smp krb5-libs krbafs less
libacl libattr libselinux libstdc++ libuser libwvstreams libxml2
libxml2-python
lockdev lrzsz lvm2 mailx make MAKEDEV mingetty mkinitrd mktemp modutils
ncurses
net-tools newt nscd openldap openssh openssl pam pcre perl perl-Filter popt
portmap ppp procmail psmisc pyOpenSSL python python-optik pyxf86config
rhnlib
rhpl rmt rpm-python sed slang syslinux tar tzdata usbutils usermode
which words
yp-tools zlib
The implicit.RedHat file contains:
ash basesystem bash beecrypt binutils bzip2-libs chkconfig comps coreutils
cpio cracklib cracklib-dicts cups cups-libs cyrus-sasl cyrus-sasl-md5
cyrus-sasl-plain db4 dev e2fsprogs ed elfutils elfutils-libelf ethtool
expat file filesystem findutils fontconfig freetype gawk gdbm gettext glib
glib2 glibc glibc-common gmp gnupg grep groff gzip hdparm hesiod hotplug
htmlview hwdata info initscripts iproute iputils isdn4k-utils jfsutils
jwhois kbd krb5-libs krbafs krbafs-utils less libacl libattr libgcc libgcj
libjpeg libpng libstdc++ libtermcap libtiff libtool-libs libuser
libwvstreams
lockdev losetup lslk lsof lvm m4 mailx make MAKEDEV mingetty minicom
mkinitrd
mktemp modutils mount mt-st ncurses net-tools newt nscd openldap openssh
openssh-server openssl pam passwd patch pcre perl perl-Filter popt portmap
ppp procmail procps psmisc pspell pyOpenSSL python python-optik pyxf86config
raidtools rdist readline redhat-config-mouse redhat-menus redhat-release
rhnlib rhpl rmt rootfiles rpm rpm-python rp-pppoe sed sendmail setserial
setup shadow-utils slang sudo sysklogd syslinux SysVinit tar tcpdump termcap
traceroute tzdata up2date usbutils usermode utempter util-linux vim-minimal
wget which wireless-tools words wvdial XFree86-libs XFree86-libs-data
XFree86-Mesa-libGL xinetd yp-tools zlib
Both FC2 and RHEL3 appear to have some "missing" files that are listed
in the comps.xml file but don't exist on the disks. The installer
doesn't complain but my buildIso script needs to know about them to know
when to stop looking for RPMs. It looks for these in the files
"missing.Fedora" and "missing.RedHat."
The missing.Fedora file contains:
efibootmgr
elilo
losetup
openCryptoki
ppc64-utils
prctl
run
s390utils
yaboot
The missing.RedHat file contains:
acpid
efibootmgr
elilo
iprutils
iscsi
lrzsz
openCryptoki
ppc64-utils
prctl
reiserfs-utils
s390utils
statserial
yaboot
Finally, there may be some RPMs you want added in or left out depending
on which target you've selected. These are in extra.Fedora and
extra.RedHat.
The extra.Fedora file contains:
-at
checkpolicy
policy-sources
The at rpm was not installing properly under FC2t3 and the -at leaves it
out. This may be fixed under FC2 -- I haven't had time to check yet.
The checkpolicy and policy-sources files are only of interest if you are
using selinux.
The extra.RedHat file contains:
bridge-utils
brltty
I don't know that I really need either of these, but they are installed
in a minimal install and they don't seem to be picked up implicitly like
those listed in implicit.RedHat. So for the moment I'm including them
explicitly.
Before showing the buildIso script itself, I will also include an
example ks.cfg file that seems to be working under both FC2 and RHEL3
and should work with this script. I've left off the %post commands and
hashed out the rootpw.
What's left of the ks.cfg file contains:
install
cdrom
lang en_US.UTF-8
langsupport --default en_US.UTF-8 en_US.UTF-8
keyboard us
mouse generic
skipx
rootpw --iscrypted ##########################
firewall --disabled
#selinux --disabled
authconfig --enableshadow --enablemd5
timezone America/New_York
bootloader --location=mbr --append hda=ide-scsi
clearpart --all --initlabel
part / --fstype ext3 --size 2048
part /sandbox --fstype ext3 --size 1 --grow
part swap --size 1024
reboot
%packages
@ Core
@ Dialup Networking Support
@ Base
# GENERIC ADDITIONS
m4
libsafe
tripwire
# NEEDED FOR NTP
libcap
ntp
tcl
expect
amhsfilter
%post
The buildIso script looks first for custom rpms in the CUSTOM_RPMS
directory (default ../RPMs), then for replacement rpms in the PACKAGES
directory (default ../Packages), and then for standard rpms on the
install CDs. It lays out the ISO file directory structure under ROOTS
(default ../Roots) is ${ROOTS}/IsoRoot. The script contains a lot of
commented mutterings about where things resided under various RH
versions. There are many apparent redundancies and out of desperation I
tended to replace them all where possible. Much of this could/should be
cleaned up -- but it works.
The buildIso script contains:
#! /bin/sh --
#
# Interesting files and where they (should?) reside:
# boot.iso:
# images/boot.iso
# (in 7.1 this was images/boot.img)
# initrd.img: (first two are md5 identical in FC2t2)
# isolinux/initrd.img
# images/boot.iso[/isolinux/initrd.img]
# images/pxeboot/initrd.img
# (in 7.1 this was images/boot.img[initrd.img])
# isolinux.cfg: (identical)
# isolinux/isolinux.cfg
# images/boot.iso[isolinux/isolinux.cfg]
# (in 7.1 this was images/boot.img[/syslinux.cfg]
# ks.cfg:
# /ks.cfg
# isolinux/ks.cfg
# isolinux/initrd.img[(gzipped)/isolinux/ks.cfg]
# isolinux/initrd.img[(gzipped)/ks.cfg]
# images/pxeboot/initrd.img[(gzipped)/isolinux/ks.cfg]
# images/pxeboot/initrd.img[(gzipped)/ks.cfg]
# (in 7.1 this was images/boot.img[(gzipped)/ks.cfg]
#
case `uname --kernel-release` in
2.4*) DEFAULT_TARGET=RedHat
;;
2.6*) DEFAULT_TARGET=Fedora
;;
*) echo "Unrecognized kernel release `uname --kernel-release`"
exit 1
;;
esac
TARGET=${TARGET:-$DEFAULT_TARGET}
ROOTS=${ROOTS:-`(cd ../Roots ; pwd)`}
PACKAGES=${PACKAGES:-`(cd ../Packages ; pwd)`}
CUSTOM_RPMS=${CUSTOM_RPMS:-`(cd ../RPMs ; pwd)`}
ISO_LABEL=PinnacleCSIBastionInstall
ISO_ROOT=${ROOTS}/IsoRoot
ISO_NAME=${1:-BastionInstall.iso}
RPMLIST_NAME=/tmp/rpmlist
TMPLIST_NAME=/tmp/tmplist
RPM_PATH=${TARGET}/RPMS
COMPS_NAME=comps.xml
COMPS_PATH=${TARGET}/base/${COMPS_NAME}
HDLIST_NAME=hdlist
HDLIST_PATH=${TARGET}/base/${HDLIST_NAME}
# N.B. - the IsoRoot ks.cfg has extra rpm names not in the local ks.cfg
KICKSTART_NAME=ks.cfg
KICKSTART_PATH=${ISO_ROOT}/${KICKSTART_NAME}
BOOTCAT_NAME=boot.cat
BOOTCAT_PATH=isolinux/${BOOTCAT_NAME}
CD_ROOT=/mnt/cdrom
BOOTIMG_NAME=boot.iso
BOOTIMG_PATH=images/${BOOTIMG_NAME}
BOOTIMG_MOUNT=/mnt/bootimg
BOOTIMG_ROOT=${ROOTS}/BootImage
CONFIG_NAME=isolinux.cfg
CONFIG_PATH=isolinux/${CONFIG_NAME}
INITRD_NAME=initrd.img
INITRD_PATH=isolinux/${INITRD_NAME}
INITRD_MOUNT=/mnt/initrd
Cleanup()
{
for FS_ROOT in ${ISO_ROOT} ${BOOTIMG_ROOT}
do
if [ -e ${FS_ROOT} ]
then
rm -rf ${FS_ROOT}
fi
mkdir ${FS_ROOT}
done
}
ReplicateNonRpms()
{
if [ -e ${CD_ROOT} ]
then
sudo umount ${CD_ROOT} 2>/dev/null
else
sudo mkdir ${CD_ROOT}
fi
eject
echo -n "Please insert ${TARGET} CD 1 and press ENTER: "
read line
sudo mount ${CD_ROOT}
( cd ${CD_ROOT} ; find . -print | grep -v RPMS | cpio -pdmvu
${ISO_ROOT} )
sudo umount ${CD_ROOT}
eject
chmod 644 ${ISO_ROOT}/${HDLIST_PATH}
}
UnpackBootIso()
{
if [ -e ${BOOTIMG_MOUNT} ]
then
sudo umount ${BOOTIMG_MOUNT} 2>/dev/null
else
sudo mkdir ${BOOTIMG_MOUNT}
fi
sudo mount -o loop -t iso9660 ${ISO_ROOT}/${BOOTIMG_PATH}
${BOOTIMG_MOUNT}
mkdir ${BOOTIMG_ROOT}
( cd ${BOOTIMG_MOUNT} ; find . -print | cpio -pdmvu ${BOOTIMG_ROOT} )
sudo umount ${BOOTIMG_MOUNT}
}
RepackBootIso()
{
chmod 644 ${ISO_ROOT}/${BOOTIMG_PATH}
sudo mkisofs -o ${ISO_ROOT}/${BOOTIMG_PATH} -V "${ISO_LABEL}" -b
isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size
4 -boot-info-table -R -J -V -T ${BOOTIMG_ROOT}
}
# initrd.img: (first two are md5 identical in FC2t2)
# isolinux/initrd.img
# images/boot.iso[/isolinux/initrd.img]
# images/pxeboot/initrd.img
UnpackInitRd()
{
if [ -e ${INITRD_MOUNT} ]
then
sudo umount ${INITRD_MOUNT} 2>/dev/null
else
sudo mkdir ${INITRD_MOUNT}
fi
zcat ${ISO_ROOT}/${INITRD_PATH} >/tmp/${INITRD_NAME}
sudo mount -o loop /tmp/${INITRD_NAME} ${INITRD_MOUNT}
}
RepackInitRd()
{
sudo umount ${INITRD_MOUNT}
rm -f /tmp/${INITRD_NAME}.gz 2>/dev/null
gzip /tmp/${INITRD_NAME}
sudo cp /tmp/${INITRD_NAME}.gz ${ISO_ROOT}/${INITRD_PATH}
sudo cp /tmp/${INITRD_NAME}.gz ${BOOTIMG_ROOT}/${INITRD_PATH}
sudo cp /tmp/${INITRD_NAME}.gz ${ISO_ROOT}/images/pxeboot/${INITRD_NAME}
}
# isolinux.cfg: (they are identical)
# isolinux/isolinux.cfg
# images/boot.iso[isolinux/isolinux.cfg]
#
# allowcddma sometimes helps with CD problems - hasn't made a difference
here
# mem=exactmap mem=640k@0m mem=1023M@1M sometimes helps Proliant memory
# recognition - hasn't made a difference here
#
UpdateLinuxConfig()
{
chmod 644 ${ISO_ROOT}/${CONFIG_PATH}
ed - ${ISO_ROOT}/${CONFIG_PATH} << '!'
H
/default/s/linux/ks/p
/append ks/s|ks|ks=cdrom:/ks.cfg|p
w
q
!
chmod 644 ${BOOTIMG_ROOT}/${CONFIG_PATH}
cp ${ISO_ROOT}/${CONFIG_PATH} ${BOOTIMG_ROOT}/${CONFIG_PATH}
}
# ks.cfg:
# /ks.cfg
# isolinux/ks.cfg
# isolinux/initrd.img[(gzipped)/ks.cfg]
# images/boot.iso[isolinux/initrd.img[(gzipped)/ks.cfg]]
AddKickstartConfig()
{
cp -f ${KICKSTART_NAME} ${KICKSTART_PATH}
ed - ${KICKSTART_PATH} <<!
H
?^[@]?r extra.${TARGET}
w
q
!
}
AddBootMessage()
{
cat > ${ISO_ROOT}/BOOTMSG.TXT <<'!'
Test boot message
!
}
RpmsInPackage()
{
sed -n -e "/<name>${1}<\/name>/,/<\/group>/p"
<${ISO_ROOT}/${COMPS_PATH} | grep '<packagereq' \
| sed -e 's/[<][^>]*[>]//g' | sed -e 's/ *//'
}
DetermineRpmList()
{
# These RPMS seem to be implied without explicit comps.xml entries
cat implicit.${TARGET} > ${RPMLIST_NAME}
sed -n -e '/%packages/,/%post/p' <${KICKSTART_PATH} | grep -v '^ *#'
| grep -v '^%' | grep -v '^ *$' | while read LINE
do
case ${LINE} in
[@]*) RpmsInPackage "`echo $LINE | sed -e 's/@ *//'`"
>>${RPMLIST_NAME} ;;
[-]*)
;;
*) echo ${LINE} >>${RPMLIST_NAME}
;;
esac
done
sort -u -o ${RPMLIST_NAME} ${RPMLIST_NAME}
>${TMPLIST_NAME}
while read PACKAGE
do
if ! grep -q '^ *'"${PACKAGE}"' *$' missing.${TARGET}
then
echo ${PACKAGE} >> ${TMPLIST_NAME}
fi
done < ${RPMLIST_NAME}
mv ${TMPLIST_NAME} ${RPMLIST_NAME}
}
CopyRPMsFromDirectory()
{
DIRECTORY=${1:?"usage: $0 <directory>"}
>${TMPLIST_NAME}
while read PACKAGE
do
FILES=`ls ${DIRECTORY}/${PACKAGE}-*.rpm 2>/dev/null | grep
${PACKAGE}-[a-zA-Z0-9._]*-[a-zA-Z0-9._]*.rpm`
if [ -n "${FILES}" ]
then
for FILE in ${FILES}
do
echo ${FILE}
cp ${FILE} ${ISO_ROOT}/${RPM_PATH}
done
else
echo ${PACKAGE} >> ${TMPLIST_NAME}
fi
done <${RPMLIST_NAME}
mv ${TMPLIST_NAME} ${RPMLIST_NAME}
}
CopyRPMs()
{
if [ -e ${ISO_ROOT}/${RPM_PATH} ]
then
rm -rf ${ISO_ROOT}/${RPM_PATH}
fi mkdir ${ISO_ROOT}/${RPM_PATH}
CopyRPMsFromDirectory ${CUSTOM_RPMS}
CopyRPMsFromDirectory ${PACKAGES}
REMAINING_RPMS=`cat ${RPMLIST_NAME} | wc -l`
DISK=1
while [ ${REMAINING_RPMS} -gt 0 ]
do
echo "${REMAINING_RPMS} RPMs remaining."
eject
echo -n "Please insert ${TARGET} Disk ${DISK} and press ENTER: "
read line
sudo mount ${CD_ROOT}
CopyRPMsFromDirectory ${CD_ROOT}/${TARGET}/RPMS
sudo umount ${CD_ROOT}
eject
REMAINING_RPMS=`cat ${RPMLIST_NAME} | wc -l`
DISK=`expr ${DISK} + 1`
done
}
MakeIsoFile()
{
( cd ${ROOTS} ; find src -print | cpio -pdmvu ${ISO_ROOT} )
if [ "$TARGET" = RedHat ]
then # RHEL3 genhdlist doesn't have --productpath
/usr/lib/anaconda-runtime/genhdlist --withnumbers ${ISO_ROOT}
PYTHONPATH=/usr/lib/anaconda /usr/lib/anaconda-runtime/pkgorder
${ISO_ROOT}/ '' rhe3qu2 >/tmp/pkgorder.txt
/usr/lib/anaconda-runtime/genhdlist --withnumbers --fileorder
/tmp/pkgorder.txt ${ISO_ROOT}
else
/usr/lib/anaconda-runtime/genhdlist --productpath ${TARGET}
${ISO_ROOT}
fi
sudo mkisofs -o ${ISO_NAME} -V "${ISO_LABEL}" -b
isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot
-boot-info-table -J -r -nobak -T ${ISO_ROOT}
}
Cleanup
ReplicateNonRpms
UnpackBootIso
#UnpackInitRd
UpdateLinuxConfig
AddKickstartConfig
#AddBootMessage
#RepackInitRd
RepackBootIso
DetermineRpmList CopyRPMs
MakeIsoFile