Background
So far I have used ezjail to manage FreeBSD jails. I use jails since years to have different parts of a software stack in some kind of a container (in a ZFS dataset for the filesystem side of the container). On one hand to not let dependencies of one part of the software stack have influence of other parts of the software stack. On the other hand to have the possibility to move parts of the software stack to a different system if necessary. Normally I run -stable or –current or more generally speaking, a self-compiled FreeBSD on those systems. In ezjail I like the fact that all jails on a system have one common basejail underlying, so that I update one place for the userland and all jails get the updated code.
Since a while I heard good things about iocage and how it integrates ZFS, so I decided to give it a try myself. As iocage does not come with an official way of creating a basejail (respectively a release) from a self-compiled FreeBSD (at least documented in those places I looked, and yes, I am aware that I can create a FreeBSD release myself and use it, but I do not like to have to create a release additionally to the buildworld I use to update the host system) here now the short HOWTO achieve this.
Invariants
In the following I assume the iocage ZFS parts are already created in dataset ${POOLNAME}/iocage which is mounted on ${IOCAGE_BASE}/iocage. Additionally the buildworld in /usr/src (or wherever you have the FreeBSD source) should be finished.
Pre-requisites
To have the necessary dataset-infrastructure created for own basejails/releases, at least one official release needs to be fetched before. So run the command below (if there is no ${IOCAGE_BASE}/iocage/releases directory) and follow the on-screen instructions.
iocage fetch
HOWTO
Some variables:
POOLNAME=mpool SRC_REV=r$(cd /usr/src; svnliteversion) IOCAGE_BASE=””
Creating the iocage basejail-datasets for this ${SRC_REV}:
zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/bin zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/boot zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/lib zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/libexec zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/rescue zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/sbin zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/bin zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/include zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/lib zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/lib32 zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/libdata zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/libexec zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/sbin zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/share zfs create –o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/src
Install from /usr/src (the executable “chown” is hardlinked across an iocage basejail dataset boundary, this fails in the normal installworld, so we have to ignore this error and install a copy of the chown binary to the place where the hardlink normally is):
cd /usr/src make –i installworld DESTDIR=${IOCAGE_BASE}/iocage/base/${SRC_REV}-RELEASE/root >&! iocage_installworld_base.log cp –pv ${IOCAGE_BASE}/iocage/base/${SRC_REV}-RELEASE/root/usr/sbin/chown ${IOCAGE_BASE}/iocage/base/${SRC_REV}-RELEASE/root/usr/bin/chgrp make distribution DESTDIR=${IOCAGE_BASE}/iocage/base/${SRC_REV}-RELEASE/root »& iocage_installworld_base.log
While we are here, also create a release and not only a basejail:
zfs create –o compression=lz4 ${POOLNAME}/iocage/releases/${SRC_REV}-RELEASE zfs create –o compression=lz4 ${POOLNAME}/iocage/releases/${SRC_REV}-RELEASE/root make installworld DESTDIR=${IOCAGE_BASE}/iocage/releases/${SRC_REV}-RELEASE/root >&! iocage_installworld_release.log make distribution DESTDIR=${IOCAGE_BASE}/iocage/releases/${SRC_REV}-RELEASE/root »& iocage_installworld_release.log
And finally make this the default release which iocage uses when creating new jails (this is optional):
iocage set release=${SRC_REV}-RELEASE default
Now the self-build FreeBSD is available in iocage for new jails.