Instructions for Scripting a FreeBSD 9.x Install

The previous article, Booting FreeBSD 9 via PXE, might be helpful for implementing this script.

First set all the variables

#!/bin/sh

# Variables
DESTDIR=/mnt
OUTPUT_REDIR="/dev/stdout"

# Figure out the primary disk
PRIMARY_DISK=`/sbin/sysctl -n kern.disks`

# Network card
/bin/echo -n "Gathering Network info..  "
NETIF=`/sbin/ifconfig -l -u | /usr/bin/sed -e 's/lo0//' -e 's/ //g'`

/bin/echo -n "Insert the full system hostname: "
read HOSTNAME

This defaults to installing to the first disk and the first NIC with link.

Configure the disk

# Setup the disk
/bin/echo "Setup the GPT Label on $PRIMARY_DISK"
/sbin/gpart create -s GPT $PRIMARY_DISK

# Setup boot
/bin/echo -n "Setup the partitions.. "
/sbin/gpart add -b 34 -s 256 -t freebsd-boot -l boot $PRIMARY_DISK
/bin/echo -n "boot.. "

# Setup swap
/sbin/gpart add -s 6g -t freebsd-swap -l swap0 $PRIMARY_DISK
/bin/echo -n "swap0.. "

# Setup system
/sbin/gpart add -t freebsd-zfs -l system $PRIMARY_DISK
/bin/echo "system."

# Install the bootcode
/bin/echo "Install the boot code.."
/sbin/gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 $PRIMARY_DISK

Using GPT to label the disks and setup a boot, 6GB swap, and ZFS partition that will use all the free space.

Build the zpool

# Remove the zpool.cache
if [ -f /boot/zfs/zpool.cache ]; then
	/bin/rm /boot/zfs/zpool.cache
fi

# Setup the zpool
/bin/echo "Setup the system zpool.."
/sbin/zpool create -O mountpoint=/mnt system /dev/gpt/system
if [ $? -ne 0 ]; then
   /sbin/zpool import -f system
   /sbin/zpool destroy system
   /sbin/zpool create -O mountpoint=/mnt system /dev/gpt/system
fi

First, remove any old zpool.cache files that might be left over from a prior install

Create a zpool called system on /dev/gpt/system. Check and make sure it succeeded, if not try forcing and import and destroy the old one to try again.

Create the filesystems and set the filesystem options

# Set ZFS File System Options
/bin/echo "Setup the ZFS filesystems"
#/sbin/zfs create -o compress=lzjb system/tmp
/bin/mkdir -p /mnt/tmp
/bin/chmod 1777 /mnt/tmp
/sbin/zfs create system/usr
#/sbin/zfs create -o setuid=on system/usr/local
#/sbin/zfs create -o compress=gzip system/usr/src
#/sbin/zfs create -o compress=lzjb system/usr/obj
#/sbin/zfs create -o compress=gzip system/usr/ports
#/sbin/zfs create -o compress=off system/usr/ports/distfiles
/sbin/zfs create system/var
#/sbin/zfs create -o compress=gzip system/var/log
#/sbin/zfs create -o compress=lzjb system/var/audit
#/sbin/zfs create -o compress=lzjb system/var/tmp
/bin/mkdir -p /mnt/var/tmp
/bin/chmod 1777 /mnt/var/tmp
#/sbin/zfs create -o canmount=off system/usr/home
/sbin/zpool set bootfs=system system

Create the basic filesystem layout. As you can see, I left a bunch of the extra stuff off because I did not want to worry about configuring it now. For example, with the filesystem compression on for /var/log I should go disable the compression flags in /etc/newsyslog.conf.

Install the OS

# Install base
/bin/echo "Installing base"
/usr/bin/tar -xvf /usr/freebsd-dist/base.txz -C $DESTDIR

