OmniOS PXE Server for SmartOS

It is useful to have a variety of options for host operating systems to run fundamental network services like DHCP and PXE booting. OmniOS is well-suited to that task and is very similar to SmartOS which makes it easy to transition between them.

Differences from SmartOS that may trip you up.

  1. zcat is called gzcat
  2. tar x doesn't work in a pipeline. You need to tar -xpf -

Pre-Requisites

I expect that you have an OmniOS host or VM with a static IP available. I did this myself with Vagrant.  Static IPs in Vagrant are clumsy at best so YMMV.

Procedure

Bootstrap PKGSRC:

curl -s http://pkgsrc.joyent.com/packages/SmartOS/bootstrap/bootstrap-2013Q2-i386.tar.gz |
  gzcat | (cd /; sudo tar -xpf -)

Install the necessary packages:

pkgin -y update
pkgin -y upgrade
pkgin -y install isc-dhcpd tftp-hpa

Configure the TFTP service:

svcadm enable inetd
echo "tftp dgram udp wait root /opt/local/sbin/in.tftpd in.tftpd -v -s /tftpboot" > /tmp/tftp.inetd
inetconv -i /tmp/tftp.inetd -o /tmp

Configure the DHCP service:

cat > /opt/local/etc/dhcp/dhcpd.conf <<'EOF'
authoritative;
ddns-update-style none;
option domain-name "example.local";
option domain-name-servers 208.67.222.222, 208.67.220.220;
default-lease-time 600;
max-lease-time 7200;
log-facility local7;

subnet 192.168.2.0 netmask 255.255.255.0 {
  range 192.168.2.10 192.168.2.60;
  option routers 192.168.2.1;
}

group {
  next-server 192.168.2.20;
  if exists user-class and option user-class = "iPXE" {
    filename = "smartos.ipxe";
  } else {
    filename = "undionly.kpxe";
  }  
  host smartos-a {
    hardware ethernet 01:23:45:67:89:ab;
    fixed-address 192.168.2.60;
  }

  host smartos-b {
    hardware ethernet ba:98:76:54:32:10;
    fixed-address 192.168.2.59;
  }
}
EOF
mkdir -p /var/db/isc-dhcp/
touch /var/db/isc-dhcp/dhcpd.leases
mkdir -p /var/run/isc-dhcp/

Set up the PXE boot assets:

mkdir /tftpboot
curl http://cuddletech.com/IPXE-100612_undionly.kpxe > /tftpboot/undionly.kpxe
cat > /tftpboot/smartos.ipxe.tpl <<'EOF'
#!ipxe
# /tftpboot/smartos.ipxe.tpl
kernel /smartos/$release/platform/i86pc/kernel/amd64/unix -B smartos=true
initrd /smartos/$release/platform/i86pc/amd64/boot_archive
boot
EOF
mkdir /tftpboot/smartos

Get the latest SmartOS Platform and set it up as the default boot:

curl 'https://us-east.manta.joyent.com/Joyent_Dev/public/SmartOS/platform-latest.tgz' > /tftpboot/platform-latest.tgz
cd /tftpboot/smartos
gzcat /tftpboot/platform-latest.tgz | tar -xpf -
directory=$(ls /tftpboot/smartos | grep platform- | sort | tail -n1)
release=${directory:9}
mv /tftpboot/smartos/{$directory,$release}
mkdir /tftpboot/smartos/$release/platform
mv /tftpboot/smartos/$release/{i86pc,platform}
cat /tftpboot/smartos.ipxe.tpl | sed -e"s/\$release/$release/g" > /tftpboot/smartos.ipxe

And now you have an OmniOS PXE server for SmartOS.