I hacked up some­thing like this a cou­ple of years back. The result was a sys­tem where I could install any FreeB­SD ver­sion on any netboot-capable machine in a cou­ple of minutes.

dhcpd first: it seems a bit like a hack to build extra fields onto the DHCP mes­sage, but DHCP is real­ly the only sen­si­ble way to dis­trib­ute “boot from here” infor­ma­tion. Typ­ing the cor­rect incan­ta­tions in the dhcpd con­fig file is a sep­a­rate tuto­r­i­al worthy.

Since the pos­si­bil­i­ties of the FreeB­SD non-interactive installscript real­ly sucked and were entire­ly inad­e­quate for my needs, I end­ed up cre­at­ing a full dis­tri­b­u­tion (make dis­tri­b­u­tion) before­hand, open­ing as a chroot and installing any ports, and mak­ing all rel­e­vant changes to con­fig­u­ra­tion files, and then archiv­ing the dis­tri­b­u­tion files on my file serv­er. The archive would then con­tain a tar­ball for every FreeB­SD ver­sion + con­fig­u­ra­tion com­bi­na­tion I needed.

I then point­ed the pxe­loader at a stripped-down ramdisk FreeB­SD instal­la­tion with the sole task of run­ning a cus­tom rc.local script which would for­mat the hard­disk, fetch the dis­tri­b­u­tion tar­ball from the file serv­er via NFS and write the tar­ball to the disk. For my light­weight dis­tri­b­u­tion this took ca. 2 min­utes, MUCH faster than run­ning through a tra­di­tion­al non-interactive install process. The rc.local script con­tained the log­ic to select the the cor­rect dis­tri­b­u­tion (ver­sion + con­fig) on the file serv­er, although I had to change the script when I want­ed anoth­er ver­sion (unless I always want­ed HEAD). The con­fig was cho­sen auto­mat­i­cal­ly based on the MAC address of the machine.

I end­ed up set­ting up a TFTP serv­er only for the ramdisk instal­la­tion. It would be real­ly nice if the pxe­loader sup­port­ed fetch­ing via HTTP too, in addi­tion to NFS and TFTP.

As these were throw-away instal­la­tions intend­ed to run tests, I need­ed to also be able to nuke the instal­la­tion and install a new ver­sion auto­mat­i­cal­ly. I did this by set­ting the hard­disk as pri­ma­ry boot option in the BIOS and net­boot as sec­ond option. When I need­ed to rein­stall the machine, I just nuked the MBR and let the machine reboot.

If you find the time for your project, con­sid­er hack­ing up an easy way of cre­at­ing cus­tom, fully-functional dis­tri­b­u­tions fast on a build machine. Some­thing like NanoB­SD. The instal­la­tion process would then only involve cre­at­ing a ramdisk-based FreeB­SD dis­tri­b­u­tion and writ­ing a sim­ple rc.local instal­la­tion script that pre­pares the sys­tem disk, selects a dis­tri­b­u­tion based on some log­ic and pipes the files to the disk.