The operating system is configured by providing an
operating-system declaration in a file that can then be passed to
guix system command (see Invoking guix system). A
simple setup, with the default system services, the default Linux-Libre
kernel, initial RAM disk, and boot loader looks like this:
;; This is an operating system configuration template ;; for a "bare bones" setup, with no X11 display server. (use-modules (gnu)) (use-service-modules networking ssh) (use-package-modules admin) (operating-system (host-name "komputilo") (timezone "Europe/Berlin") (locale "en_US.utf8") ;; Assuming /dev/sdX is the target hard disk, and "my-root" is ;; the label of the target root file system. (bootloader (grub-configuration (device "/dev/sdX"))) (file-systems (cons (file-system (device "my-root") (title 'label) (mount-point "/") (type "ext4")) %base-file-systems)) ;; This is where user accounts are specified. The "root" ;; account is implicit, and is initially created with the ;; empty password. (users (cons (user-account (name "alice") (comment "Bob's sister") (group "users") ;; Adding the account to the "wheel" group ;; makes it a sudoer. Adding it to "audio" ;; and "video" allows the user to play sound ;; and access the webcam. (supplementary-groups '("wheel" "audio" "video")) (home-directory "/home/alice")) %base-user-accounts)) ;; Globally-installed packages. (packages (cons tcpdump %base-packages)) ;; Add services to the baseline: a DHCP client and ;; an SSH server. (services (cons* (dhcp-client-service) (service openssh-service-type (openssh-configuration (port-number 2222))) %base-services)))
This example should be self-describing. Some of the fields defined
above, such as
bootloader, are mandatory.
Others, such as
services, can be omitted, in
which case they get a default value.
Below we discuss the effect of some of the most important fields
(see operating-system Reference, for details about all the available
fields), and how to instantiate the operating system using
packages field lists packages that will be globally visible
on the system, for all user accounts—i.e., in every user’s
environment variable—in addition to the per-user profiles
(see Invoking guix package). The %base-packages variable
provides all the tools one would expect for basic user and administrator
tasks—including the GNU Core Utilities, the GNU Networking Utilities,
the GNU Zile lightweight text editor,
etc. The example above adds tcpdump to those, taken from the
packages admin) module (see Package Modules). The
(list package output) syntax can be used to add a specific output
of a package:
(use-modules (gnu packages)) (use-modules (gnu packages dns)) (operating-system ;; ... (packages (cons (list bind "utils") %base-packages)))
Referring to packages by variable name, like tcpdump above, has
the advantage of being unambiguous; it also allows typos and such to be
diagnosed right away as “unbound variables”. The downside is that one
needs to know which module defines which package, and to augment the
use-package-modules line accordingly. To avoid that, one can use
specification->package procedure of the
module, which returns the best package for a given name or name and
(use-modules (gnu packages)) (operating-system ;; ... (packages (append (map specification->package '("tcpdump" "htop" "firstname.lastname@example.org")) %base-packages)))
services field lists system services to be made
available when the system starts (see Services).
operating-system declaration above specifies that, in
addition to the basic services, we want the
lshd secure shell
daemon listening on port 2222 (see
lsh-service). 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 (see Defining Services).
Occasionally, instead of using the base services as is, you will want to
customize them. To do this, use
modify-services) to modify the list.
For example, suppose you want to modify
guix-daemon and Mingetty
(the console log-in) in the %base-services list (see
%base-services). To do that, you can write the
following in your operating system declaration:
(define %my-services ;; My very own list of services. (modify-services %base-services (guix-service-type config => (guix-configuration (inherit config) (use-substitutes? #f) (extra-options '("--gc-keep-derivations")))) (mingetty-service-type config => (mingetty-configuration (inherit config))))) (operating-system ;; … (services %my-services))
This changes the configuration—i.e., the service parameters—of the
guix-service-type instance, and that of all the
mingetty-service-type instances in the %base-services list.
Observe how this is accomplished: first, we arrange for the original
configuration to be bound to the identifier
config in the
body, and then we write the body so that it evaluates to the
desired configuration. In particular, notice how we use
to create a new configuration which has the same values as the old
configuration, but with a few modifications.
The configuration for a typical “desktop” usage, with an encrypted root partition, the X11 display server, GNOME and Xfce (users can choose which of these desktop environments to use at the log-in screen by pressing F1), network management, power management, and more, would look like this:
;; This is an operating system configuration template ;; for a "desktop" setup with GNOME and Xfce where the ;; root partition is encrypted with LUKS. (use-modules (gnu) (gnu system nss)) (use-service-modules desktop) (use-package-modules certs gnome) (operating-system (host-name "antelope") (timezone "Europe/Paris") (locale "en_US.utf8") ;; Assuming /dev/sdX is the target hard disk, and "my-root" ;; is the label of the target root file system. (bootloader (grub-configuration (device "/dev/sdX"))) ;; Specify a mapped device for the encrypted root partition. ;; The UUID is that returned by 'cryptsetup luksUUID'. (mapped-devices (list (mapped-device (source (uuid "12345678-1234-1234-1234-123456789abc")) (target "the-root-device") (type luks-device-mapping)))) (file-systems (cons (file-system (device "my-root") (title 'label) (mount-point "/") (type "ext4") (dependencies mapped-devices)) %base-file-systems)) (users (cons (user-account (name "bob") (comment "Alice's brother") (group "users") (supplementary-groups '("wheel" "netdev" "audio" "video")) (home-directory "/home/bob")) %base-user-accounts)) ;; This is where we specify system-wide packages. (packages (cons* nss-certs ;for HTTPS access gvfs ;for user mounts %base-packages)) ;; Add GNOME and/or Xfce---we can choose at the log-in ;; screen with F1. Use the "desktop" services, which ;; include the X11 log-in service, networking with Wicd, ;; and more. (services (cons* (gnome-desktop-service) (xfce-desktop-service) %desktop-services)) ;; Allow resolution of '.local' host names with mDNS. (name-service-switch %mdns-host-lookup-nss))
A graphical UEFI system with a choice of lightweight window managers instead of full-blown desktop environments would look like this:
;; This is an operating system configuration template ;; for a "desktop" setup without full-blown desktop ;; environments. (use-modules (gnu) (gnu system nss)) (use-service-modules desktop) (use-package-modules bootloaders certs ratpoison suckless wm) (operating-system (host-name "antelope") (timezone "Europe/Paris") (locale "en_US.utf8") ;; Use the UEFI variant of GRUB with the EFI System ;; Partition on /dev/sda1. (bootloader (grub-configuration (grub grub-efi) (device "/dev/sda1"))) ;; Assume the target root file system is labelled "my-root". (file-systems (cons* (file-system (device "my-root") (title 'label) (mount-point "/") (type "ext4")) (file-system ;; Specify partition here since FAT ;; labels are currently unsupported. (device "/dev/sda1") (mount-point "/boot/efi") (type "vfat")) %base-file-systems)) (users (cons (user-account (name "alice") (comment "Bob's sister") (group "users") (supplementary-groups '("wheel" "netdev" "audio" "video")) (home-directory "/home/alice")) %base-user-accounts)) ;; Add a bunch of window managers; we can choose one at ;; the log-in screen with F1. (packages (cons* ratpoison i3-wm i3status dmenu ;window managers nss-certs ;for HTTPS access %base-packages)) ;; Use the "desktop" services, which include the X11 ;; log-in service, networking with Wicd, and more. (services %desktop-services) ;; Allow resolution of '.local' host names with mDNS. (name-service-switch %mdns-host-lookup-nss))
See Desktop Services, for the exact list of services provided by
%desktop-services. See X.509 Certificates, for background
information about the
nss-certs package that is used here.
Again, %desktop-services is just a list of service objects. If you want to remove services from there, you can do so using the procedures for list filtering (see SRFI-1 Filtering and Partitioning in GNU Guile Reference Manual). For instance, the following expression returns a list that contains all the services in %desktop-services minus the Avahi service:
(remove (lambda (service) (eq? (service-kind service) avahi-service-type)) %desktop-services)
is stored in the my-system-config.scm
guix system reconfigure my-system-config.scm command
instantiates that configuration, and makes it the default GRUB boot
entry (see Invoking guix system).
The normal way to change the system configuration is by updating this
file and re-running
guix system reconfigure. One should never
have to touch files in /etc or to run commands that modify the
system state such as
fact, you must avoid that since that would not only void your warranty
but also prevent you from rolling back to previous versions of your
system, should you ever need to.
Speaking of roll-back, each time you run
reconfigure, a new generation of the system is created—without
modifying or deleting previous generations. Old system generations get
an entry in the GRUB boot menu, allowing you to boot them in case
something went wrong with the latest generation. Reassuring, no? The
guix system list-generations command lists the system
generations available on disk. It is also possible to roll back the
system via the commands
guix system roll-back and
guix system switch-generation.
Although the command
guix system reconfigure will not modify
previous generations, must take care when the current generation is not
the latest (e.g., after invoking
guix system roll-back), since
the operation might overwrite a later generation (see Invoking guix system).
At the Scheme level, the bulk of an
is instantiated with the following monadic procedure (see The Store Monad):
Return a derivation that builds os, an
object (see 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.
This procedure is provided by the
(gnu system) module. Along
(gnu services) (see Services), this module contains the
guts of GuixSD. Make sure to visit it!