[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

System configuration with Guix

From: Ludovic Courtès
Subject: System configuration with Guix
Date: Tue, 10 Dec 2013 00:33:07 +0100
User-agent: Gnus/5.130007 (Ma Gnus v0.7) Emacs/24.3 (gnu/linux)


Commit 033adfe in Guix adds the (gnu system) Guile module, which is a
first stab at providing a declarative system configuration mechanism.
This is inspired by NixOS, and is also probably familiar to users of
Puppet or Chef.

Currently it’s only used to build a QEMU image, but in the
not-too-distant future it will be used to build installer images, and
actual system images.

Below is the doc I’ve written to describe the spirit of that approach,
and part of its implementation.

Comments welcome!


6.6 System Configuration

_This section documents work-in-progress.  As such it may be incomplete,
outdated, or open to discussions.  Please discuss it on

   The GNU system supports a consistent whole-system configuration
mechanism.  By that we mean that all aspects of the global system
configuration—such as the available system services, timezone and locale
settings, user accounts—are configured in a single place.  Such a
"system configuration" can be "instantiated"—i.e., effected.

   This section describes this mechanism.  First we focus on the system
administrator’s viewpoint—explaining how the system is configured and
instantiated.  Then we show how this mechanism can be extended, for
instance to support new system services.

* Menu:

* Using the Configuration System::      Customizing your GNU system.
* Defining Services::                   Adding new service definitions.

6.6.1 Using the Configuration System

The operating system is configured by filling in an ‘operating-system’
structure, as defined by the ‘(gnu system)’ module.  A simple setup,
with the default system services, the default Linux-Libre kernel,
initial RAM disk, and boot loader looks like this:

     (use-modules (gnu system)
                  (gnu system shadow)   ; for 'user-account'
                  (gnu system service)  ; for 'lsh-service'
                  (gnu packages base)   ; Coreutils, grep, etc.
                  (gnu packages bash)   ; Bash
                  (gnu packages system) ; dmd, Inetutils
                  (gnu packages zile)   ; Zile
                  (gnu packages less)   ; less
                  (gnu packages guile)  ; Guile
                  (gnu packages linux)) ; procps, psmisc

     (define %komputilo
        (host-name "komputilo")
        (timezone "Europe/Paris")
        (locale "fr_FR.UTF-8")
        (users (list (user-account
                      (name "alice")
                      (password "")
                      (uid 1000) (gid 100)
                      (comment "Bob's sister")
                      (home-directory "/home/alice"))))
        (packages (list coreutils bash guile-2.0
                        guix dmd
                        findutils grep sed
                        procps psmisc
                        zile less))
        (services (cons (lsh-service #:port 2222 #:allow-root-login? #t)

   This example should be self-describing.  The ‘packages’ field lists
packages provides by the various ‘(gnu packages ...)’ modules above;
these are the packages that will be globally visible on the system, for
all user accounts, in addition to the per-user profiles (*note Invoking
guix package::).

   The ‘services’ field lists "system services" to be made available
when the system starts.  The %STANDARD-SERVICES list, from the ‘(gnu
system)’ module, provides the basic services one would expect from a GNU
system: a login service (mingetty) on each tty, syslogd, libc’s name
service cache daemon (nscd), etc.

   The ‘operating-system’ declaration above specifies that, in addition
to those services, we want the ‘lshd’ secure shell daemon listening on
port 2222, and allowing remote ‘root’ logins (*note (lsh)Invoking
lshd::).  Under the hood, ‘lsh-service’ arranges so that ‘lshd’ is
started with the right command-line options, possibly with supporting
configuration files generated as needed (*note Defining Services::).

   Assuming the above snippet is stored in the ‘my-system-config.scm’
file, the (yet unwritten!)  ‘guix system --boot my-system-config.scm’
command instantiates that configuration, and makes it the default GRUB
boot entry.  The normal way to change the system’s configuration is by
updating this file and re-running the ‘guix system’ command.

   At the Scheme level, the bulk of an ‘operating-system’ declaration is
instantiated with the following monadic procedure (*note The Store

 -- Monadic Procedure: operating-system-derivation os
     Return a derivation that builds OS, an ‘operating-system’ object
     (*note Derivations::).

     The output of the derivation is a single directory that refers to
     all the packages, configuration files, and other supporting files
     needed to instantiate OS.

   One of the advantages of putting all the system configuration under
the control of Guix is that it makes it possible to roll-back to a
previous system instantiation, should anything go wrong with the new
one.  Another one is that it makes it easy to replicate the very same
configuration across different machines, or at different points in time,
without having to resort to additional administration tools layered on
top of the system’s own tools.

6.6.2 Defining Services

The ‘(gnu system dmd)’ module defines several procedures that allow
users to declare the operating system’s services (*note Using the
Configuration System::).  These procedures are _monadic
procedures_—i.e., procedures that return a monadic value in the store
monad (*note The Store Monad::).  Examples of such procedures include:

     return the definition of a service that runs ‘mingetty’ to offer a
     login service on the given console tty;

     return a definition for libc’s name service cache daemon (nscd);

     return a definition for a service that runs ‘guix-daemon’ (*note
     Invoking guix-daemon::).

   The monadic value returned by those procedures is a "service
definition"—a structure as returned by the ‘service’ form.  Service
definitions specifies the inputs the service depends on, and an
expression to start and stop the service.  Behind the scenes, service
definitions are “translated” into the form suitable for the
configuration file of dmd, the init system (*note (dmd)Services::).

   As an example, here is what the ‘nscd-service’ procedure looks like:

     (define (nscd-service)
       (mlet %store-monad ((nscd (package-file glibc "sbin/nscd")))
         (return (service
                  (documentation "Run libc's name service cache daemon.")
                  (provision '(nscd))
                  (start `(make-forkexec-constructor ,nscd "-f" "/dev/null"
                  (stop  `(make-kill-destructor))

                  (respawn? #f)
                  (inputs `(("glibc" ,glibc)))))))

The ‘inputs’ field specifies that this service depends on the GLIBC
package—the package that contains the ‘nscd’ program.  The ‘start’ and
‘stop’ fields are expressions that make use of dmd’s facilities to start
and stop processes (*note (dmd)Service De- and Constructors::).  The
‘provision’ field specifies the name under which this service is known
to dmd, and ‘documentation’ specifies on-line documentation.  Thus, the
commands ‘deco start ncsd’, ‘deco stop nscd’, and ‘deco doc nscd’ will
do what you would expect (*note (dmd)Invoking deco::).

Attachment: pgpEtRC9Tap7o.pgp
Description: PGP signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]