Managing Multiple FreeBSD Systems
It is quite simple to manage multiple FreeBSD systems on your network, and to keep them maintained to the same revision level. The buildworld process can be quite long, but luckily, you only need to do it once, no matter how many FreeBSD machines you operate. In this document, I will describe how to keep multiple machines updated from only one copy of the ports tree, and one copy of the system sources.
PLEASE NOTE!!! Below, will be advice and/or examples that may not follow FreeBSD canon, and in these situations I will note where the canonical method can be found and followed. I realize my methods could be labeled dangerous in some situations, may not being good results. As always, I highly encourage the the canonical method be followed and fully understood before trying my "seat of the pants" methods decribed near the end of this article. Again, I will always point out where my methods are deviating from the norm.
Preparing Your Sources
My build machine, is of course my most powerful machine on my network. Its name is ATHENA. I use cvsup to keep my ports and sources trees updated on ATHENA. I keep a copy of ports-supfile and standard-supfile in my /root directory for convenience. Here are the commands I use to update my ports and sources:
# csup -g -L 2 ports-supfile # csup -g -L 2 standard-supfile
Straight forward, this is basically the standard use of cvsup, nothing special here. My systems are all i386 compatible, so all my kernel config files live in /usr/src/sys/i386/conf. I have currently 4 types of machines on my network, so I keep 4 kernel config files, named: HP7100, IBM8307, IBM6792, IBM2378. Each of these config files is edited and tailored to that system (ok, in reality.. only the HP7100's file has any critical edits, the others are basically just renamed copies of GENERIC). First up, we start with building the world.
# cd /usr/src # time make -j 4 buildworld
This process will take a while. On the faster, latest model computers, you might see it take less than one hour, but on an older system, two or more hours might be the norm. The time command is just there to tickle our curiosity of how long it takes our system to execute the entire buildworld. You can actually pre-pend 'time' to nearly any command.
Next, its time to build our kernels. This is how I do all of mine in succession. Note that we are still in the directory /usr/src.
# make -j 4 buildkernel KERNCONF=HP7100; make -j 4 buildkernel KERNCONF=IBM8307; make -j 4 buildkernel KERNCONF=IBM6792; make -j 4 buildkernel KERNCONF=IBM2378
That will build all four of my kernels needed for my various types of systems. Note that the '-j 4' tells make to use 4 build threads, this keeps my box busier while its waiting on the disk i/o bottle neck.
Using NFS to Deliver Your Source Trees
NFS is a fantastic way to delivery these source directories to clients on our network, using the /etc/exports file. mine looks like this:
/usr -alldirs -maproot=root -network=192.168.125 -mask=255.255.255.0
The -alldirs allows any directory under /usr to be mounted to a folder. This is handy, as our clients will be mounting 3 directories that are from under /usr. The -network directive limits connecting clients to only those that are on my local LAN, which is 192.168.125.0/24 (192.168.125.1-254, with subnet mask of 255.255.255.0). Important to note, that you should edit the specified network for your local LAN address. The above configuration might seem like it's a little too open, but remember, that root will need to write to the remote /usr/ports/distfiles directory, so its a necessary evil. Check out the FreeBSD handbook's page on NFS here: http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-nfs.html
Now, we need to edit the file /etc/rc.conf to allow the NFS daemon to start. Add these lines to /etc/rc.conf:
rpcbind_enable="YES" nfs_server_enable="YES" mountd_flags="-r"
The NFS daemon can then be started like this:
kill -HUP `cat /var/run/mountd.pid`
After these steps have been followed, the NFS server should be exporting your /usr directory to your local LAN.
Mounting The Exports From Your Client Systems
Once the NFS daemon has restarted, you should be able to see the exported volumes from your clients. A good check to see what's there, is the 'showmount' command. Here is the output from one of a query of my NFS server, as mentioned above, named ATHENA:
[jhorne@pollux ~]$ showmount -e athena Exports list on athena: /usr 192.168.125.0
So now we have confirmed that the exports are working on our NFS server, lets mount them up from the clients. If I first check my current mounted volumes, I would see:
[root@pollux ~]# df -h Filesystem Size Used Avail Capacity Mounted on /dev/ad0s1a 496M 67M 389M 15% / devfs 1.0K 1.0K 0B 100% /dev /dev/ad0s1e 496M 18K 456M 0% /tmp /dev/ad0s1f 102G 770M 93G 1% /usr /dev/ad0s1d 2.4G 44M 2.2G 2% /var
Now, we mount the remote volumes:
# mount athena:/usr/src /usr/src # mount athena:/usr/obj /usr/obj # mount athena:/usr/ports /usr/ports
and checking again, we now see the 3 remote volumes, mounted locally.
[root@pollux ~]# df -h Filesystem Size Used Avail Capacity Mounted on /dev/ad0s1a 496M 67M 389M 15% / devfs 1.0K 1.0K 0B 100% /dev /dev/ad0s1e 496M 18K 456M 0% /tmp /dev/ad0s1f 102G 770M 93G 1% /usr /dev/ad0s1d 2.4G 44M 2.2G 2% /var athena:/usr/src 39G 21G 15G 58% /usr/src athena:/usr/obj 39G 21G 15G 58% /usr/obj athena:/usr/ports 39G 21G 15G 58% /usr/ports
Now we have access to the world that we built earlier on ATHENA. Its now quite simple to install the kernel and world. Change directories to /usr/src, and proceed as you normally would (either in single user mode with network support, or in full multi-user mode, which ever installworld method you prefer). Personally, I always installworld while my system is up and running, even tho this can sometimes be dangerous. Even though I myself have never had a problem doing it like this, I'm not willing to promise that you the reader will never have a problem, so I *highly* recommend that you familiarize yourself with the canonical method, and master that way first. The canonical method can be learned about here: http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html
So, after moving to whatever usermode you prefer, and mounting the NFS file systems, change to /usr/src on your clients, and perform the update like this:
# cd /usr/src # make installkernnel KERNCONF=[KERN-CONFIG] # mergemaster -p # make installworld # mergemaster
Reboot afterwards, and your system will be running the same kernel and world version as your build server! Success!
Installing and Updating Ports
Once the /usr/ports directory from your build server has been mounted on your client, you then have the ability to build anything you need on any server, but only having to maintain 1 copy of the current ports collection. Before we start building, we need to make one small edit to our client's /etc/make.conf. Add this line:
(and create a tmp directory under /usr). This will cause all the sources to do their building under /usr/tmp, instead of somewhere under /usr/ports (which, remember, is a file system that does not belong to the client who is building the port). Some of the more complicated ports will error out if they don't build their work directories on a file system where they have full rights. the WRKDIRPREFIX take care of this problem. If /usr/tmp doesn't work for you, then specify something that works for your configuration. After this is set up, your system is ready to build any port you need, using your build server!
I would also note, that updating ports that are already installed, will also use the same NFS-mounted ports tree. The command portupgrade will not care where the tree physically comes from, so mount up, and update away!