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
~~~ {.bash}
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.