2003-05-02 · in Tech Notes · 728 words

GARStow is the package management system I'm building and using.


Back when I first started building my own system, I (like most people) installed all my software in /usr/local. Pretty much everything works fine if you do this, because it's the common case; however, upgrading software is unreliable because you can't assume you've removed old versions of files, and removing software is pretty much impossible.

The next iteration of the system involved having each package installed with its prefix set to /pkg/packagename, and constructing symlinks by hand in /include and /lib so that libraries worked correctly. My /etc/profile built $PATH automatically from the directories in /pkg; this ended up making path searching in bash horribly slow, so I built a script to construct /pkg/bin as a directory full of symlinks to files in the other bin directories. This made package installation and upgrading easy, and removal reasonably straightforward (I still had to remove the symlinks by hand); however, libraries still need symlinks making in the right place.

Having looked at GNU stow, the BSD and GAR ports systems, and how the UKC CS department installs software, I reasoned that most of this should be automatable. I therefore modified GAR to understand stow, and GARStow is the result.

How GARStow works

As with the standard GAR system (which you're most likely to have run into for GARNOME, although it was built for the Bootable Business Card project), packages are built from source: the GAR tree uses GNU make to download packages, verify their checksums, extract them, configure them, build them and install them. The major changes that I've made are to the installation step.

GARStow follows the standard stow prefix advice: all packages are configured to have the same prefix (on my system, /gar). However, when packages are installed, the prefix is set to /gar/packages/packagename-version. A symlink is then made from that directory to /gar/packages/packagename, and /gar/packages/packagename is then stowed into /gar. A more concrete example of how this works:

$ which links
$ ls -l /gar/bin/links
[...] Oct 16 22:37 /gar/bin/links -> ../packages/links/bin/links
$ ls -ld /gar/packages/links
[...] Oct 16 22:36 /gar/packages/links -> links-2.1pre4
$ ls /gar/packages/links-2.1pre4/bin/

This system means that when a new version of a package is installed, the old package is cleanly unstowed, but is kept around; it is easy to switch between versions of a package by changing the symlink and restowing. Likewise, it is easy to remove a package. It is also possible to ship a package to another GARStow installation by just copying the package-version directory, making the symlink and stowing it. (This could be extended to support making binary packages from GARStow.)

For software that follows the GNU guidelines on prefix handling, GARStow Makefiles are very straightforward:

GARNAME = xemacs
MASTER_SITES = ftp://ftp.xemacs.org/pub/xemacs/xemacs-21.5/
LIBDEPS = x11/xlib

DESCRIPTION = A LISP environment disguised as a shiny text editor
HOME_URL = http://www.xemacs.org/

include ../../gar.lib/auto.mk


To install this package, all I need to do is make -C /gar/text/xemacs install.

I've also modified GAR so that it can check PGP signatures of packages; the GAR tree contains files containing the PGP keys used to verify packages. (Bear in mind that I don't provide signed packages of GARStow, so this doesn't buy you any security unless you check that the keys in your GARStow tree are the correct ones.)

The future

GARStow is far from finished; there's a lot more I'd like to do to it.