# Install kernel
/bin/echo "Installing kernel"
/usr/bin/tar -xvf /usr/freebsd-dist/kernel.txz -C $DESTDIR
/bin/echo "Move kernel"
/bin/mv $DESTDIR/boot/GENERIC/* $DESTDIR/boot/kernel/

# Install doc
/bin/echo "Install docs"
/usr/bin/tar -xvf /usr/freebsd-dist/doc.txz -C $DESTDIR

# Install games (gotta have fortune.. :) )
/bin/echo "Install games"
/usr/bin/tar -xvf /usr/freebsd-dist/games.txz -C $DESTDIR

Pretty straight forward, just extract the various parts into $DESTDIR (/mnt). You can leave off doc and/or games, but I like having the man pages and fortune.

Set the rc.conf and loader.conf settings

# Set loader.conf variables
/bin/echo "Setting the loader.conf variables.."
echo 'geom_label_load="YES"' >> $DESTDIR/boot/loader.conf
echo 'zfs_load="YES"' >> $DESTDIR/boot/loader.conf
echo 'vfs.root.mountfrom="zfs:system"' >> $DESTDIR/boot/loader.conf


# Set rc.conf variables
/bin/echo "Setting the rc.conf variables.."
# Set hostname
echo "hostname=\"$HOSTNAME\"" >> $DESTDIR/etc/rc.conf
# Set DHCP
echo "ifconfig_$NETIF=\"DHCP\"" >> $DESTDIR/etc/rc.conf
# Enable sshd
echo 'sshd_enable="YES"' >> $DESTDIR/etc/rc.conf
echo '' >> $DESTDIR/etc/rc.conf

# Disable sendmail
echo '# Postfix' >> $DESTDIR/etc/rc.conf
echo 'postfix_enable="YES"' >> $DESTDIR/etc/rc.conf
echo 'sendmail_enable="NO"' >> $DESTDIR/etc/rc.conf
echo 'sendmail_submit_enable="NO"' >> $DESTDIR/etc/rc.conf
echo 'sendmail_outbound_enable="NO"' >> $DESTDIR/etc/rc.conf
echo 'sendmail_msp_queue_enable="NO"' >> $DESTDIR/etc/rc.conf
echo '' >> $DESTDIR/etc/rc.conf

# Enable NTP
echo '# NTP' >> $DESTDIR/etc/rc.conf
echo 'ntpdate_enable="YES"' >> $DESTDIR/etc/rc.conf
echo 'ntpd_enable="YES"' >> $DESTDIR/etc/rc.conf
echo '' >> $DESTDIR/etc/rc.conf

echo 'zfs_enable="YES"' >> $DESTDIR/etc/rc.conf
# Disable background fsck
echo 'background_fsck="NO"' >> $DESTDIR/etc/rc.conf

Basic config, plus a little extra. I always use Postfix on my systems, so I disable sendmail right away.

Configure the swap partition

# Set swap
echo "/dev/gpt/swap0 none swap sw 0 0" >> $DESTDIR/etc/fstab

Set the timezone

# Set the timezone
/bin/echo "Setting the timezone to PST.."
/bin/cp /usr/share/zoneinfo/PST8PDT $DESTDIR/etc/localtime

This batch of systems uses Pacific time.

Update the system via FreeBSD Update

# Update the system using FreeBSD Update
/bin/echo "Running FreeBSD Update"
FREEBSD_UPDATE="/usr/sbin/freebsd-update"
# Fetch the updates
#$FREEBSD_UPDATE -b $DESTDIR fetch >${OUTPUT_REDIR}

# Install the Downloaded FreeBSD Updates
#$FREEBSD_UPDATE -b $DESTDIR install >${OUTPUT_REDIR}

I have disabled this for testing, but otherwise you can uncomment the two lines and it will update the system for you.

Copy over the zpool.cache

# Copy the cache file
if [ -f /boot/zfs/zpool.cache ]; then
   /bin/echo "copy zpool.cache.."
   /bin/mkdir -p $DESTDIR/boot/zfs
   /bin/cp /boot/zfs/zpool.cache $DESTDIR/boot/zfs/zpool.cache
fi
if [ -f /var/tmp/zpool.cache ]; then
   /bin/echo "copy /var/tmp/zpool.cache.."
   /bin/mkdir -p $DESTDIR/boot/zfs
   /bin/cp /var/tmp/zpool.cache $DESTDIR/boot/zfs/zpool.cache
fi

This detects if the cache file is present and copies it over to the real system, otherwise it will not boot.

Reset the mount points

/bin/echo "Resetting the mount points"
/sbin/zfs umount -a
/sbin/zfs set mountpoint=legacy system
/sbin/zfs set mountpoint=/tmp system/tmp
/sbin/zfs set mountpoint=/usr system/usr
/sbin/zfs set mountpoint=/var system/var

Umount the zfs partitions and set them to their normal values. By unmounting them first, we prevent them from being mounted on top of what we have mounted there already.

Reboot

# Reboot
/bin/echo "Rebooting now.."
/sbin/reboot

Everything is done so reboot the system. Note that commenting out the reboot call can be handy in troubleshooting so you can investigate what was done before it rebooted.

After the system comes up you will need to login and set the root password and create your users.

And here is a link to the raw script that you can use: build.sh

Powered by FreeBSD! r4l domain registration