K.Mandla's blog of Linux experiences

Case in point: A Crux ports server at 100Mhz 16Mb

I have five machines all running Crux now, although that number is apt to fluctuate from time to time. With that many machines all updating their ports libraries directly from the Internet, it only makes sense to give that responsibility to one machine, and let the others refresh themselves from it.

And it only makes sense for that one machine to automatically refresh its own tree once a day, or perhaps even twice a day, and serve those ports to the remaining machines whenever they need it. The server doesn’t have to do any real compiling — in fact, it’s probably not going to do anything at all, just sit and wait for another machine to request fresh ports.

The ironic part is, this is terribly simple to set up. crond can handle the important role — automatically refreshing the system ports — and NFS makes the actual serving of the ports no more difficult than mounting a directory and copying them across. An rsync command from the root account of the client, and it’s done. Lower bandwidth and no need to swamp the Crux servers with multiple machines updating individually.

The first step in setting it up is to build a kernel that can act as a server. NFS is activated under the File systems::Network file systems options in the 2.6.28 kernel, and there’s a separate option for the server and the client. I’ve activated both on my machine, but that’s also because I use the battered Thinkpad as a way of transferring files across machines, and I want to be able to mount that as a normal user, and read and write to it.

Once the kernel is built, you’ll need to set up the server and trigger it as a service. The best place I know for information on setting up an NFS server is the Arch wiki. After that, both portmap and nfs-utils need to be installed on the server. For export options, I used this:

/usr/ports/ 192.168.XX.1/24(ro,sync)

Since there’s no need for clients to write to the directory, I set mine to read-only. Other options, for example the ones on the Gentoo wiki, also seem superfluous, and so I don’t enable any of those either.

I’ve had trouble starting the server when I manually enable the network through /etc/rc.local, so I use the same commands in the /etc/rc.d/net service instead — everything from enabling the pcmcia socket with pcmcia-socket-startup and setting wireless options with iwconfig, to starting dhcpcd.

Now it’s time to set up crond. This is even easier, since there’s only one file to make, and one file to edit. Open up /etc/crontab and adjust it to your liking. Personally I just want the ports updated once a day — more than that seems overdone. Perhaps with another distro you might want fresher updates, but in my experience, once a day is more than enough for Crux. Here’s what I used to get updates at 7:30 a.m., local time.

30 07 * * * /usr/sbin/runjobs /etc/cron/daily

And in the /etc/cron/daily folder, make a file that says only this.

/usr/bin/ports -u

Don’t forget to make that file executable. I wondered for a long while why cron wasn’t doing anything, and then I remembered that. :D

After that, just make sure crond, net, portmap and nfsserver are all triggered in your /etc/rc.conf file, so the entire business is ready at boot.

For clients, I edited my /etc/fstab files to include this line.

192.168.XX.XX:/usr/ports /media/ports nfs noauto,nolock 0 0

I like to mount external files and drives to the /media folder, and symlink into the home directories to access them. The noauto flag doesn’t mount it at boot, and nolock helps avoid a weird two- to three-minute delay when I mount the network drives. Notice that I didn’t include the users flag, which would have allowed normal users to mount the server too. I see no point in that, since normal users can’t synchronize the ports tree anyway because they don’t have write permission to the local /usr/ports folder.

Once that’s in place, I switch to the superuser account, mount the network drive, and use this to sync the local tree against the server.

rsync -a --progress /media/ports /usr/ports

I can still update my ports tree manually, and I can still edit and maintain ports unique to each machine or keep source files on a local machine (such as the proprietary wireless firmware for my Intel PRO/Wireless 2200BG). There are no source packages on the server, no binaries, but the patches and extra files can remain there as well. Best of all, if I need to rebuild a machine, it’s easy to get a fresh tree without relying on access beyond my local network.

The erstwhile dealbreaker flaws this machine has — the noisy, small hard drive and the relatively nonexistent RAM — don’t really matter in this role. Since the ports tree is only refreshed once a day, and it’s first thing in the morning, it can do it’s job and be noisy for a little bit, then sit idle and quiet for 23 hours and 55 minutes. (To ease your environmental concerns, the wattage rating on the AC adapter is 60W, which in my mind ranks it about the same as the light bulb in my kitchen.)

And the final touch? Installing cmatrix so the machine has something fun to show, while it’s sitting, counting the seconds until the next ports update. Now tell me: Can you think of a better use for an extra 100Mhz laptop? :)

P.S.: I suppose you could do this for some other script-based distros, or perhaps use one machine to sync the ABS tree in Arch, and serve it to the rest of your house. Feel free to experiment. ;)