Install Linux onto a headless server without a cdrom drive

11 01 2010

Recently I got hold of three Sun Fire 2270 – until I opened the boxes I didn’t realise that they had no cd/dvd drives, VGA cards or iLOM’s installed.  I suppose it makes sense in these space-saving, energy-conscious, cost-sensitive times, although it did mean I had some work to do to get CentOS installed.  In the end it involved network booting and redirection to the serial console.  Unusually documentation was sparse, so here my attempt…

1. Publish the Installation OS on the Source Server

As I was installing CentOS 5.4 I retrieved the iso file from the web.   The next step is to loop mount the iso, using a command something like this:

#mount -o loop centos5.iso /mnt/iso (remember to create this directory before mounting)

I choose to publish this iso via my Apache webserver so I created a symbolic link called ‘centos’ in the www root folder (you can also publish via FTP or NFS):

#cd /var/www/html
#ln -s /mnt/iso centos

This should now mean that the iso image is available via your web server (browse to http://<webserver>/centos and make sure or else the next step will fail).

If your using kickstart (and I suggest you do for convenience) copy your kickstart file to the webserver and check the url to it (eg; http://<webserver>/kickstart/ks.cfg)

2. Setup the Network Boot Environment

Now we’ve our source OS and kickstart file published, we need to tell our server to boot from the network and retrieve the installation information.  To do this I configured the netboot and dhcpd services on the same box as my webserver.  For DHCP I set up a static entry in my /etc/dhcpd.conf file (my network is – adjust as necessary):

default-lease-time                      30000;
max-lease-time                          30000;
option subnet-mask            ;
option domain-name-servers    ;
option domain-name                      "mydomain.local";
ddns-update-style                       none;</pre>
<pre>subnet netmask {
option subnet-mask;
option routers;
<pre>host x2270 {
hardware ethernet 00:aa:bb:cc:dd:ee;
filename "pxelinux.0";

This entry specifies the hardware address shown (taken from the sticker on the back of the x2270), it provisions a fixed address for it (, it sets a ‘next-server’ option ( – this is my netboot/web/dhcp server) as well as a ‘filename’ option (pxelinux.0 is the pxe bootstrap file we create on TFTP server next).

Next we need to set up our PXE boot server, this is the guy that allows the machine to be installed to boot from the network.  My preference is to use system-config-netboot tool, it’s very straight-forward to use and does pretty much everything we need.

Open system-config-netboot and choose Configure->Network Installation, then click Add to create a new installation source by setting the following fields:

Operating System Identifier – this is a unique name, in my case I just used CentOS32

Select Protocol for Installation – in this instance we’re using HTTP

Server IP Address – this is the IP of the HTTP server, in my instance

Location – this is the relative path to the installation directory ‘/centos’

After configured these setting click OK and close the ‘Configure Network Installations’ window.   At this stage we have the network installation configured we just need to get our server to use it.  To do this click ‘New’  and enter the following fields:

Hostname or IP Address – this is the ip or hostname of the machine to be installed (in my instance

Operating System – if all went well with the network installation setup this should drop down to CentOS32

Make sure everything else on this windows is unchecked or not selected.  We’ll do our serial settings and kickstart settings by hand (it appears there’s a bug that has the kickstart page looping because it inserts an additional ‘/’ character).  You can now click OK and close the application.

Our final step is to adjust the network boot environment to use our kickstart file and use the serial console (as we’ve no VGA card).  To that end we edit the file /tftpboot/linux-install/pxelinux.cfg/<hex-code>.  The hex-code filename comes from pxelinux and can be found using the command:


In my environment that’s the IP of the address of the machine to be installed.  This file lists the pxelinux boot environment for that host – we need to append ks=http://<webserver>/kickstart/ks.cfg for our machine to be installed using our kickstart and also console=ttyS0 so our machine will redirect output to the serial console.  So my /tftpboot/linux-install/0A000569 file looks like (disregard the line break after the kickstart setting):

default CentOS32
label CentOS32
kernel CentOS32/vmlinuz
append initrd=CentOS32/initrd.img  ramdisk_size=8419 console=ttyS0 method=
ip=dhcp ks=

3. Boot and Install Server

The Sun servers came with a RJ45 to Serial adapter, I connected this to a network cable and into the back of the new Sun x2270.  I stuck the other end in a USB serial adapter and then into another CentOS box.  This allowed me to use minicom to connect to the serial port (port settings are device=/dev/ttyUSB0 with 9600,8N1 and no flow control).  Next I hit the power switch and booted the new server – my servers were initially set to boot from the hard disk so I had to enter the BIOS (using Ctrl+E) and then set the boot device priority so that the network card was before the hard disk).  After setting this I rebooted and watched the installation progress nicely using the netboot server, HTTP source and kickstart file.  By the way I originally didn’t set console=ttyS0, so when anaconda kicks in it disappears from screen – this was key to these particular Sun boxes.

After the network installation has completed don’t forget to edit the boot device priority again or else the machine will netboot again.  Also once you’re done with network booting remove the next-server and filename options from DHCP – I’d also recommend switching off the netboot server so nothing else tries to boot from it (or abuse it).


View conf file without comments

6 01 2010

Short and sweet entry to start 2010.  Some linux configuration files are pretty long and really include very few directives, a prime example is squid.conf (mine is currently an almighty 4898 lines!).  Most of these lines are comments and if we were so inclined we could probably copy the file without comments and sort the wheat from the chaff (of the 4898 lines, my squid.conf actually only uses 68 lines!)  I use the following to display or pipe the file without any comments:

grep ^[^#] /usr/local/squid/etc/squid.conf


grep ^[^#] /usr/local/squid/etc/squid.conf > tmp

This shows only the directives.

Alternatively we could redo the grep only this time show 2 of lines of comments before the directive using:

grep -B 2 ^[^#] /usr/local/squid/etc/squid.conf

Using USB Storage in Kickstart

21 12 2009

Recently I’ve been going through several kickstart build scripts – mainly to setup the correct packages and settings.  I thought it would be convenient if I was able to use the same kickstart DVD for all machines but read in the appropriate settings from a USB stick.  To do this, I put the following in my kickstart postscript…

# Check for USB storage and profile definition
if [ -d /proc/scsi/usb-storage ]; then
DEVICENUM=$(ls /proc/scsi/usb-storage/)
DEVICELETTER=$(<<<$DEVICENUM tr ‘[1-9]’ ‘[a-i]’)
echoOut “USB storage found at sd”$DEVICELETTER
mkdir -p /mnt/usb
mount /dev/sd${DEVICELETTER}1 /mnt/usb
if [ -f /mnt/usb/network-settings-*.bash ]; then
source /mnt/usb/network-settings-*.bash
cp /mnt/usb/network-settings-*.bash /root/
echoOut “Loaded profile found on USB storage”
echoOut “Unable to find profile settings on USB storage”
echoOut “No USB storage present…”

The echoOut function is just an echo function I wrote to do an ordinary echo, log to a file and tee it to tty3 (for use the kickstart installation).  I could go further with this script and perhaps use a menu in the case of several available files, but a single file on the USB is fine for me.

Custom Installation CentOS/RHEL DVD

30 11 2009

I recently had to create a custom CentOS 5.4 DVD that included a set list of installed packages, some files copied from the DVD and a comprehensive kickstart script.  After trawling the web for a couple of days I did manage to successfully get my image operational – there are quite a few quirks and the required information is on the web but it’s not exactly in one place… So here’s my effort:

– Copy the CentOS DVD to a local image folder (you can use the actual physical CentOS DVD or just the ISO file).  At this stage we have to ensure that all files from the disk are copied including .discinfo and .treeinfo.  If we don’t we’ll get the ‘CentOS cd was not found error…:

#mkdir -p /mnt/centos (we’ll only use this mount the iso/dvd)

#mount -o loop /home/mark/CentOS-5.4-i386-bin-DVD.iso /mnt/centos (if using the iso file)

#mount /dev/cdrom /mnt/centos (if using the physical DVD)

#cp -av /mnt/centos /home/mark/  (the options -av ensure all files and links are copied)

#mv /home/mark/centos /home/mark/customdvd

– Remove the repodata information from our customdvd image folder, we’re going to regenerate this data later.  (NB: It’s important not to remove repodata/comp.xml as this is a full package list we can edit):

#cd /home/mark/customdvd/

#rm ./repodata/*.gz ./repomd.xml

– Modify or add packages to our customdvd image folder.  In this example I’ll add the lshw rpm package to keep it straightforward.  I downloaded this package from  The DVD has a CentOS folder which contains all the rpm packages, we’ll keep ours in there too. (NB: you’ll need to add any dependencies into this folder too, if they’re not already there):

#cp /home/mark/lshw-2.14-1.el5.rf.i386.rpm /home/mark/customdvd/CentOS/

– At this stage we need to add our lshw package to the comps.xml file.  The comps.xml file is a xml database file that lists all the packages in the familiar installation groups along with whether or not they’re installed as part of that group by default or not.  The repodata we create later reads the comps.xml file and outputs the required file information for our installation.  With only one package it’s probably easiest to just add the package name to the ‘core’ package group, but just in case you’ve a bunch more packages to install I’m going to create a new group called ‘custom’ and add lshw to the new group.  For comps.xml it’s important you add the rpm package name, this is not necessarily the same name as the file/package, so query the file first to find the name with the command:

#rpm -q –qf ‘%{NAME}\n’ -p /home/mark/lshw-2.14-1.el5.rf.i386.rpm

In our case the package name actually is ‘lshw’ so we edit the file comps.xml and enter something like the following (hopefully this is self-explanatory):

<name xml:lang=”uk”>custom</name>
<description>Custom Tools</description>
<description xml:lang=”uk”>Custom Tools</description>
<packagereq type=”mandatory”>lshw</packagereq>

– Now we need to recreate the repodata for our installation.  The repodata is the link between comps.xml and the rpm packages in the DVD’s CentOS folder.  Using the createrepo utility we can iterate through all the rpm’s and create the appropriate files to help with our installation (we deleted they earlier).  The files that createrepo generates need to be relative to the DVD’s path so we have to declare the path before doing the regeneration:

#cd /home/mark/customdvd/

#declare -x discinfo=`head -1 .discinfo`

#createrepo -u “media://$discinfo” -g repodata/comps.xml .

Hopefully at this stage you’ll see the rpms being iterated over and you’ll end up with additional files in customdvd/repodata.  If you don’t have the createrepo utility installed use ‘yum install createrepo’ to get it.

At this stage our custom installation DVD could be made into an iso and burnt, however if you want to add more files to the DVD (not rpm packages) copy them into the customdvd image folder. Before we do that however we may want to add a kickstart file to the DVD.

– (Optional) Copy the file kickstart file to the DVD:

#cp /home/mark/ks.cfg /home/mark/customdvd/

At this point we could create the DVD iso and just boot and type ‘linux ks=cdrom:/ks.cfg’ to run through our kickstart installation, however to have it automatically run our kickstart installation, edit the file isolinux/isolinux.cfg file so that our kickstart runs automatically, for example:

label linux
kernel vmlinuz
append initrd=initrd.img ks=cdrom:/ks.cfg

To use files from the DVD during kickstart installation, for example predefined config files, you’ll need to copy the files using a %post –nochroot script.  Don’t panic though, after copying the files you can simply using a standard %post for example:

%post –nochroot
mkdir /mnt/sysimage/tempdir
mkdir -p /mnt/cdrom
mount -t iso9660 /tmp/cdrom /mnt/cdrom
cp /mnt/cdrom/CentOS/filex /mnt/sysimage/tempdir/

After this you can use filex from within your %post, for example:

cp /tempdir/filex /opt

Ok – so now we have our customdvd image the way we need it, we can create our iso using mkisofs (you probably won’t need all the options so just strip out the ones you don’t need):

mkisofs  -o /home/mark/customcentos.iso -r -J -N -d -hide-rr-moved \
-sysid `hostname`  -V ‘Custom CENTOS’  \
-no-emul-boot -boot-info-table -boot-load-size 4 \
-b isolinux/isolinux.bin -c isolinux/ \

After this we should have a shiny new custom CentOS/RHEL DVD.  Ordinarily I check the output ISO file using a virtual machine.  Best of luck.