FreeBSD PXE boot Part 2
Some posts ago I wrote that I was busy to find out how a FreeBSD machine can be PXE-ed from a Linux server. Well, I found that some time ago, but I didn't have the time to type it here, yet. Well, as always, once you know how it's done, it's quite simple. But because a lot of the FreeBSD documentation is very old (talking about FreeBSD 4, 5 and 6) it takes some time to find it all.
Oke, here we go!
Prereqs
First of all you need a working NFS, DHCP, Web and TFTP server on your Linux
machine. How to do that is beyond this document and also fairly easy. In my
case the Puppet/Repository/NFS/Name/DHCP/TFTP/Web server is the system with IP
192.168.0.1 and in the nameserver the host frinst
(short for FreeBSD
installation test machine) is defined with IP 192.168.0.2
.
This machine also has a 1TB disk mounted as /repo
, the place where all
software and repositories are placed.
And you need to have root access to a FreeBSD machine to play around with memory file systems.
Software
To start things of we need the FreeBSD software. I downloaded it from the Dutch Unix Users Group (NLUUG). We need two things, the complete install CD and a simple boot CD. Maybe it can be done with one, I haven't tested that, so this is what I did.
First get the FreeBSD bootonly iso and copy the contents to the PXE directory
wget http://ftp.nluug.nl/FreeBSD/ISO-IMAGES-i386/8.2/FreeBSD-8.2-RELEASE-i386-bootonly.iso
mount -o loop FreeBSD-8.2-RELEASE-i386-bootonly.iso /mnt
mkdir -p /tftpboot/images/freebsd/i386/8.2
cd /tftpboot/images/freebsd/i386/8.2
cp -R /mnt/* .
umount /mnt
Now get the complete FreeBSD installation disk and copy that to the repository
wget http://ftp.nluug.nl/FreeBSD/ISO-IMAGES-i386/8.2/FreeBSD-8.2-RELEASE-i386-disc1.iso
mount -o loop FreeBSD-8.2-RELEASE-i386-disc1.iso /mnt
mkdir -p /repo/freebsd/FreeBSD-8.2-i386
cd /repo/freebsd/FreeBSD-8.2-i386
cp -R /mnt/* .
umount /mnt
and get all updates for this FreeBSD version
mkdir -p /repo/freebsd/pub/FreeBSD/ports/i386/packages-8.2-release
cd /repo/freebsd/pub/FreeBSD/ports/i386/packages-8.2-release
rsync -va --delete ftp.nluug.nl::FreeBSD/ports/i386/packages-8.2-release/All .
rsync -va --delete ftp.nluug.nl::FreeBSD/ports/i386/packages-8.2-release/Latest .
PXE/TFTP
Now the PXE/TFTP server needs to know how to handle a boot request coming from the FreeBSD machine. This needs a chain loader to make things work. This is how I did it:
DEFAULT vesamenu.c32 PROMPT 0 TIMEOUT 300 MENU TITLE FreeBSD 8.2 Installation LABEL FreeBSD 8.2 i386 - Normal MENU LABEL FreeBSD 8.2 i386 - Normal PXE images/freebsd/i386/8.2/boot/pxeboot TEXT HELP Install FreeBSD 8.2 for i386 (32 bits) with normal filesystems ENDTEXT MENU SEPARATOR
DHCP
In your DHCP server there should be an entry for the new machine and it should look something like this
group { # Test host frinst { hardware ethernet xx:xx:xx:xx:xx:xx; fixed-address frinst; option host-name "frinst"; next-server 192.168.0.1; filename "pxelinux.0"; option root-path "192.168.0.1:/tftpboot/images/freebsd/i386/8.2"; } }
Take a long and good look at the root-path option. This should point to the FreeBSD image directory on the TFTP server.
NFS
The NFS server needs to export the repository and the TFTP directories for FreeBSD installation. The export file needs to have:
/tftpboot/images/freebsd 192.168.0.0/24(fsid=10,ro,no_root_squash,no_subtree_check) /repo/freebsd 192.168.0.0/24(fsid=11,ro,no_root_squash,no_subtree_check)
Notice that the fsid
is not 0 and that they are all different.
Sysinstall
Finally we have all the prelim stuff sorted out. But we we try to install the FreeBSD machine, you get the standard sysinstall screens and no automation. And that was just what we wanted.
To make that work we need some extra's.
First we need to switch off the default menu actions of sysinstall
Edit the file /tftp/images/freebsd/i386/8.2/boot/loader.conf
to look like
mfsroot_load="YES" mfsroot_type="mfs_root" mfsroot_name="/boot/mfsroot" autoboot_delay=0 vfs.root.mountfrom="ufs:/dev/md0"
and the file /tftp/images/freebsd/i386/8.2/boot/loader.rc
include /boot/loader.4th start check-password
and create a script that gets executed at the end of the installation process.
This script must be in the directory /repo/freebsd/FreeBSD-8.2-i386
and is executed as /dist/inst_post
at the end of the installation.
#!/bin/sh #------------------------------------------------------------------------------# # Set the package root for the post installation # #------------------------------------------------------------------------------# PACKAGEROOT='http://muppet.tonkersten.com/freebsd' export PACKAGEROOT #------------------------------------------------------------------------------# # Install and enable Puppet # #------------------------------------------------------------------------------# pkg_add -r puppet echo 'puppet_enable="YES"' >> /etc/rc.conf #------------------------------------------------------------------------------# # Set the PACKAGEROOT to the muppet server # #------------------------------------------------------------------------------# echo '# Set the PACKAGEROOT to the muppet server' >> /etc/csh.cshrc echo 'setenv PACKAGEROOT "http://muppet.tonkersten.com/freebsd"' >> /etc/csh.cshrc # echo '# Set the PACKAGEROOT to the muppet server' >> /etc/profile echo 'PACKAGEROOT="http://muppet.tonkersten.com/freebsd"' >> /etc/profile echo 'export PACKAGEROOT' >> /etc/profile #------------------------------------------------------------------------------# # Set the default root password # #------------------------------------------------------------------------------# echo '$1$nUXX0vpK$RPLtXUmvxcdB4UaqMhzYd.' | pw user mod root -H 0 #------------------------------------------------------------------------------# # That's all, folks!! # #------------------------------------------------------------------------------# exit
OK, almost there
Now all things are in place to tell FreeBSD to use them. But that is not as
easy as it sounds. We need to modify the memory file system, so that it
contains the file install.cfg
, used by sysinstall
to perform a unattended
installation.
First create a file called install.cfg
containing
#------------------------------------------------------------------------------# # Turn on extra debugging. # #------------------------------------------------------------------------------# debug=YES #------------------------------------------------------------------------------# # Ok, this ought to turn off ALL prompting, don't complain to me that you # # lost a machine because you netbooted it on the same subnet as this # # box # #------------------------------------------------------------------------------# nonInteractive=YES noWarn=YES tryDHCP=YES #------------------------------------------------------------------------------# # My host specific data (Should be changed later) # #------------------------------------------------------------------------------# hostname=frinst domainname=tonkersten.com #------------------------------------------------------------------------------# # Which installation device to use # # le0 -< VMware machines # #------------------------------------------------------------------------------# nfs=192.168.0.1:/repo/freebsd/FreeBSD-8.2-i386 netDev=le0 tryDHCP=YES mediaSetNFS #------------------------------------------------------------------------------# # Select which distributions we want. # # Like this: # # dists=base bin doc manpages dict info des compat1x compat3x crypto # # distSetCustom # # # # Or like this: # # distSetMinimum, distSetUser, distSetXUser, distSetKernDeveloper # # distSetDeveloper, distSetXDeveloper and distSetEverything # # # # Watch out: When just installing 'base' you also need GENERIC, otherwise you # # don't have a kernel # #------------------------------------------------------------------------------# distSetMinimum #------------------------------------------------------------------------------# # Now set the parameters for the partition editor on da0. # #------------------------------------------------------------------------------# disk=da0 partition=all bootManager=standard diskPartitionEditor #diskPartitionWrite #------------------------------------------------------------------------------# # All sizes are expressed in 512 byte blocks! # # # # A 500MB root partition, followed by a 2G swap partition, followed by # # a 1G /var, a 1G /tmp, a 1G /sidn with softupdates and a /usr using all the # # remaining space on the disk /usr has softupdates enables (non zero option # # after the mountpoint) # #------------------------------------------------------------------------------# da0s1-1=ufs 1024000 / da0s1-2=swap 4096000 none da0s1-3=ufs 2048000 /var da0s1-4=ufs 2048000 /tmp da0s1-5=ufs 2048000 /sidn 1 da0s1-6=ufs 0 /usr 1 # # Let's do it! diskLabelEditor #------------------------------------------------------------------------------# # OK, everything is set. Start the install # #------------------------------------------------------------------------------# installCommit #------------------------------------------------------------------------------# # Run post commands # #------------------------------------------------------------------------------# command="/dist/inst_post" system #------------------------------------------------------------------------------# # That's all, folks!! # #------------------------------------------------------------------------------# shutdown
This file now needs to be inserted into the memory file system. On a FreeBSD box do
cd /tmp
cp -p ~/mfsroot.gz .
gunzip mfsroot.gz
mdconfig -f mfsroot -u 0
mount /dev/md0 /mnt
cp -p ~/install.cfg /mnt
umount /mnt
mdconfig -d -u 0
gzip mfsroot
cp -p mfsroot.gz ~
and that should be it.
Now boot the new machine with PXE and select the FreeBSD installation option and the machine will be auto installed and from now on it will be manged with the Puppet configuration system. Just as easy as that.