probably.co.uk logo

Using iPXE with a URL to kickstart Linux

433 words, 3 minutes.

Although kickstarting Linux is pretty simple, it can be frustrating if you’re trying to build different versions. Take, for example, building RHEL (CentOS/SciLin) version 5 and version 6 hosts. The initrd and vmlinuz files are version specific, and not backwards compatible. I’ve seen a DHCP/PXE configuration, in a large bank, have a sprawling and complex set of menus just to counter for different OS releases! This is quite unnecessary.

UPDATE in 2024: Hello! This blog post is over 10 years old now, yet here we are in 2024 and I’m seeing a large uptick in traffic coming here to read this. So before you read on, could I ask a small favour please? I’m really intrigued as to why traffic has increased, so would you mind dropping me a quick email via the link below, or pinging me on Mastodon or LinkedIn, letting me know what you were looking for, and maybe a little about the problem you’re trying to solve? The reason why I find this so intriguing is, the traffic spike tells me there’s some sort of shift in infrastructure going on; maybe people are bringing workloads back from the cloud more frequently? Anyway, I’d love to hear from you as to how you ended up here at this post. Thanks for taking time to read this bit, please do continue to read what you came here for 😊

Sometime ago I looked at iPXE. There is a nice capability with it to add a script, or link, to the initial boot process. Using this I rolled a single ISO (you could put it in a DHCP/PXE/TFTP setup - I did it this way because I wanted a simple, transportable, solution to use on my desktop and laptop) with a link to a CGI I’d written. Using the CGI I do a lookup, based on MAC address, for the host’s intended Linux version and a tailored kickstart file.

One ISO can therefore boot multiple Linux versions and even host-specific kickstart files (which are always kept to the most bare bones they can be - handing off to a configuration management tool like Ansible or Puppet in the %post section to let it handle what it does best).

Here’s an example file that is rolled into the ipxe.iso build with make EMBED=menu.ipxe bin/ipxe.iso

host:src$ cat menu.ipxe
 #!ipxe
 dhcp net0
 chain http://192.168.1.1:3000/pxe/${net0/mac}

And an example of the output from the CGI:

MacBook-Pro:~$ curl -s http://192.168.1.1:3000/pxe/08:00:27:59:86:69
#!ipxe
kernel -n img http://build/centos/6.4/os/x86_64pxeboot/vmlinuz ks=http://192.168.1.1:3000/ks kssendmac
initrd http://build/centos/6.4/os/x86_64pxeboot/initrd.img
boot img

The pretty rough CGI I use is written in Perl Mojolicious, and can be found on Github.

✍️ Respond by email