https://guix.gnu.org/feeds/blog/system-services.atomGNU Guix — Blog — System servicesfeed author nameGNU Guixhttps://guix.gnu.org/themes/initial/img/icon.png2024-03-15T23:01:42Zhttps://guix.gnu.org/blog/2023/reinstating-an-iconic-error-message//Reinstating an iconic error messageLudovic Courtès2023-04-01T11:00:00Z2023-04-01T11:00:00Z Software development is a social process. What might be a “bug” for
someone might well be a “feature” for someone else. The Guix project
rediscovered it the hard way when, after “fixing a bug” that had been
present in Guix System for years, it was confronted with an uproar in its
user base. In this post we look at why developers considered the initial behavior a
“bug”, why users on the contrary had come to rely on it, and why
developers remained blind to it. A patch to reinstate the initial
behavior is being reviewed . This
post is also…<p>Software development is a social process. What might be a “bug” for
someone might well be a “feature” for someone else. The Guix project
rediscovered it the hard way when, after “fixing a bug” that had been
present in Guix System for years, it was confronted with an uproar in its
user base.</p><p>In this post we look at why developers considered the initial behavior a
“bug”, why users on the contrary had come to rely on it, and why
developers remained blind to it. A patch to reinstate the initial
behavior <a href="https://issues.guix.gnu.org/62584">is being reviewed</a>. This
post is also an opportunity for us Guix developers to extend our
apologies to our users whose workflow was disrupted.</p><h1>The crux of the matter</h1><p>Anyone who’s used Guix System in the past has seen this message on the
console during the boot process:</p><pre><code>error in finalization thread: Success</code></pre><p>The following picture shows a typical boot screen (with additional
messages in the same vein):</p><p><img src="/static/blog/img/error-success.jpg" alt="Picture of a monitor showing the error/success boot message." /></p><p>If you have never seen it before, it may look surprising to you. Guix
System users lived with it literally for years; the message became a
hint that the boot process was, indeed, successful.</p><p>A few months ago, a contributor sought to satisfy their curiosity by
finding the origin of the message. It did look like a spurious error
message, after all, and perhaps the right course of action would be to
address the problem at its root—or so they thought.</p><p>As it turns out, the message <a href="https://git.savannah.gnu.org/cgit/guile.git/tree/libguile/finalizers.c#n238?id=df86a2a8c8725ac6244a222d399a5b959101f621">originated in
Guile</a>—check
out the <a href="https://www.gnu.org/software/guile/manual/html_node/Foreign-Object-Memory-Management.html">Guile
manual</a>
if you’re curious about finalization. Investigation revealed two
things: first, that this <code>perror</code> call in Guile was presumably reporting
the wrong error code—this was
<a href="https://git.savannah.gnu.org/cgit/guile.git/commit/?id=1fbe89f7bdbf35408ec2df8de755c2f1323016a6">fixed</a>.</p><p>The second error—the core of the problem—lied in Guix System itself.
Remember that, in its quest of memory safety™, statelessness, and fun,
Guix System does it all in Guile Scheme—well, except for the kernel (for
now). As soon as Linux has booted, Guix System spawns Guile to run boot
code that’s in its <a href="https://guix.gnu.org/manual/en/html_node/Initial-RAM-Disk.html"><em>initial RAM
disk</em></a>
(“initrd”). Right before executing
<a href="https://gnu.org/software/shepherd"><code>shepherd</code></a>, its service manager, as
PID 1, the initrd code would carelessly close all the file descriptors
above 2 to make sure they do not leak into PID 1. The problem—you
guessed it—is that one of them was the now-famous file descriptor of the
finalization thread’s pipe; the finalization thread would quickly notice
and boom!</p><pre><code>error in finalization thread: Success</code></pre><p>Our intrepid developers thought: “hey, we found it! Let’s fix it!”. And
so <a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=168a7933c0e138dc7061a3f0dc96871e16da5c5f">they
did</a>.</p><h1>Breaking user workflows</h1><p>This could have been the end of the story, but there’s more to it than
software. As Xkcd <a href="https://xkcd.com/1172/">famously captured</a>, this was
bound to break someone’s workflow. Indeed, had developers paid more
attention to what users had to say, they would have <em>known</em> that the
status quo was preferable.</p><p>For some time now, users had shown that they held the error/success
message deep in their heart. The message was seen on the blackboard at
the <a href="https://10years.guix.gnu.org">Ten Years of Guix</a> celebration, as a
motto, as a rallying cry, spontaneously put on display:</p><p><img src="https://10years.guix.gnu.org/static/images/photos/roptat-finalization-thread.jpg" alt="Picture of a blackboard with the famous message (by Julien Lepiller, under CC0)." /></p><p>What’s more, a fellow NixOS hacker and Guix enthusiast, beguiled by this
powerful message, <a href="/static/blog/img/error-success-sticker.svg">designed</a>
stickers and brought them to FOSDEM in February 2023:</p><p><img src="/static/blog/img/error-success-sticker-pile.jpg" alt="Picture of error/success stickers (under CC0)." /></p><p>The sticker design builds upon the “test pilot” graphics made by Luis
Felipe for the <a href="https://guix.gnu.org/en/blog/2021/gnu-guix-1.3.0-released/">1.3.0
release</a>.
The test pilot has a bug on its helmet. In a way, the drawing and error
message both represent, metaphorically, a core tenet of Guix as a
project; just like Haskell is <em>avoiding success at all costs</em>, Guix
seems trapped in an <em>error/success</em> quantum state.</p><p>Had it gone too far? Was calling it a “bug” the demonstration of the
arrogance of developers detached from the reality of the community?</p><h1>Fixing our mistakes</h1><p>Those who installed Guix System starting from <a href="https://guix.gnu.org/en/blog/2022/gnu-guix-1.4.0-released/">version
1.4.0</a> have
been missing out on the error/success boot message. The patch
<a href="https://issues.guix.gnu.org/62584">submitted today</a> finally reinstates
that message. The review process will determine whether consensus is to
enable it by default—as part of
<a href="https://guix.gnu.org/manual/en/html_node/Base-Services.html#index-_0025base_002dservices-1"><code>%base-service</code></a>—or
whether to make it optional—after all, we also need to accommodate the
needs of <em>new</em> users who never saw this message. This will allow users
to restore their workflow, while also ensuring that those freshly
printed stickers remain relevant.</p><p>This incident had broader consequences in the project. It led some to
suggest that we, finally, set up a <em>request-for-comment</em> (RFC) kind of
process that would give all the community a say on important topics—a
process most large free software projects have developed in one form or
another. Such a process could have prevented this incident: instead of
arrogantly labeling it as a “bug”, developers would have proposed an RFC
to remove the message; the discussion period, most likely, would have
made it clear that removal was not a desirable outcome and we would all
have moved on.</p><p>This incident made many users uncomfortable, but we are glad that it is
now being addressed. The lessons learned will be beneficial to the
project for the years to come.</p><p><img src="/static/blog/img/error-success-sticker-bird.jpg" alt="Picture of a metal bird holding an error/success sticker (under CC0)." /></p><h1>Credits</h1><blockquote><p><a href="https://git.savannah.gnu.org/cgit/guix/guix-artwork.git/tree/promotional/">Test
pilot</a>
by Luis Felipe distributed under the terms of
<a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a>;
sticker design distributed under
<a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a> as
well. Blackboard picture by Julien Lepiller under
<a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a>; sticker
pictures under
<a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a>.</p><p>Many thanks to the anonymous sticker provider!</p></blockquote><h4>About GNU Guix</h4><p><a href="https://guix.gnu.org">GNU Guix</a> is a transactional package manager and
an advanced distribution of the GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects user
freedom</a>.
Guix can be used on top of any system running the Hurd or the Linux
kernel, or it can be used as a standalone operating system distribution
for i686, x86_64, ARMv7, AArch64 and POWER9 machines.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. When used as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless approach to
operating system configuration management. Guix is highly customizable
and hackable through <a href="https://www.gnu.org/software/guile">Guile</a>
programming interfaces and extensions to the
<a href="http://schemers.org">Scheme</a> language.</p>https://guix.gnu.org/blog/2018/customize-guixsd-use-stock-ssh-agent-everywhere//Customize GuixSD: Use Stock SSH Agent Everywhere!Chris Marusich2018-05-26T17:00:00Z2018-05-26T17:00:00Z I frequently use SSH. Since I don't like typing my password all the
time, I use an SSH agent. Originally I used the GNOME Keyring as my
SSH agent, but recently I've switched to using the ssh-agent from
OpenSSH. I accomplished this by doing the following two things: Replace the default GNOME Keyring with a custom-built version that
disables the SSH agent feature. Start my desktop session with OpenSSH's ssh-agent so that it's
always available to any applications in my desktop session. Below, I'll show you in…<p>I frequently use SSH. Since I don't like typing my password all the
time, I use an SSH agent. Originally I used the GNOME Keyring as my
SSH agent, but recently I've switched to using the <code>ssh-agent</code> from
OpenSSH. I accomplished this by doing the following two things:</p><ul><li><p>Replace the default GNOME Keyring with a custom-built version that
disables the SSH agent feature.</p></li><li><p>Start my desktop session with OpenSSH's <code>ssh-agent</code> so that it's
always available to any applications in my desktop session.</p></li></ul><p>Below, I'll show you in detail how I did this. In addition to being
useful for anyone who wants to use OpenSSH's <code>ssh-agent</code> in GuixSD, I
hope this example will help to illustrate how GuixSD enables you to
customize your entire system to be just the way you want it!</p><h1>The Problem: GNOME Keyring Can't Handle My SSH Keys</h1><p>On GuixSD, I like to use the <a href="https://www.gnome.org">GNOME desktop
environment</a>. GNOME is just one of <a href="https://www.gnu.org/software/guix/manual/en/html_node/Desktop-Services.html">the
various desktop environments that GuixSD
supports</a>.
By default, the GNOME desktop environment on GuixSD comes with a lot
of goodies, including the <a href="https://wiki.gnome.org/Projects/GnomeKeyring">GNOME
Keyring</a>, which is
GNOME's integrated solution for securely storing secrets, passwords,
keys, and certificates.</p><p>The GNOME Keyring has many useful features. One of those is <a href="https://wiki.gnome.org/Projects/GnomeKeyring/Ssh">its SSH
Agent feature</a>.
This feature allows you to use the GNOME Keyring as an SSH agent.
This means that when you invoke a command like <code>ssh-add</code>, it will add
the private key identities to the GNOME Keyring. Usually this is
quite convenient, since it means that GNOME users basically get an SSH
agent for free!</p><p>Unfortunately, up until <a href="https://www.gnome.org/news/2018/03/gnome-3-28-released/">GNOME 3.28 (the current
release)</a>,
the GNOME Keyring's SSH agent implementation was not as complete as
the stock SSH agent from OpenSSH. As a result, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=775981">earlier versions of
GNOME Keyring did not support many use
cases</a>. This was a
problem for me, since GNOME Keyring couldn't read my modern SSH keys.
To make matters worse, by design the SSH agent for GNOME Keyring and
OpenSSH both use the same environment variables (e.g.,
<code>SSH_AUTH_SOCK</code>). This makes it difficult to use OpenSSH's
<code>ssh-agent</code> everywhere within my GNOME desktop environment.</p><p>Happily, starting with GNOME 3.28, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=775981">GNOME Keyring delegates all SSH
agent functionality to the stock SSH agent from
OpenSSH</a>. They
have removed their custom implementation entirely. This means that
today, I could solve my problem simply by using the most recent
version of GNOME Keyring. I'll probably do just that when the new
release gets included in Guix. However, when I first encountered this
problem, GNOME 3.28 hadn't been released yet, so the only option
available to me was to customize GNOME Keyring or remove it entirely.</p><p>In any case, I'm going to show you how I solved this problem by
modifying the default GNOME Keyring from the Guix package collection.
The same ideas can be used to customize any package, so hopefully it
will be a useful example. And what if you don't use GNOME, but you do
want to use OpenSSH's <code>ssh-agent</code>? In that case, you may still need
to customize your GuixSD system a little bit. Let me show you how!</p><h1>The Solution: <code>~/.xsession</code> and a Custom GNOME Keyring</h1><p>The goal is to make OpenSSH's <code>ssh-agent</code> available everywhere when we
log into our GNOME desktop session. First, we must arrange for
<code>ssh-agent</code> to be running whenever we're logged in.</p><p>There are many ways to accomplish this. For example, I've seen people
implement shell code in their shell's start-up files which basically
manages their own <code>ssh-agent</code> process. However, I prefer to just
start <code>ssh-agent</code> once and not clutter up my shell's start-up files
with unnecessary code. So that's what we're going to do!</p><h1>Launch OpenSSH's <code>ssh-agent</code> in Your <code>~/.xsession</code></h1><p>By default, GuixSD uses the <a href="https://sourceforge.net/projects/slim.berlios">SLiM desktop
manager</a>. When you log
in, SLiM presents you with a menu of so-called "desktop sessions",
which correspond to the desktop environments you've declared in your
<a href="https://www.gnu.org/software/guix/manual/en/html_node/operating_002dsystem-Reference.html">operating system
declaration</a>.
For example, if you've added the
<a href="https://www.gnu.org/software/guix/manual/en/html_node/Desktop-Services.html">gnome-desktop-service</a>
to your operating system declaration, then you'll see an option for
GNOME at the SLiM login screen.</p><p>You can further customize your desktop session with the <code>~/.xsession</code>
file. The contract for this file in GuixSD is the same as it is for
many GNU/Linux distributions: <a href="https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/services/xorg.scm?id=263c9941a1e523b360ca9f42d1ed6b11e6e6e285#n392">if it exists, then it will be
executed</a>.
The arguments passed to it will be the command line invocation that
would normally be executed to start the desktop session that you
selected from the SLiM login screen. Your <code>~/.xsession</code> is expected
to do whatever is necessary to customize and then start the specified
desktop environment. For example, when you select GNOME from the SLiM
login screen, your <code>~/.xsession</code> file will basically be executed like
this (for the exact execution mechanism, please refer to the source
code linked above):</p><pre><code class="language-shell">$ ~/.xsession gnome-session</code></pre><p>The upshot of all this is that the <code>~/.xsession</code> is an <em>ideal</em> place
to set up your SSH agent! If you start an SSH agent in your
<code>~/.xsession</code> file, you can have the SSH agent available everywhere,
automatically! Check it out: Put this into your <code>~/.xsession</code> file,
and make the file executable:</p><pre><code class="language-shell">#!/run/current-system/profile/bin/bash
exec ssh-agent "$@"</code></pre><p>When you invoke <code>ssh-agent</code> in this way, it executes the specified
program in an environment where commands like <code>ssh-add</code> just work. It
does this by setting environment variables such as <code>SSH_AUTH_SOCK</code>,
which programs like <code>ssh-add</code> find and use automatically. Because
GuixSD allows you to customize your desktop session like this, you can
use any SSH agent you want in any desktop environments that you want,
automatically!</p><p>Of course, if you're using GNOME Keyring version 3.27 or earlier (like
I was), then this isn't quite enough. In that case, the SSH agent
feature of GNOME Keyring will override the environment variables set
by OpenSSH's <code>ssh-agent</code>, so commands like <code>ssh-add</code> will wind up
communicating with the GNOME Keyring instead of the <code>ssh-agent</code> you
launched in your <code>~/.xsession</code>. This is bad because, as previously
mentioned, GNOME Keyring version 3.27 or earlier doesn't support as
many uses cases as OpenSSH's <code>ssh-agent</code>.</p><p>How can we work around this problem?</p><h1>Customize the GNOME Keyring</h1><p>One heavy-handed solution would be to remove GNOME Keyring entirely.
That would work, but then you would lose out on all the other great
features that it has to offer. Surely we can do better!</p><p>The GNOME Keyring documentation
<a href="https://wiki.gnome.org/Projects/GnomeKeyring/Ssh">explains</a> that one
way to disable the SSH agent feature is to include the
<code>--disable-ssh-agent</code> configure flag when building it. Thankfully,
Guix provides some ways to customize software in <em>exactly</em> this way!</p><p>Conceptually, we "just" have to do the following two things:</p><ul><li><p>Customize the existing <code>gnome-keyring</code> package.</p></li><li><p>Make the <code>gnome-desktop-service</code> use our custom <code>gnome-keyring</code>
package.</p></li></ul><h1>Create a Custom GNOME Keyring Package</h1><p>Let's begin by defining a custom <code>gnome-keyring</code> package, which we'll
call <code>gnome-keyring-sans-ssh-agent</code>. With Guix, we can do this in
less than ten lines of code:</p><pre><code class="language-scheme">(define-public gnome-keyring-sans-ssh-agent
(package
(inherit gnome-keyring)
(name "gnome-keyring-sans-ssh-agent")
(arguments
(substitute-keyword-arguments
(package-arguments gnome-keyring)
((#:configure-flags flags)
`(cons "--disable-ssh-agent" ,flags))))))</code></pre><p>Don't worry if some of that code is unclear at first. I'll clarify it
now!</p><p>In Guix, a <code><package></code> record like the one above is defined by a macro
called <code>define-record-type*</code> (<a href="https://git.savannah.gnu.org/cgit/guix.git/tree/guix/records.scm?id=263c9941a1e523b360ca9f42d1ed6b11e6e6e285#n178">defined in the file guix/records.scm in
the Guix
source</a>).
It's similar to an <a href="https://www.gnu.org/software/guile/manual/en/html_node/SRFI_002d9-Records.html#SRFI_002d9-Records">SRFI-9
record</a>.
The <code>inherit</code> feature of this macro is very useful: it creates a new
copy of an existing record, overriding specific fields in the new copy
as needed.</p><p>In the above, we define <code>gnome-keyring-sans-ssh-agent</code> to be a copy of
the <code>gnome-keyring</code> package, and we use <code>inherit</code> to change the <code>name</code>
and <code>arguments</code> fields in that new copy. We also use the
<code>substitute-keyword-arguments</code> macro (<a href="https://git.savannah.gnu.org/cgit/guix.git/tree/guix/utils.scm?id=263c9941a1e523b360ca9f42d1ed6b11e6e6e285#n345">defined in the file
guix/utils.scm in the Guix
source</a>)
to add <code>--disable-ssh-agent</code> to the list of <a href="https://www.gnu.org/software/guix/manual/en/html_node/Build-Systems.html">configure
flags</a>
defined in the <code>gnome-keyring</code> package. The effect of this is to
define a new GNOME Keyring package that is built exactly the same as
the original, but in which the SSH agent is disabled.</p><p>I'll admit this code may seem a little opaque at first, but all code
does when you first learn it. Once you get the hang of things, you
can customize packages any way you can imagine. If you want to learn
more, you should read the docstrings for the <code>define-record-type*</code> and
<code>substitute-keyword-arguments</code> macros in the Guix source code. It's
also very helpful to <code>grep</code> the source code to see examples of how
these macros are used in practice. For example:</p><pre><code class="language-shell">$ # Search the currently installed Guix for the current user.
$ grep -r substitute-keyword-arguments ~/.config/guix/latest
$ # Search the Guix Git repository, assuming you've checked it out here.
$ grep -r substitute-keyword-arguments ~/guix</code></pre><h1>Use the Custom GNOME Keyring Package</h1><p>OK, we've created our own custom GNOME Keyring package. Great! Now,
how do we use it?</p><p>In GuixSD, the GNOME desktop environment is treated as a <a href="https://www.gnu.org/software/guix/manual/en/html_node/Services.html">system
service</a>. To
make GNOME use our custom GNOME Keyring package, we must somehow
customize the <code>gnome-desktop-service</code> (<a href="https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/services/desktop.scm?id=263c9941a1e523b360ca9f42d1ed6b11e6e6e285#n795">defined in the file
gnu/services/desktop.scm</a>)
to use our custom package. How do we customize a service? Generally,
the answer depends on the service. Thankfully, many of GuixSD's
services, including the <code>gnome-desktop-service</code>, follow a similar
pattern. In this case, we "just" need to pass a custom
<code><gnome-desktop-configuration></code> record to the <code>gnome-desktop-service</code>
procedure in our operating system declaration, like this:</p><pre><code class="language-scheme">(operating-system
...
(services (cons*
(gnome-desktop-service
#:config my-gnome-desktop-configuration)
%desktop-services)))</code></pre><p>Here, the <code>cons*</code> procedure just adds the GNOME desktop service to the
<code>%desktop-services</code> list, returning the new list. For details, please
refer to <a href="https://www.gnu.org/software/guile/manual/en/html_node/List-Constructors.html#index-cons_002a">the Guile
manual</a>.</p><p>Now the question is: what should <code>my-gnome-desktop-configuration</code> be?
Well, if we examine <a href="https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/services/desktop.scm?id=263c9941a1e523b360ca9f42d1ed6b11e6e6e285#n799">the definition of this record type in the Guix
source</a>,
we see the following:</p><pre><code class="language-scheme">(define-record-type* <gnome-desktop-configuration> gnome-desktop-configuration
make-gnome-desktop-configuration
gnome-desktop-configuration
(gnome-package gnome-package (default gnome)))</code></pre><p>The <code>gnome</code> package referenced here is a "meta" package: it exists
only to aggregate many GNOME packages together, including
<code>gnome-keyring</code>. To see <a href="https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/gnome.scm?id=263c9941a1e523b360ca9f42d1ed6b11e6e6e285#n5977">its
definition</a>,
we can simply invoke <code>guix edit gnome</code>, which <a href="https://www.gnu.org/software/guix/manual/en/html_node/Invoking-guix-edit.html#Invoking-guix-edit">opens the file where
the package is
defined</a>:</p><pre><code class="language-scheme">(define-public gnome
(package
(name "gnome")
(version (package-version gnome-shell))
(source #f)
(build-system trivial-build-system)
(arguments '(#:builder (mkdir %output)))
(propagated-inputs
;; TODO: Add more packages according to:
;; <https://packages.debian.org/jessie/gnome-core>.
`(("adwaita-icon-theme" ,adwaita-icon-theme)
("baobab" ,baobab)
("font-cantarell" ,font-cantarell)
[... many packages omitted for brevity ...]
("gnome-keyring" ,gnome-keyring)
[... many packages omitted for brevity ...]
(synopsis "The GNU desktop environment")
(home-page "https://www.gnome.org/")
(description
"GNOME is the graphical desktop for GNU. It includes a wide variety of
applications for browsing the web, editing text and images, creating
documents and diagrams, playing media, scanning, and much more.")
(license license:gpl2+)))</code></pre><p>Apart from being a little long, this is <a href="https://www.gnu.org/software/guix/manual/en/html_node/Defining-Packages.html#Defining-Packages">just a normal package
definition</a>.
We can see that <code>gnome-keyring</code> is included in the list of
<code>propagated-inputs</code>. So, we need to create a replacement for the
<code>gnome</code> package that uses our <code>gnome-keyring-sans-ssh-agent</code> instead
of <code>gnome-keyring</code>. The following package definition accomplishes
that:</p><pre><code class="language-scheme">(define-public gnome-sans-ssh-agent
(package
(inherit gnome)
(name "gnome-sans-ssh-agent")
(propagated-inputs
(map (match-lambda
((name package)
(if (equal? name "gnome-keyring")
(list name gnome-keyring-sans-ssh-agent)
(list name package))))
(package-propagated-inputs gnome)))))</code></pre><p>As before, we use <code>inherit</code> to create a new copy of the <code>gnome</code>
package that overrides the original <code>name</code> and <code>propagated-inputs</code>
fields. Since Guix packages are just defined using good old scheme,
we can use existing language features like
<a href="https://www.gnu.org/software/guile/manual/en/html_node/List-Mapping.html#index-map"><code>map</code></a>
and
<a href="https://www.gnu.org/software/guile/manual/en/html_node/Pattern-Matching.html#Pattern-Matching"><code>match-lambda</code></a>
to manipulate the list of propagated inputs. The effect of the above
is to create a new package that is the same as the <code>gnome</code> package but
uses <code>gnome-keyring-sans-ssh-agent</code> instead of <code>gnome-keyring</code>.</p><p>Now that we have <code>gnome-sans-ssh-agent</code>, we can create a custom
<code><gnome-desktop-configuration></code> record and pass it to the
<code>gnome-desktop-service</code> procedure as follows:</p><pre><code class="language-scheme">(operating-system
...
(services (cons*
(gnome-desktop-service
#:config (gnome-desktop-configuration
(gnome-package gnome-sans-ssh-agent)))
%desktop-services)))</code></pre><h1>Wrapping It All Up</h1><p>Finally, you need to run the following commands as <code>root</code> to create
and boot into the new <a href="https://www.gnu.org/software/guix/manual/en/html_node/Invoking-guix-system.html">system
generation</a>
(replace <code>MY-CONFIG</code> with the path to the customized operating system
configuration file):</p><pre><code class="language-shell"># guix system reconfigure MY-CONFIG
# reboot</code></pre><p>After you log into GNOME, any time you need to use SSH, the stock SSH
agent from OpenSSH that you started in your <code>~/.xsession</code> file will be
used instead of the GNOME Keyring's SSH agent. It just works! Note
that it still works even if you select a non-GNOME desktop session
(like XFCE) at the SLiM login screen, since the <code>~/.xsession</code> is not
tied to any particular desktop session,</p><p>In the unfortunate event that something went wrong and things just
aren't working when you reboot, don't worry: with GuixSD, you can
safely roll back to the previous system generation via <a href="https://www.gnu.org/software/guix/manual/en/html_node/Using-the-Configuration-System.html#index-roll_002dback_002c-of-the-operating-system">the usual
mechanisms</a>.
For example, you can run this from the command line to roll back:</p><pre><code class="language-shell"># guix system roll-back
# reboot</code></pre><p>This is one of the great benefits that comes from the fact that <a href="https://www.gnu.org/software/guix/manual/en/html_node/Introduction.html#Introduction">Guix
follows the functional software deployment
model</a>.
However, note that because the <code>~/.xsession</code> file (like many files in
your home directory) is not managed by Guix, you must manually undo
the changes that you made to it in order to roll back fully.</p><h1>Conclusion</h1><p>I hope this helps give you some ideas for how you can customize your
own GuixSD system to make it exactly what you want it to be. Not only
can you customize your desktop session via your <code>~/.xsession</code> file,
but Guix also provides tools for you to modify any of the default
packages or services to suit your specific needs.</p><p>Happy hacking!</p><h1>Notices</h1><p><a href="http://creativecommons.org/publicdomain/zero/1.0/"><img src="https://licensebuttons.net/p/zero/1.0/88x31.png" alt="CC0" title="CC0 1.0
Universal" /></a></p><p>To the extent possible under law, Chris Marusich has waived all
copyright and related or neighboring rights to this article,
"Customize GuixSD: Use Stock SSH Agent Everywhere!". This work is
published from: United States.</p><p>The views expressed in this article are those of Chris Marusich and do
not necessarily reflect the views of his past, present, or future
employers.</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> is a transactional package
manager for the GNU system. The Guix System Distribution or GuixSD is
an advanced distribution of the GNU system that relies on GNU Guix and
<a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects the user's
freedom</a>.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. Guix uses low-level
mechanisms from the Nix package manager, except that packages are
defined as native <a href="https://www.gnu.org/software/guile">Guile</a> modules,
using extensions to the <a href="http://schemers.org">Scheme</a> language. GuixSD
offers a declarative approach to operating system configuration
management, and is highly customizable and hackable.</p><p>GuixSD can be used on an i686, x86_64 and armv7 machines. It is also
possible to use Guix on top of an already installed GNU/Linux system,
including on mips64el and aarch64.</p>https://guix.gnu.org/blog/2017/running-system-services-in-containers//Running system services in containersLudovic Courtès2017-04-14T14:45:00Z2017-04-14T14:45:00Z At FOSDEM, in the awesome
Guile track , I
briefly demoed a new experimental GuixSD feature as part my
talk on system services :
the ability to run system services in containers or “sandboxes”. This
post discusses the rationale, status, and implementation of this
feature. The problem Our computers run many programs that talk to the Internet, and the
Internet is an unsafe place as we all know—with states and assorted
organizations
collecting “zero-day exploits”
to exploit them as they see fit. One of the big tasks of operating
system distributions has been to keep track of known software
vulnerabilities and patch…<p>At FOSDEM, in the awesome
<a href="https://fosdem.org/2017/schedule/track/gnu_guile/">Guile track</a>, I
briefly demoed a new experimental GuixSD feature as part my
<a href="https://fosdem.org/2017/schedule/event/composingsystemservicesinguixsd/">talk on system services</a>:
the ability to run system services in containers or “sandboxes”. This
post discusses the rationale, status, and implementation of this
feature.</p><h4>The problem</h4><p>Our computers run many programs that talk to the Internet, and the
Internet is an unsafe place as we all know—with states and assorted
organizations
<a href="https://www.wired.com/2014/04/obama-zero-day/">collecting “zero-day exploits”</a>
to exploit them as they see fit. One of the big tasks of operating
system distributions has been to keep track of known software
vulnerabilities and patch their packages as soon as possible.</p><p>When we look closer, many vulnerabilities out there can be exploited
because of a combination of two major weaknesses of GNU/Linux and
similar Unix-like operating systems: lack of memory-safety in the C
language family, and
<a href="https://en.wikipedia.org/wiki/Ambient_authority">ambient authority</a> in
the operating system itself. The former leads to a huge class of bugs
that become security issues: buffer overflows, use-after-free, and so
on. The latter makes them more exploitable because processes have
access to many resources beyond those they really need.</p><p>Security-sensitive software is now increasingly written in memory-safe
languages, as is the case for Guix and GuixSD. Projects that have been
using C are even considering a complete rewrite,
<a href="https://lists.torproject.org/pipermail/tor-dev/2017-March/012088.html">as is the case for Tor</a>.
Of course the switch away from memory-unsafe languages won’t happen
overnight, but it’s good to see a consensus emerging.</p><p>The operating system side of things is less bright. Although the
<a href="https://en.wikipedia.org/wiki/Principle_of_least_authority">principle of least authority (POLA)</a>
has been well-known in operating system circles for a long time, it
remains foreign to Unix and GNU/Linux. Processes run with the full
authority of their user. On top of that, until recent changes to the
Linux kernel, resources were global and there was essentially a single
view of the file system, of the process hierarchy, and so on. So when a
remote-code-execution vulnerability affects a system service—like
<a href="https://bugs.bitlbee.org/ticket/1281">in the BitlBee instant messaging gateway (CVE-2016-10188)</a>
running on my laptop—an attacker could potentially do a lot on your
machine.</p><p>Fortunately, many daemons have built-in mechanisms to work around this
operating system defect. For instance,
<a href="https://github.com/bitlbee/bitlbee/blob/master/unix.c#L155">BitlBee</a>,
and
<a href="https://gitweb.torproject.org/tor.git/tree/src/or/config.c#n1338">Tor</a>
can be told to switch to a separate unprivileged user,
<a href="https://github.com/lathiat/avahi/blob/master/avahi-daemon/chroot.c"><code>avahi-daemon</code></a>
and
<a href="https://github.com/ntp-project/ntp/blob/stable/ntpd/ntpd.c#L1000"><code>ntpd</code></a>
can do that and also change root. These techniques do reduce the
privileges of those processes, but they are still imperfect and <em>ad
hoc</em>.</p><h4>Increasing process isolation with containers</h4><p>The optimal solution to this problem would be to honor POLA in the first
place. As an example, the venerable GNU/Hurd is a
<a href="https://en.wikipedia.org/wiki/Capability-based_security">capability-based operating system</a>.
Thus, GNU/Hurd has supported fine-grained virtualization from the start:
a newly-created process can be given a capability to its own <code>proc</code>
server (which implements the POSIX notion of processes), to a specific
TCP/IP server, etc. In addition, its POSIX personality offers
interesting extensions, such as the fact that processes run with the
authority of
<a href="https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mach/hurd/getuid.c;h=ff95fd58b8a9819fd0525d42ed8c3d85dbb6cb99;hb=HEAD#l42"><em>zero</em></a>
or more UIDs. For instance, the Hurd’s
<a href="https://git.savannah.gnu.org/cgit/hurd/hurd.git/tree/utils/login.c"><code>login</code> program</a>
starts off with zero UIDs and gains a UID when someone has been
authenticated.</p><p>Back to GNU/Linux,
<a href="http://man7.org/linux/man-pages/man7/namespaces.7.html">“namespaces”</a>
have been introduced as a way to retrofit per-process views of the
system resources, and thus improve isolation among processes. Each
process can run in a separate namespace and thus have a different view
of the file system, process tree, and so on (a process running in
separate namespaces is often referred to as a “container”, although that
term is sometimes used to denote much larger tooling and practices built
around namespaces.) Why not use that to better isolate system services?</p><p>Apparently this idea has been floating around. systemd has been
<a href="https://lwn.net/Articles/706025/">considering to extend its “unit files”</a>
to include directives instructing systemd to run daemons in separate
namespaces. GuixSD uses
<a href="https://www.gnu.org/software/shepherd">the Shepherd</a> instead of
systemd, but running system services in separate namespaces is something
we had been considering for a while.</p><p>In fact, adding the ability to run system services in containers was a
low-hanging fruit: we already had
<a href="https://www.gnu.org/software/guix/news/container-provisioning-with-guix.html"><code>call-with-container</code></a>
to run code in containers, so all we needed to do was to
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=63302a4e55241a41eab4c21d7af9fbd0d5817459">provide a containerized service starter</a>
that uses <code>call-with-container</code>.</p><p>The Shepherd itself remains unaware of namespaces, it simply ends up
calling
<a href="https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/build/shepherd.scm#n108"><code>make-forkexec-constructor/container</code></a>
instead of
<a href="https://www.gnu.org/software/shepherd/manual/en/html_node/Service-De_002d-and-Constructors.html#index-make_002dforkexec_002dconstructor"><code>make-forkexec-constructor</code></a>
and that’s it. The changes to the service definitions of
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=a062b6ca99ad61c9df473fe49a93d69f9698c59d">BitlBee</a>
and
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=ee295346ce81c276ffb4ee34cc6f5b134b415097">Tor</a>
are minimal. The end result, for Tor, looks like this:</p><pre><code class="language-scheme">(let ((torrc (tor-configuration->torrc config)))
(with-imported-modules (source-module-closure
'((gnu build shepherd)
(gnu system file-systems)))
(list (shepherd-service
(provision '(tor))
(requirement '(user-processes loopback syslogd))
(modules '((gnu build shepherd)
(gnu system file-systems)))
(start #~(make-forkexec-constructor/container
(list #$(file-append tor "/bin/tor") "-f" #$torrc)
#:mappings (list (file-system-mapping
(source "/var/lib/tor")
(target source)
(writable? #t))
(file-system-mapping
(source "/dev/log") ;for syslog
(target source)))))
(stop #~(make-kill-destructor))
(documentation "Run the Tor anonymous network overlay.")))))</code></pre><p>The
<a href="https://www.gnu.org/software/guix/manual/en/html_node/G_002dExpressions.html#index-with_002dimported_002dmodules"><code>with-imported-modules</code></a>
form above instructs Guix to <em>import</em> our <code>(gnu build shepherd)</code>
library, which provides <code>make-forkexec-constructor/container</code>, into
PID 1. The <code>start</code> method of the service specifies the command to start
the daemon, as well as file systems to map in its mount name space
(“bind mounts”). Here all we need is write access to <code>/var/lib/tor</code> and
to <code>/dev/log</code> (for logging <em>via</em> syslogd). In addition to these two
mappings, <code>make-forkexec-constructor/container</code> automatically adds
<code>/gnu/store</code> and a bunch of files in <code>/etc</code> as we will see below.</p><h4>Containerized services in action</h4><p>So what do these containerized services look like when they’re running?
When we run
<a href="https://www.gnu.org/software/shepherd/manual/en/html_node/Invoking-herd.html"><code>herd status bitblee</code></a>,
disappointingly, we don’t see anything special:</p><pre><code>charlie@guixsd ~$ sudo herd status bitlbee
Status of bitlbee:
It is started.
Running value is 487.
It is enabled.
Provides (bitlbee).
Requires (user-processes networking).
Conflicts with ().
Will be respawned.
charlie@guixsd ~$ ps -f 487
UID PID PPID C STIME TTY STAT TIME CMD
bitlbee 487 1 0 Apr11 ? Ss 0:00 /gnu/store/pm05bfywrj2k699qbxpjjqfyfk3grz2i-bitlbee-3.5.1/sbin/bitlbee -n -F -u bitlbee -c /gnu/store/y4jfxya56i1hl9z0a2h4hdar2wm</code></pre><p>Again this is because the Shepherd has no idea what a namespace is, so
it just displays the daemon’s PID in the global namespace, <code>487</code>. The
process is running as user <code>bitlbee</code>, as requested by the <code>-u bitlbee</code>
command-line option.</p><p>We can invoke
<a href="http://man7.org/linux/man-pages/man1/nsenter.1.html"><code>nsenter</code></a> and
take a look at what the BitlBee process “sees” in its namespace:</p><pre><code>charlie@guixsd ~$ sudo nsenter -t 487 -m -p -i -u $(readlink -f $(type -P bash))
root@guixsd /# echo /*
/dev /etc /gnu /proc /tmp /var
root@guixsd /# echo /proc/[0-9]*
/proc/1 /proc/5
root@guixsd /# read line < /proc/1/cmdline
root@guixsd /# echo $line
/gnu/store/pm05bfywrj2k699qbxpjjqfyfk3grz2i-bitlbee-3.5.1/sbin/bitlbee-n-F-ubitlbee-c/gnu/store/y4jfxya56i1hl9z0a2h4hdar2wmivgbl-bitlbee.conf
root@guixsd /# echo /etc/*
/etc/hosts /etc/nsswitch.conf /etc/passwd /etc/resolv.conf /etc/services
root@guixsd /# echo /var/*
/var/lib /var/run
root@guixsd /# echo /var/lib/*
/var/lib/bitlbee
root@guixsd /# echo /var/run/*
/var/run/bitlbee.pid /var/run/nscd</code></pre><p>There’s no <code>/home</code> and generally very little in BitlBee’s mount
namespace. Notably, the namespace lacks <code>/run/setuid-programs</code>, which
is where
<a href="https://www.gnu.org/software/guix/manual/en/html_node/Setuid-Programs.html">setuid programs</a>
live in GuixSD. Its <code>/etc</code> directory contains the minimal set of files
needed for proper operation rather than the complete <code>/etc</code> of the host.
<code>/var</code> contains nothing but BitlBee’s own state files, as well as the
socket to libc’s name service cache daemon (<code>nscd</code>), which runs in the
host system and performs name lookups on behalf of applications.</p><p>As can be seen in <code>/proc</code>, there’s only a couple of processes in there
and “PID 1” in that namespace is the <code>bitlbee</code> daemon. Finally, the
<code>/tmp</code> directory is a private tmpfs:</p><pre><code>root@guixsd /# : > /tmp/hello-bitlbee
root@guixsd /# echo /tmp/*
/tmp/hello-bitlbee
root@guixsd /# exit
charlie@guixsd ~$ ls /tmp/*bitlbee
ls: cannot access '/tmp/*bitlbee': No such file or directory</code></pre><p>Our <code>bitlbee</code> process runs in a separate mount, PID, and IPC namespace,
but it runs in the global user namespace. The reason for this is that
we want the <code>-u bitlbee</code> option (which instructs <code>bitlbee</code> to setuid to
an unprivileged user at startup) to work as expected. It also shares
the network namespace because obviously it needs to access the network.</p><p>A nice side-effect of these fully-specified execution environments for
services is that it makes them more likely to behave in a reproducible
fashion across machines—just like fully-specified build environments
<a href="https://www.gnu.org/software/guix/news/reproducible-builds-a-means-to-an-end.html">help achieve reproducible builds</a>.</p><h4>Conclusion</h4><p>GuixSD <code>master</code> and its upcoming release include this feature and a
couple of containerized services, and it works like a charm! Yet, there
are still open questions as to the way forward.</p><p>First, we only looked at “simple” services so far, with simple static
file system mappings. Good candidates for increased isolation are HTTP
servers such as NGINX. However, for these, it’s more difficult to
determine the set of file system mappings that must be made. GuixSD has
the advantage that it knows
<a href="https://www.gnu.org/software/guix/manual/en/html_node/Web-Services.html">how NGINX is configured</a>
and could potentially derive file system mappings from that information.
Getting it right may be trickier than it seems, though, so this is
something we’ll have to investigate.</p><p>Another open question is how the service isolation work should be split
between the distro, the init system, and the upstream service author.
Authors of daemons already do part of the work <em>via</em> <code>setuid</code> and
sometimes <code>chroot</code>. Going beyond that would often hamper portability
(the namespace interface is specific to the kernel Linux) or even
functionality if the daemon ends up lacking access to resources it
needs.</p><p>The init system alone also lacks information to decide what goes into
the namespaces of the service. For instance, neither the upstream
author nor the init system “knows” whether the distro is running <code>nscd</code>
and thus they cannot tell whether the <code>nscd</code> socket should be
bind-mounted in the service’s namespace. A similar issue is that of
D-Bus policy files discussed in
<a href="https://lwn.net/Articles/706025/">this LWN article</a>. Moving D-Bus
functionality into the init system itself to solve this problem, as the
article suggests, seems questionable, notably because it would add more
code to this critical process. Instead, on GuixSD, a service author can
make the right policy files available in the sandbox; in fact, GuixSD
already knows which policy files are needed thanks to its service
framework so we might even be able to automate it.</p><p>At this point it seems that tight integration between the distro and the
init system is the best way to precisely define system service
sandboxes. GuixSD’s
<a href="https://www.gnu.org/software/guix/manual/en/html_node/Using-the-Configuration-System.html#System-Services">declarative approach to system services</a>
along with tight Shepherd integration help a lot here, but it remains to
be seen how difficult it is to create sandboxes for complex system
services such as NGINX.</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> is a transactional package
manager for the GNU system. The Guix System Distribution or GuixSD is
an advanced distribution of the GNU system that relies on GNU Guix and
<a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects the user's
freedom</a>.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. Guix uses low-level
mechanisms from the Nix package manager, except that packages are
defined as native <a href="https://www.gnu.org/software/guile">Guile</a> modules,
using extensions to the <a href="http://schemers.org">Scheme</a> language. GuixSD
offers a declarative approach to operating system configuration
management, and is highly customizable and hackable.</p><p>GuixSD can be used on an i686 or x86_64 machine. It is also possible to
use Guix on top of an already installed GNU/Linux system, including on
mips64el, armv7, and aarch64.</p>https://guix.gnu.org/blog/2015/service-composition-in-guixsd//Service composition in GuixSDLudovic Courtès2015-11-19T00:00:00+01002015-11-19T00:00:00+0100 GuixSD provides a declarative, stateless approach to operating system configuration management. In this context, the mechanism offered to select and compose system services is a crucial one. This post presents the new service framework introduced in the 0.9.0 version of GNU Guix. Declarative Configuration Management GuixSD is not like your parents’ distro. Instead of fiddling with configuration files all around, or running commands that do so as a side effect, the system administrator declares what the system will be like. This takes the form of an …<div><p>GuixSD provides a declarative, stateless approach to operating system configuration management. In this context, the mechanism offered to select and compose system services is a crucial one. This post presents the new service framework introduced in the <a href="/news/gnu-guix-090-released.html">0.9.0 version</a> of GNU Guix.<br /></p><h4>Declarative Configuration Management</h4><p>GuixSD is not like your parents’ distro. Instead of fiddling with configuration files all around, or running commands that do so as a side effect, the system administrator <em>declares</em> what the system will be like. This takes the form of an <a href="https://www.gnu.org/software/guix/manual/en/html_node/Using-the-Configuration-System.html">operating-system declaration</a>, which specifies all the details: file systems, user accounts, locale, timezone, system services, etc.<br /></p><p>If you’re familiar with it, this may remind you of what deployment tools like Ansible and Puppet provide. There is an important difference though: GuixSD takes a stateless—or “purely functional”—approach. This means that instantiating the system with <a href="https://www.gnu.org/software/guix/manual/en/html_node/Invoking-guix-system.html">guix system</a> always produces the same result, without modifying the current system state. This is what makes it possible to test new system configurations, roll-back to previous ones, and so on. The <a href="https://www.gnu.org/software/guix/manual/en/html_node/Invoking-guix-system.html">guix system</a> command allows system configurations to be instantiated on the bare metal, in virtual machines, or in <a href="/news/container-provisioning-with-guix.html">containers</a>, which makes it easy to test them.<br /></p><p>In GuixSD, operating-system declarations are first-class objects in the <a href="https://www.gnu.org/software/guile/">host language</a>. They can be inspected at the REPL:<br /></p><div class="example"><pre>scheme@(guile-user)> ,use (gnu)
scheme@(guile-user)> (define os (load "os-config.scm"))
scheme@(guile-user)> (operating-system-kernel os)
$1 = #<package linux-libre-4.2.6 gnu/packages/linux.scm:279 2ea90c0>
scheme@(guile-user)> (length (operating-system-user-services os))
$2 = 30
scheme@(guile-user)> (map user-account-name (operating-system-users os))
$3 = ("alice" "nobody" "root")
</pre></div><p>It is also possible to write functions that take or return OS configurations. For instance, the <a href="http://git.savannah.gnu.org/cgit/guix.git/tree/gnu/system/vm.scm#n382">virtualized-operating-system function</a> returns a variant of the given OS where the set of file systems and the initrd are changed so that the resulting OS can be used in a lightweight virtual machine environment. Likewise for <a href="http://git.savannah.gnu.org/cgit/guix.git/tree/gnu/system/linux-container.scm#n50">containerized-operating-system</a>.<br /></p><h4>Services Beyond Daemons</h4><p>System services are specified in the services field of operating-system declarations, which is a list of service objects. As a user, we want to be able to ideally add one line specifying the <a href="https://www.gnu.org/software/guix/manual/en/html_node/Services.html">system service</a> we want to add, possibly with several instances of a service, and have GuixSD do the right thing.<br /></p><p>Before 0.9.0, GuixSD had a narrow definition of what a “system service” is. Each service in the operating-system configuration had to map to exactly one dmd service—<a href="https://www.gnu.org/software/dmd">GNU dmd</a> is the init system of GuixSD. This would work well in many cases: an SSH server or a log-in daemon is indeed a service that dmd has to take care of, even a file system mount is an operation that can be usefully inserted into dmd’s service dependency graph.<br /></p><p>However, this simple mapping failed to capture more complex service composition patterns. A striking example is “super-daemons”—daemons that can spawn other daemons, such as dbus-daemon or inetd. From the user viewpoint, it does not matter whether a daemon is started by dmd, or by dbus-daemon, or by inetd; this should be transparent. If it’s a D-Bus service, then dbus-daemon’s configuration file should be told about the service; if it’s an inetd service, then inetd.conf should be augmented accordingly; if it’s a dmd service, information on how to start and stop it should go to dmd’s configuration file. Unfortunately, the pre-0.9.0 services could not express such things.<br /></p><p>Worse, this approach did not capture the more general pattern of <em>service extension</em>. In the examples above, the super-daemons are effectively <em>extended</em> by other services that rely on them. But there are many cases where services are similarly extended: <a href="https://wiki.gentoo.org/wiki/Project:Eudev">eudev</a> can be passed new device rules, <a href="http://www.freedesktop.org/wiki/Software/polkit/">polkit</a> can be extended with new rules and actions, the <a href="http://www.linux-pam.org/">Pluggable authentication module system (PAM)</a> can be extended with new services, and so on. At that point it was clear that GuixSD’s naive approach wouldn’t scale.<br /></p><h4>Composing System Services</h4><p>The lesson learned from these observations is that system services <em>extend</em> each other in various way. The new <a href="https://www.gnu.org/software/guix/manual/en/html_node/Service-Composition.html">service composition framework</a> is built around this model: “system services”, broadly defined, can extend each other, and services and their “extends” relationships form a graph. The root of the graph is the operating system itself.<br /></p><p>We can see that this pattern applies to services that are not daemons. PAM is one such example. Accounts are another example: GuixSD provides an “account service” that can be extended with new user accounts or groups; for example, the <a href="https://www.gnu.org/software/guix/manual/en/html_node/Networking-Services.html#index-ntp_002dservice">Network time protocol (NTP) daemon</a> needs to run under the unprivileged “ntp” user, so the NTP service extends the account service with an “ntp” user account. Likewise, the “/etc” service can be extended with new files to be added to /etc; the “setuid” service can be extended with new programs to be made setuid-root. <a href="https://www.gnu.org/software/guix/manual/en/html_node/Service-Reference.html">See the manual</a> for more examples.<br /></p><p>The nice thing is that composition of services is made <em>explicit</em>: extensions can only happen where explicit extension relationships have been <a href="https://www.gnu.org/software/guix/manual/en/html_node/Service-Types-and-Services.html">declared</a>. By looking at the extension graph, users can see how services fit together. The <a href="https://www.gnu.org/software/guix/manual/en/html_node/Invoking-guix-system.html#system_002dextension_002dgraph">guix system extension-graph</a> command, for instance, takes an operating-system declaration and renders the extension graph in the Graphviz format, making it easy to inspect the OS configuration structure.<br /></p><p>The API makes it easy to see how services contributed to a specific service’s configuration. For instance, the following expression shows the PAM service as extended by other declared services:<br /></p><pre><code class="language-scheme">(fold-services (operating-system-services os)
#:target-type pam-root-service-type)
</code></pre><p>The result is a service object whose value is a list of pam-service objects. Likewise, the following expression returns the /etc service, whose value is a list of entries to be added to /etc:<br /></p><pre><code class="language-scheme">(fold-services (operating-system-services os)
#:target-type etc-service-type)
</code></pre><p>This contrasts with the approach taken by <a href="http://nixos.org/">NixOS</a>, GuixSD’s cousin, and described in this <a href="https://nixos.org/~eelco/pubs/nixos-jfp-final.pdf">2010 paper</a>. In NixOS, the whole system configuration is described in an “attribute set”—a list of key/value associations, similar to JavaScript objects or Python dictionaries. Each NixOS service is passed the whole system configuration, allowing it to inspect and change any part of it.<br /></p><p>This form of <a href="https://en.wikipedia.org/wiki/Ambient_authority">ambient authority</a> gives a lot of flexibility, but it makes it harder to reason about service composition—all a service implementation does is inspect, add, or modify attributes of the global configuration, which may or may not affect other services. The use of a loose key/value dictionary also prevents good error reporting; for instance, a typo in a service name may go undetected. Lastly, NixOS services are enabled by writing service.enable = true stanzas, which leads to complications for services that may have several instances, each with its own configuration.<br /></p><h4>Wrapping Up</h4><p>The new <a href="https://www.gnu.org/software/guix/manual/en/html_node/Service-Composition.html">service composition framework</a> in GuixSD 0.9.0 addresses shortcomings found in previous versions of GuixSD. It simplifies operating-system declarations for users, and provides a highly extensible framework that clearly exposes the way services are composed.<br /></p><p>This new framework has already allowed us to integrate <a href="https://www.gnu.org/software/guix/manual/en/html_node/Desktop-Services.html">Freedesktop and GNOME services</a> in a convenient way. We hope it will prove fruitful as we address other types of services, such as Web services.<br /></p><h4>About GNU Guix</h4><p><a href="http://www.gnu.org/software/guix">GNU Guix</a> is a functional package manager for the GNU system. The Guix System Distribution or GuixSD is an advanced distribution of the GNU system that relies on GNU Guix and <a href="http://www.gnu.org/distros/free-system-distribution-guidelines.html">respects the user's freedom</a>.<br /></p><p>In addition to standard package management features, Guix supports transactional upgrades and roll-backs, unprivileged package management, per-user profiles, and garbage collection. Guix uses low-level mechanisms from the Nix package manager, except that packages are defined as native <a href="http://www.gnu.org/software/guile">Guile</a> modules, using extensions to the <a href="http://schemers.org">Scheme</a> language. GuixSD offers a declarative approach to operating system configuration management, and is highly customizable and hackable.<br /></p><p>GuixSD can be used on an i686 or x86_64 machine. It is also possible to use Guix on top of an already installed GNU/Linux system, including on mips64el and armv7.<br /></p></div>https://guix.gnu.org/blog/2014/gnu-dmd-02-released//GNU dmd 0.2 releasedLudovic Courtès2014-07-08T00:00:00+02002014-07-08T00:00:00+0200 GNU dmd 0.2 has been released . It provides new features such as the ability to load new definitions for existing services, as well as bug fixes and an improved manual . GNU dmd is a dependency-based service manager meant to be used as the init system in GNU. It is written in Guile Scheme. …<div><p><a href="http://www.gnu.org/software/dmd">GNU dmd</a> 0.2 has been <a href="http://lists.gnu.org/archive/html/guix-devel/2014-07/msg00039.html">released</a>. It provides new features such as the ability to load new definitions for existing services, as well as bug fixes and an improved <a href="http://www.gnu.org/software/dmd/manual">manual</a>.<br /></p><p>GNU dmd is a dependency-based service manager meant to be used as the init system in GNU. It is written in Guile Scheme.<br /></p></div>https://guix.gnu.org/blog/2013/gnu-dmd-01-released//GNU dmd 0.1 releasedLudovic Courtès2013-12-02T00:00:00+01002013-12-02T00:00:00+0100 GNU dmd 0.1 has been released , providing many improvements and bug fixes. GNU dmd is a dependency-based service manager meant to be used as the init system in GNU. It is written in Guile Scheme. …<div><p><a href="http://www.gnu.org/software/dmd">GNU dmd</a> 0.1 has been <a href="https://lists.gnu.org/archive/html/guix-devel/2013-12/msg00014.html">released</a>, providing many improvements and bug fixes.<br /></p><p>GNU dmd is a dependency-based service manager meant to be used as the init system in GNU. It is written in Guile Scheme.<br /></p></div>