Note: if this page interests you, you should also take a look at http://cambuca.ldhs.cetuc.puc-rio.br/RedHat7-CDs-HowTo.html which covers adding Reiserfs support to Red Hat 7.0
As a real-life example, we will walk through what is required to incorporate the Linux Terminal Server Project into Red Hat 7.2. We will update a couple of the standard Red Hat packages, include the LTSP packages, and finally alter the installer so that it will be as "newbie-proof" as possible.
------------- --------------- ----------- | | eth0 | | eth1 | | | Terminals |---------------| LTSP Server |-----------| Lan/Wan | | | 192.168.0.254 | | DHCP | | ------------- --------------- ----------- no firewall firewall all but DHCP/SSH
| ./disc1/RedHat/base/comps | contains the package groupings |
| ./disc1/RedHat/base/hdlists* | contains dependancies, package info, etc |
| ./disc1/RedHat/base/stage2.img | cramfs image containing the installer |
| /usr/lib/anaconda | installer code |
| /usr/lib/anaconda-runtime | utilities to generate installer images |
zlib-1.1.3-23.i386.rpm ==== ======== ==== | | architecture type | | | version number | package nameIf you are doing is updating a package to a new version, say updating to zlib-1.2.0-2.i386.rpm, all you should need to do is replace the old package with the new package and then run this shell script:
#!/bin/sh # current working directory BASE=`pwd` # generate hdlists* /usr/lib/anaconda-runtime/genhdlist --withnumbers $BASE/disc1 $BASE/disc2 # generate the package ordering PYTHONPATH=/usr/lib/anaconda /usr/lib/anaconda-runtime/pkgorder $BASE/disc1 i386 > filelist # now generate hdlists* with the correct ordering /usr/lib/anaconda-runtime/genhdlist --withnumbers --fileorder ./filelist $BASE/disc1 $BASE/disc2 # build disk 1 cd disc1 mkisofs -r -J -T -b dosutils/autoboot/cdboot.img -c .boot.cat -o ../1.iso . # build disk 2 cd ../disc2 mkisofs -r -J -T -o ../2.iso . cd .. # done!
The syntax of the comps file is pretty simple:
1 Group One {
package-one
package-two
}
0 Group Two {
package-three
package-four
}
0 --hide Hidden Group of Groups
@ Group One
@ Group Two
package-five
}
/usr/lib/anaconda/ contains all of the source code for the anaconda installer
/usr/lib/anaconda-runtime/ contains all of the tools required to build new installer images.
I generally hack the stage2.img directly... the tools to regenerate the entire installer are complex and slow. ./disc1/RedHat/base/stage2.img is a cramfs image. To hack on it directly rather than regenerating it:
cd ./disc1/RedHat/base/ mkdir mnt mkdir new mount -o loop,ro -t cramfs ./stage2.img ./mnt cp -av ./mnt/* ./new/ # <hack on ./new/* as described below> cd ./disc1/RedHat/base/ umount ./mnt rmdir ./mnt cd ./new mkcramfs . ../stage2.img rm -rfv newIn Red Hat 7.1, stage2.img was an ext2 formated so you could hack on the image directly. Earlier version were ISO9660 formated, IIRC.
The primary hacking occurs in ./disc1/RedHat/base/new/usr/lib/anaconda/installclasses
Each install class is defined here. The first thing we're going to do is copy workstation.py to ltsp.py - the Workstation install is close to what we want so we'll use that as our base.
Next we're going to hack on ltsp.py into shape. In the ltsp.py file listed below, the original workstation.py code is in blue and the lines modifiled/added for ltsp.py are in red. The comments describe what each change does:
from installclass import BaseInstallClass
from translate import N_
import os
import iutil
from partitioning import *
from fsset import *
class InstallClass(BaseInstallClass):
name = N_("LTSP") # <- name this install class "LTSP"
pixmap = "ltsp.png" # <- icon for the "LTSP" install option
sortPriority = 1 # <- this makes LTSP the first install option
arch = 'i386'
def setSteps(self, dispatch):
BaseInstallClass.setSteps(self, dispatch);
dispatch.skipStep("authentication")
def setGroupSelection(self, comps):
BaseInstallClass.__init__(self, comps)
# change the default package group options & automatically select
# "Workstation Common" and "LTSP" package groupings:
self.showGroups(comps, [ "KDE", ("GNOME", 1),
"Software Development",
"Web Server", "Open Office",
"SQL Database Server", "Dialup Support",
"Education" ] )
comps["Workstation Common"].select()
comps["LTSP"].select()
def setInstallData(self, id):
BaseInstallClass.setInstallData(self, id)
autorequests = [ ("/", None, 1100, None, 1, 1) ]
bootreq = getAutopartitionBoot()
if bootreq:
autorequests.append(bootreq)
(minswap, maxswap) = iutil.swapSuggestion()
autorequests.append((None, "swap", minswap, maxswap, 1, 1))
id.partitions.autoClearPartType = CLEARPART_TYPE_LINUX
id.partitions.autoClearPartDrives = None
id.partitions.autoPartitionRequests = autoCreatePartitionRequests(autorequests)
# Modify the firewall defaults: make "eth0" a trusted device and
# permit SSH:
id.firewall.trustdevs = ["eth0"]
id.firewall.ssh = 1
# if eth0 exists, set its defaults to 192.168.0.254/255.255.255.0
# and if eth1 exists, set its default to DHCP
dev = id.network.available()
if dev.has_key("eth0"):
dev["eth0"].set(('bootproto', 'none'))
dev["eth0"].set(('ipaddr', '192.168.0.254'))
dev["eth0"].set(('netmask', '255.255.255.0'))
dev["eth0"].set(('onboot', 'yes'))
if dev.has_key("eth1"):
dev["eth1"].set(('bootproto', 'dhcp'))
dev["eth1"].set(('onboot', 'yes'))
def __init__(self, expert):
BaseInstallClass.__init__(self, expert)
Now all we need to do is generate a new stage2.img and then generate the ISOs. That's it!