Syslinux and netbooting refresh

For some time now we've used PXElinux from the fabulous Syslinux project to netboot servers when we automatically install them. When we restart a machine this now provides us with the following menu:

pxelinux menu

This was in the days before cobbler but it is simple and works well for us - we also have a little wrapper that wraps around it so that we can automatically install new servers, kick puppet, then change them back to a normal boot.

It was time to have a slight cleanup and along the way we've improved a few things with out setup and found out a few useful syslinux/PXElinux tips.

PXElinux configurations are stored in a directory (normally pxelinux.cfg):

  • localboot

LABEL localboot
localboot 0

  • install

LABEL install
KERNEL debian-installer/i386/linux
APPEND auto=true priority=critical initrd=debian-installer/i386/initrd.gz

  • rescue

LABEL rescue
KERNEL debian-installer/i386/linux
APPEND rescue/enable=true priority=critical initrd=debian-installer/i386/initrd.gz

This is a little limiting as if you want to use a different configuration you have to change files. We create a "common" file combining all these files together, the install file then becomes:

INCLUDE pxelinux.cfg/common
DEFAULT install
SAY This is the INSTALL image (32 bit)

As you build up more and more images the advantages really build up. Recently we actually swapped to using syslinux menus so each paragraph in "common" is now:

LABEL install
MENU LABEL Debian automatic install (32-bit)
MENU INDENT 2
LINUX debian-installer/i386/linux
INITRD debian-installer/i386/initrd.gz
APPEND auto=true priority=critical ....
TEXT HELP
Automatically install a 32-bit version of Debian.
This _will_ wipe this machine.
ENDTEXT

Note that new versions of syslinux allow you to use "INITRD" as a separate line (you don't need to put it in the APPEND line - this just makes the configuration slightly more readable. "LINUX" is just an alias for "KERNEL" - another aid to readability.

One other neat module in Syslinux now is "HDT" - Hardware Detection Tool - this displays information about the machine - and far faster than booting a full blown operating system. To allow it to work properly you first need to copy /usr/share/misc/pci.ids and /lib/modules/uname -r/modules.alias into the specified location. Then use a paragraph like this:

LABEL hdt
MENU LABEL ^HDT (Hardware Detection Tool)
MENU INDENT 2
KERNEL modules/hdt.c32
APPEND modules_alias=images/modules.pcimap pciids=images/pci.ids memtest=memtest
TEXT HELP
HDT provides an easy way to describe the hardware inside your machine.
ENDTEXT

There are a few other tricks to the menu system. You can use the "MENU SEPARATOR" which inserts a blank line, however we didn't find it aided navigation terribly well. Instead we indented all entries by 2 as you can see above. Instead of separations, we then used menu headings:

LABEL -
MENU LABEL Debian:
MENU DISABLE

Lastly we need to tell syslinux to use the menu (we also tweak a few things there):

UI modules/menu.c32
MENU TITLE Bitcube PXE boot
# Yellow, not grey text
MENU COLOR disabled 1;33;44 #60cccccc #00000000 std
# Three more rows in the menu please
MENU ROWS 15
MENU TABMSGROW 20
MENU CMDLINEROW 21
MENU TIMEOUTROW 21
MENU HELPMSGROW 22

Almost there now, let's set some timeout values - TOTALTIMEOUT will cause a localboot even if someone has interrupted the boot sequence.

# 10ths of a second, TOTAL timeout always happens
TIMEOUT 100
TOTALTIMEOUT 6000
ONTIMEOUT localboot

Lastly we use "IPAPPEND" so that we can do automatically set the network adapter in Debian (see our patch). Unfortunately a recent change breaks menu in the current version. Fortunately there is a workaround - just change the "UI menu.c32" line to "UI menu.c32 ~".