|
|
Subscribe / Log in / New account

GNU Guix sports functional package management

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.


to post comments

GNU Guix sports functional package management

Posted Aug 1, 2013 4:44 UTC (Thu) by dberkholz (guest, #23346) [Link] (7 responses)

Because the answer always seems to be, let's write another package manager. Sigh.

GNU Guix sports functional package management

Posted Aug 1, 2013 8:59 UTC (Thu) by Flameeyes (guest, #51238) [Link]

... in Guile.

GNU Guix sports functional package management

Posted Aug 1, 2013 9:34 UTC (Thu) by sionescu (subscriber, #59410) [Link] (3 responses)

Given the shortcomings of ebuilds which are written in bash, yes.

GNU Guix sports functional package management

Posted Aug 1, 2013 19:04 UTC (Thu) by dberkholz (guest, #23346) [Link] (2 responses)

While I agree with you that writing the core of a package manager in bash is awful, it has a very natural mapping to the types of operations you perform while building and installing software. File operations, process control, calling out to external processes are all very well-suited to shell scripting.

If for some weird reason I had to write a new package manager, I'd implement the internals in a high-level language (likely functional or logical) with minimal runtime dependencies to keep breakage options down. But I'd keep the packages in modern shell, whether it's bash, zsh, etc.

GNU Guix sports functional package management

Posted Aug 1, 2013 19:36 UTC (Thu) by justincormack (subscriber, #70439) [Link] (1 responses)

You can do file operations, process control and so on in a high level language too, its not horrendously hard. Surprised how little people bother though; Go might be a good target as it has reasonable support already.

GNU Guix sports functional package management

Posted Aug 2, 2013 11:38 UTC (Fri) by sorpigal (guest, #36106) [Link]

At the very least Perl could be used. It's less error-prone than sh and has about the same level of easy access to file operations and so forth.

GNU Guix sports functional package management

Posted Aug 1, 2013 12:52 UTC (Thu) by renox (guest, #23785) [Link]

>Because the answer always seems to be, let's write another package manager. Sigh.

Well, Guix/nix are at least different from the 'normal' package tools: the rpm/pkg wasteful split is here only due to inertia, both have similar features.

GNU Guix sports functional package management

Posted Aug 2, 2013 13:47 UTC (Fri) by smitty_one_each (subscriber, #28989) [Link]

I think I want to write a package manager that manages other package managers.
I just need the write XML data store to hold the data.
Then there is the question of whether to optimize for insecurity, using PHP, or bloat, and use Java.
I guess Java has more of an XML affinity, so I'll use that.
Good times.

"glib" package

Posted Aug 1, 2013 19:11 UTC (Thu) by atai (subscriber, #10977) [Link] (1 responses)

The article mentions a "glib" package. Should that be the glibc package?

"glib" package

Posted Aug 2, 2013 3:50 UTC (Fri) by pr1268 (guest, #24648) [Link]

No, glib and glibc are two separate entities.

  • glib is a library of accessory functions and data structures, many of which are used by GTK+.
  • glibc is the GNU version of the C Standard Library.

GNU Guix sports functional package management

Posted Aug 2, 2013 14:01 UTC (Fri) by etienne (guest, #25256) [Link] (3 responses)

> enabling unprivileged users to install and update their own versions of packages

Isn't that a can of worm when the package contains a library, and "ldconfig" state is shared in between users?
How about security risk when a suid application is linked to the new library?

GNU Guix sports functional package management

Posted Aug 2, 2013 17:05 UTC (Fri) by mathstuf (subscriber, #69389) [Link]

I wouldn't think that user-installed packages are available to other users. For example, I install software into ~/misc/root/$name instead of /usr/local or whatever because it makes uninstalling a snap (rm -rf) and doesn't require sudo permissions.

Also, currently installed applications wouldn't use the new package; the old package that was linked into the suid binary would still be there.

GNU Guix sports functional package management

Posted Aug 2, 2013 20:32 UTC (Fri) by virtex (subscriber, #3019) [Link]

Think about the types of installs users already tend to do in their own accounts -- desktop themes, panel apps, browser plugins and extensions, conky configs -- and every program has its own method of managing installed material. After a while it gets to be a mess. I've long wished I could manage these types of additions using apt-get, yum, emerge, or whatever. Then I could keep all my stuff up to date with a simple "apt-get upgrade". Or I could just see everything I have installed with "dpkg --list". You get the idea.

This is the type of package management that would be most useful for individual users. Allowing a user to install their own private version of Firefox, however, would be secondary, at least in my opinion.

GNU Guix sports functional package management

Posted Aug 3, 2013 2:31 UTC (Sat) by idupree (guest, #71169) [Link]

System .so files *cannot* be updated, because of the design of Nix/Guix. (Well, unless you're root and manually break things, obviously.) /etc/ld.so.cache is not used because it's an impurity. I believe NixOS/Guix uses rpath (runpath) in binaries rather than having a global library search path. (e.g. see http://nixos.org/patchelf.html )

"[Unprivileged?] users cannot install setuid binaries." - http://nixos.org/nixos/ . (Also, Openwall GNU/*/Linux has made a working system with no suid/sgid/fscaps binaries at all. I hope everyone goes this way eventually.)

Yes, it's a can of worms; these people opened the can and killed all the worms. After all, these worms threatened purity even without unprivileged package installation. Consider: If you (sysadmin) left an old, vulnerable 'sudo' installed? System security depends on whether you garbage-collect it![*] But if the filesystem cannot grant capabilities, and if users are already allowed to run their own binaries in their home directories, then adding data to new places in /nix/store is not a risk (besides defense-in-depth).

[*] I'm not up-to-date regarding whether Nix and/or Guix have this old-setuid-executables risk. I think the Openwall approach to setuid would be the best, but maybe that's just me.


Copyright © 2013, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds