By Nathan Willis
July 31, 2013
The GNU project has released version 0.3 of Guix, its
package-management tool for GNU-based systems. Like most other
package managers, Guix is responsible for installing, updating, and
removing software packages, but it brings some uncommon features to
the task, such as unprivileged package management, per-user
installation, and garbage collection. Guix is usable today to install
and manage the current palette of GNU packages, but could be used to
keep track of others as well.
The 0.3 release was announced on
July 17 by lead developer Ludovic Courtès. Launched in
mid-2012, the project has now reached the point where it can be used
to install packages maintained in a "GNU Distribution" repository.
That repository is also maintained by Courtès, who is using it
to (eventually) bring the entire collection of GNU project software
directly to users, without waiting for downstream Linux distributions
to package it.
Guix is written in Guile, the GNU implementation of Scheme. Its
low-level package installation and removal functionality is based on
Nix, but Guix replaces much of Nix's
package-management architecture (including the package description
format) with its own Guile code. The Guix framework adds a set of
features that manages multiple installed versions of each package,
enabling unprivileged users to install and update their own versions
of packages.
The design of the package-management
system (which is explained in detail in a white paper [PDF])
refers to the core concept of "functional package
management." Several of Guix's features are said to derive
directly from its functional approach, such as garbage collection and
the rollback of updates. In a nutshell, this concept means that each
operation (e.g., installation, update, or removal) is treated as a
function: it is atomic (a property most other package managers offer),
but its outcome is also idempotent—reproducible when the
operation is repeated with the same inputs. In Guix's case, this is
important because the program offers the guarantee of idempotence even
for packages compiled from source.
The system relies on a fairly specific definition of
function "inputs," which are captured in its package description
format. Each installed package is placed in its own directory within
the Guix "package store," for example
/nix/store/hashstring-gcc-4.7.2/. The string
prepended to the package name in this directory is a hash of the
inputs used to build the package: the compiler, the library
versions, build scripts, and so on. Consequently, two versions of a
package compiled with identical inputs would result in the
same hash value, allowing Guix to re-use the same binary. But any
distinction between the inputs (say, one user using a different
version of a library) would cause Guix to install a completely new
package in the store.
A privileged Guix daemon handles the actual package maintenance
operations, with clients talking to it. The default guix
command-line client allows each user on a system to install his or her own version
of any particular package. So if one user wants to use GCC 4.8.0 and
another prefers to use 4.7.2, no problem. Moreover, in such a
scenario, both users can install their own versions of GCC without
touching the version installed by the system itself. Guix manages
this by installing every package in its own self-contained directory,
and linking each user's requested version in with symlinks.
Whenever a user installs a package, a link to the appropriate real
executable (in the package store) is created in
~/.guix-profile/bin/. Consequently,
~/.guix-profile/bin/ must be in the user's PATH. By default,
updating a package to a new release (or rebuilding it with different
options) creates a new entry in the package store. For a single-user
system, such superfluous packages may never take up a significant
percentage of disk space, but on a multi-user machine, the chaff could
certainly build up over time.
To deal with this problem, Guix supports garbage collection of
packages. Running guix gc will locate all of the packages
that are no longer used by any user profiles and remove them. In
multi-user setups, the user profile directories (e.g.,
~/.guix-profile are actually symbolic links into another
directory designated as Guix's garbage-collection root). That allows
the garbage collector to run even if the user's home directory is not
mounted or is encrypted.
Package proliferation in the store is a potential problem, but the
fact that garbage collection is not automatic has an up side: it
allows an install or update to be rolled back completely. The
--roll-back option undoes the previous transaction, whatever
it was. So if the user installs a buggy update, it can be rolled back
immediately afterward with little effort. Undoing a buggy update
several transactions back, however, requires stepping through each
intermediate rollback, and possibly re-applying any unrelated
operations caught in the middle.
Packages, distributions, and repositories
The Guix "distribution" system is akin to the binary package
repositories used by Apt or RPM, but Guix allows users to install binary
versions of packages when they are available in the repository, and
fall back to building packages from source when binaries are
unavailable—and, at least in theory, Guix's atomic transactions,
rollbacks, and other features work for source-installed packages, too.
The package
definition format uses Scheme, but it is pretty straightforward to
decipher even for those unfamiliar with Lisp-like languages. The Guix
manual lists the following example for the GNU Hello package:
(use-modules (guix packages)
(guix download)
(guix build-system gnu)
(guix licenses))
(define hello
(package
(name "hello")
(version "2.8")
(source (origin
(method url-fetch)
(uri (string-append "mirror://gnu/hello/hello-" version
".tar.gz"))
(sha256
(base32 "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6"))))
(build-system gnu-build-system)
(inputs `(("gawk" ,gawk)))
(synopsis "GNU Hello")
(description "Yeah...")
(home-page "http://www.gnu.org/software/hello/")
(license gpl3+)))
Some of
the key fields to consider are build-system, which tells Guix
how to compile the package from source if no binary is available, and
inputs, which defines the function inputs that contribute to
the installation function (and, consequently, the hash value used in
the package store). As one might expect, the only build system
defined so far is the canonical GNU autotools build system.
The GNU
Distribution is available to Guix users, including the core GNU
toolchain and a range of common GNU applications (plus several non-GNU
projects). Currently it is usable on 32-bit and 64-bit
Intel Linux systems, but the project says more platforms are to come.
Installing an available package is as simple as guix
package -i gcc, although there are a few wrinkles to consider.
For example, Guix's package store model works by linking a single
directory in the system-wide store to a directory in the user's
profile. This assumes that a package only installs files to one
location, which is often not the case. Packages that install content
in multiple output directories (e.g., /usr/bin and /usr/share/doc) are
split up into separate pieces for Guix, so the GNU Distribution's
glib package contains the Glibc binaries, while
glib:doc contains its corresponding documentation.
Because the package definition format specifies the build system,
it is possible for Guix to transparently support the mixed deployment
of binary and source packages—that is, when a binary package is
available, Guix can fetch and install it, but when unavailable, Guix
can build from source. Appending the --fallback switch to a
guix --install command will tell Guix to build the package
from source if there is no binary package or if the binary fails to
install. Users can query the repository to see which packages are
available with guix --list-available[=regexp], optionally
providing a regular expression to search for.
Admittedly, in practice a package-management system is only as good
as its packages. For example, the --fallback command is of
little value if the package does not compile successfully, and the
Guix GNU Distribution repository can currently only be deployed on
x86 Linux systems. But it is growing; the repository's package
list stands at just over 400 at press time, which are built using
the Hydra continuous-integration
system.
The repository is perhaps the most interesting aspect of the Guix
project. Other package managers may pick up ideas like per-user
installation and garbage collection (which is significantly more
important in a per-user installation setup) in due time. But for many years,
GNU itself has reached the computers of the majority of its users via
Linux distributions. Guix offers an alternative distribution
channel—in particular, an alternative that allows one user to
install GNU packages that have not yet worked their way through the
distribution release process, and to do so in a way that does not
overwrite the distribution package. That may have positive benefits
for GNU as a project, as well as providing inspiration for other large
free software projects (such as GNOME, which is not currently packaged
in the GNU Distribution repository) that also struggle from time to
time with the process of getting freshly-released software into the eager hands of
users.
(
Log in to post comments)