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
/lib so that libraries worked
from the directories in
/pkg; this ended up making path searching
in bash horribly slow, so I built a script to construct
as a directory full of symlinks to files in the other
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 is then stowed into
/gar. A more concrete example of how this works:
$ which links /gar/bin/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/ links
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 GARVERSION = 21.5.6 CATEGORIES = text MASTER_SITES = ftp://ftp.xemacs.org/pub/xemacs/xemacs-21.5/ DISTFILES = $(DISTNAME).tar.gz LIBDEPS = x11/xlib DESCRIPTION = A LISP environment disguised as a shiny text editor HOME_URL = http://www.xemacs.org/ include ../../gar.lib/auto.mk CONFIGURE_ARGS += --pdump
To install this package, all I need to do is
make -C /gar/text/xemacs
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.)
GARStow is far from finished; there's a lot more I'd like to do to it.
- Merge in the latest changes from GARNOME and BBC-GAR. (I note that GARNOME has support for fetching partial files now, for instance.) Likewise, push my changes that are generally useful (extra configure and archive types, signature checking, download fixes) their way.
- Support automatically building (and, optionally, installing) as a non-root user, chowning the package directory after installation. This'll break for packages that expect to be able to set ownership on things during the install.
- Albert Cahalan suggested that GARStow's GCC should spot people specifying system include paths explicitly and correct them to point at the prefix. This could be done using a wrapper script around GCC.
- While I like the idea of stow, I suspect that symlink dereferencing all the time isn't really doing wonders for my root filesystem performance. I'd like to write a very simple package manager that offered the same interface as stow, but used hardlinks and a database (which could be trivially rebuilt) to provide the reverse mapping.