jeroen.se
by jnieuwen
Using a FreeBSD jail as a ports build cluster
One of the problems you will someday run into when upgrading the ports on one of your FreeBSD machines is that the portupgrade will break. Off course you always use the -b option of portupgrade to be sure you can rollback. But this still causes trouble/unplanned downtime. The solution is of course using a machine specific for building your ports and after that installing the packages on the real machine. But unfortunately not everyone has a spare machine for this. So in this article we explore how you can use a jail for this purpose.
Using a build jail
First off all you have to create a jail. This is covered in a lot of other articles so I will not cover this process here. If you want to use this process on a laptop which gets its IP by using DHCP, you can use the extra options described here to create a working jail on it. Further you have to make sure that you have the portupgrade port installed on your host.
Preparation
First of all we look at our jail configuration:
jls
JID IP Address Hostname Path
8 192.168.0.141 build.jeroen.se /usr/home/jails/192.168.0.141
Here we see that the JID of my build jail is number 8. Of course you have to substitute your own values in the commands below. We can now mount the ports directory into the jail. If you do not already have a /usr/ports directory in your jail create it first with:
mkdir -p /usr/home/jails/192.168.0.141/usr/ports
And mount the /usr/ports directory in the jail:
mount_nullfs /usr/ports /usr/home/jails/192.168.0.141/usr/ports
After this we have to make sure we have the same packages in the jail as on our host. So we create a temporary package directory:
mkdir -p /usr/home/jails/192.168.0.141/tmp/packages
Then we fill this directory with the packages installed on the host:
cd /usr/home/jails/192.168.0.141/tmp/packages
pkg_info | cut -f1 -d" " | xargs -n 1 pkg_create -j -b
Building inside the jail
The next step is to enter the jail:
jexec 8 csh
then we make sure we have a build jail which is clean:
pkg_delete -a
and we install the packages that where on the main host:
cd /tmp/packages pkg_add *.tbz
And finally we can build the packages in the build host:
portupgrade -avrRp
Time to fetch a cup of tea while your packages are being build. After the build process we leave the jail if everything went ok. Otherwise we might have some fixing todo. To leave the jail we type:
exit
And we unmount the /usr/ports directory from the jail:
umount /usr/home/jails/192.168.0.141/usr/ports
Upgrading the host
We can now upgrade all our packages on the host with:
portupgrade -avrRPPb
If everything went according to plan, we can clean up our temporary package directory:
rm /usr/home/jails/192.168.0.141/tmp/packages/*
Using one jail for more host/jails
If you want to use the jail for building the packages for more than one host it might be needed to split up the port configuration options on a per host basis. You can set the PORT_DBDIR environment variable to the location of the directory in which you store your ports options for a given host. i.e. for my mysql host I use:
setenv PORT_DBDIR /data/jail/port_config/mysql
You probably also want to have a host specific location in which to store the packages that are build. This can be done by setting the PACKAGES environment variable. i.e. for my mysql host I use:
setenv PACKAGES /data/jail/packages/mysql
Of course you have to make sure that these directories exists and are accessible by the build jail.