Suivant: , Précédent: , Monter: Configuration du système   [Table des matières][Index]


11.2 Utiliser le système de configuration

The previous section showed the overall workflow you would follow when administering a Guix System machine (voir Guide de démarrage). Let’s now see in more detail what goes into the system configuration file.

The operating system is configured by providing an operating-system declaration in a file that can then be passed to the guix system command (voir Invoquer guix system), as we’ve seen before. A simple setup, with the default Linux-Libre kernel, initial RAM disk, and a couple of system services added to those provided by default looks like this:

;; -*- mode: scheme; -*-
;; 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 screen ssh)

(operating-system
  (host-name "komputilo")
  (timezone "Europe/Berlin")
  (locale "en_US.utf8")

  ;; Boot in "legacy" BIOS mode, assuming /dev/sdX is the
  ;; target hard disk, and "my-root" is the label of the target
  ;; root file system.
  (bootloader (bootloader-configuration
                (bootloader grub-bootloader)
                (targets '("/dev/sdX"))))
  ;; It's fitting to support the equally bare bones ‘-nographic’
  ;; QEMU option, which also nicely sidesteps forcing QWERTY.
  (kernel-arguments (list "console=ttyS0,115200"))
  (file-systems (cons (file-system
                        (device (file-system-label "my-root"))
                        (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")))
               %base-user-accounts))

  ;; Globally-installed packages.
  (packages (cons screen %base-packages))

  ;; Add services to the baseline: a DHCP client and an SSH
  ;; server.  You may wish to add an NTP service here.
  (services (append (list (service dhcp-client-service-type)
                          (service openssh-service-type
                                   (openssh-configuration
                                    (openssh openssh-sans-x)
                                    (port-number 2222))))
                    %base-services)))

The configuration is declarative. It is code in the Scheme programming language; the whole (operating-system …) expression produces a record with a number of fields. Some of the fields defined above, such as host-name and bootloader, are mandatory. Others, such as packages and services, can be omitted, in which case they get a default value. Voir Référence de operating-system, for details about all the available fields.

Below we discuss the meaning of some of the most important fields.

Troubleshooting : The configuration file is a Scheme program and you might get the syntax or semantics wrong as you get started. Syntactic issues such as misplaced parentheses can often be identified by reformatting your file:

guix style -f config.scm

The Cookbook has a short section to get started with the Scheme programming language that explains the fundamentals, which you will find helpful when hacking your configuration. Voir A Scheme Crash Course dans GNU Guix Cookbook.

Bootloader

Le champ bootloader décrit la méthode qui sera utilisée pour démarrer votre système. Les machines basées sur les processeurs Intel peuvent démarrer dans l’ancien mode BIOS, comme dans l’exemple au-dessus. Cependant, les machines plus récentes s’appuient sur l’UEFI (Unified Extensible Firmware Interface) pour démarrer. Dans ce cas, le champ bootloader devrait contenir quelque chose comme cela :

(bootloader-configuration
  (bootloader grub-efi-bootloader)
  (targets '("/boot/efi")))

Voir Configuration du chargeur d’amorçage, pour plus d’informations sur les options de configuration disponibles.

Paquets visibles sur tout le système

Le champ packages liste les paquets qui seront visibles sur tout le système, pour tous les comptes utilisateur·rice·s — c.-à-d. dans la variable d’environnement PATH de tous les utilisateur·rice·s — en plus des profils utilisateur·rice·s (voir Invoquer guix package). La variable %base-packages fournit tous les outils qu’on pourrait attendre pour les tâches de base de l’administrateur·rice et de l’utilisateur·rice — dont les GNU Core Utilities, les GNU Networking Utilities, l’éditeur de texte léger mg, find, grep, etc. L’exemple ci-dessus ajoute GNU Screen à ces paquets, récupéré depuis le module (gnu packages screen) (voir Modules de paquets). Vous pouvez utiliser la syntaxe (list package output) pour ajouter une sortie spécifique d’un paquet :

(use-modules (gnu packages))
(use-modules (gnu packages dns))

(operating-system
  ;; ...
  (packages (cons (list isc-bind "utils")
                  %base-packages)))

Se référer aux paquets par le nom de leur variable, comme isc-bind ci-dessus, a l’avantage d’être sans ambigüité ; cela permet aussi de se rendre rapidement compte de coquilles quand on a des « variables non liées ». L’inconvénient est qu’on a besoin de savoir dans quel module est défini le paquet, et de modifier la ligne use-package-modules en conséquence. Pour éviter cela, on peut utiliser la procédure specification->package du module (gnu packages), qui renvoie le meilleur paquet pour un nom donné ou un nom et une version :

(use-modules (gnu packages))

(operating-system
  ;; ...
  (packages (append (map specification->package
                         '("tcpdump" "htop" "gnupg@2.0"))
                    %base-packages)))

When a package has more than one output it can be a challenge to refer to a specific output instead of just to the standard out output. For these situations one can use the specifications->packages procedure from the (gnu packages) module. For example:

(use-modules (gnu packages))

(operating-system
  ;; ...
  (packages (append (specifications->packages
                      '("git" "git:send-email"))
                    %base-packages)))

Services systèmes

Le champ services liste les services système à rendre disponible lorsque le système démarre (voir Services). La déclaration operating-system au-dessus spécifie que, en plus des services de base, on veut que le démon ssh OpenSSH écoute sur le port 2222 (voir openssh-service-type). Sous le capot, openssh-service-type s’arrange pour que sshd soit lancé avec les bonnes options de la ligne de commande, éventuellement en générant des fichiers de configuration (voir Définir des services).

Parfois, plutôt que d’utiliser les services de base tels-quels, on peut vouloir les personnaliser. Pour cela, utilisez modify-services (voir modify-services) pour modifier la liste.

Par exemple, supposons que vous souhaitiez modifier guix-daemon et Mingetty (l’écran de connexion en console) dans la liste %base-services (voir %base-services). Pour cela, vous pouvez écrire ce qui suit dans votre déclaration de système d’exploitation :

(define %my-services
  ;; ma propre liste de services.
  (modify-services %base-services
    (guix-service-type config =>
                       (guix-configuration
                        (inherit config)
                        ;; Récupérer les substituts depuis example.org.
                        (substitute-urls
                          (list "https://example.org/guix"
                                "https://ci.guix.gnu.org"))))
    (mingetty-service-type config =>
                           (mingetty-configuration
                            (inherit config)
                            ;; Connexion automatique en tant que « guest ».
                            (auto-login "guest")))))

(operating-system
  ;; …
  (services %my-services))

Cela modifie la configuration — c.-à-d. les paramètres du service — de l’instance de guix-service-type, et de toutes les instances de mingetty-service-type dans la liste %base-services (voir voir le livre de recettes pour apprendre à connecter quelqu’un automatiquement sur un TTY donné dans GNU Guix Cookbook)). Remarquez comment on fait cela : d’abord, on s’arrange pour que la configuration de départ soit liée à l’identifiant config dans body puis on écrit body pour qu’il s’évalue en la configuration désirée. En particulier, remarquez comment on utilise inherit pour créer une nouvelle configuration qui a les même valeurs que l’ancienne configuration, avec seulement quelques modifications.

La configuration pour une utilisation de « bureau » typique, avec une partition racine chiffrée, a fichier d’échange sur la partition racine, le serveur d’affichage X11, GNOME et Xfce (les utilisateurs peuvent choisir l’environnement de bureau sur l’écran de connexion en appuyant sur F1), la gestion du réseau, la gestion de l’énergie, et bien plus, ressemblerait à ceci :

;; -*- mode: scheme; -*-
;; This is an operating system configuration template
;; for a "desktop" setup with GNOME and Xfce where the
;; root partition is encrypted with LUKS, and a swap file.

(use-modules (gnu) (gnu system nss) (guix utils))
(use-service-modules desktop sddm xorg)
(use-package-modules gnome)

(operating-system
  (host-name "antelope")
  (timezone "Europe/Paris")
  (locale "en_US.utf8")

  ;; Choose US English keyboard layout.  The "altgr-intl"
  ;; variant provides dead keys for accented characters.
  (keyboard-layout (keyboard-layout "us" "altgr-intl"))

  ;; Use the UEFI variant of GRUB with the EFI System
  ;; Partition mounted on /boot/efi.
  (bootloader (bootloader-configuration
                (bootloader grub-efi-bootloader)
                (targets '("/boot/efi"))
                (keyboard-layout keyboard-layout)))

  ;; 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 "my-root")
          (type luks-device-mapping))))

  (file-systems (append
                 (list (file-system
                         (device (file-system-label "my-root"))
                         (mount-point "/")
                         (type "ext4")
                         (dependencies mapped-devices))
                       (file-system
                         (device (uuid "1234-ABCD" 'fat))
                         (mount-point "/boot/efi")
                         (type "vfat")))
                 %base-file-systems))

  ;; Specify a swap file for the system, which resides on the
  ;; root file system.
  (swap-devices (list (swap-space
                       (target "/swapfile"))))

  ;; Create user `bob' with `alice' as its initial password.
  (users (cons (user-account
                (name "bob")
                (comment "Alice's brother")
                (password (crypt "alice" "$6$abc"))
                (group "students")
                (supplementary-groups '("wheel" "netdev"
                                        "audio" "video")))
               %base-user-accounts))

  ;; Add the `students' group
  (groups (cons* (user-group
                  (name "students"))
                 %base-groups))

  ;; This is where we specify system-wide packages.
  (packages (append (list
                     ;; for user mounts
                     gvfs)
                    %base-packages))

  ;; Add GNOME and Xfce---we can choose at the log-in screen
  ;; by clicking the gear.  Use the "desktop" services, which
  ;; include the X11 log-in service, networking with
  ;; NetworkManager, and more.
  (services (if (target-x86-64?)
                (append (list (service gnome-desktop-service-type)
                              (service xfce-desktop-service-type)
                              (set-xorg-configuration
                               (xorg-configuration
                                (keyboard-layout keyboard-layout))))
                        %desktop-services)

                ;; FIXME: Since GDM depends on Rust (gdm -> gnome-shell -> gjs
                ;; -> mozjs -> rust) and Rust is currently unavailable on
                ;; non-x86_64 platforms, we use SDDM and Mate here instead of
                ;; GNOME and GDM.
                (append (list (service mate-desktop-service-type)
                              (service xfce-desktop-service-type)
                              (set-xorg-configuration
                               (xorg-configuration
                                (keyboard-layout keyboard-layout))
                               sddm-service-type))
                        %desktop-services)))

  ;; Allow resolution of '.local' host names with mDNS.
  (name-service-switch %mdns-host-lookup-nss))

Un système graphique avec un choix de gestionnaires de fenêtres légers plutôt que des environnement de bureaux complets ressemblerait à cela :

;; -*- mode: scheme; -*-
;; 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 emacs emacs-xyz ratpoison suckless wm
                     xorg)

(operating-system
  (host-name "antelope")
  (timezone "Europe/Paris")
  (locale "en_US.utf8")

  ;; Use the UEFI variant of GRUB with the EFI System
  ;; Partition mounted on /boot/efi.
  (bootloader (bootloader-configuration
                (bootloader grub-efi-bootloader)
                (targets '("/boot/efi"))))

  ;; Assume the target root file system is labelled "my-root",
  ;; and the EFI System Partition has UUID 1234-ABCD.
  (file-systems (append
                 (list (file-system
                         (device (file-system-label "my-root"))
                         (mount-point "/")
                         (type "ext4"))
                       (file-system
                         (device (uuid "1234-ABCD" 'fat))
                         (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")))
               %base-user-accounts))

  ;; Add a bunch of window managers; we can choose one at
  ;; the log-in screen with F1.
  (packages (append (list
                     ;; window managers
                     ratpoison i3-wm i3status dmenu
                     emacs emacs-exwm emacs-desktop-environment
                     ;; terminal emulator
                     xterm)
                    %base-packages))

  ;; Use the "desktop" services, which include the X11
  ;; log-in service, networking with NetworkManager, and more.
  (services %desktop-services)

  ;; Allow resolution of '.local' host names with mDNS.
  (name-service-switch %mdns-host-lookup-nss))

Cet exemple se réfère au système de fichier /boot/efi par son UUID, 1234-ABCD. Remplacez cet UUID par le bon UUID de votre système, renvoyé par la commande blkid.

Voir Services de bureaux, for the exact list of services provided by %desktop-services.

Encore une fois, %desktop-services n’est qu’une liste d’objets service. Si vous voulez enlever des services de là, vous pouvez le faire avec des procédures pour les listes (voir SRFI-1 Filtering and Partitioning dans GNU Guile Reference Manual). Par exemple, l’expression suivante renvoie une liste qui contient tous les services dans %desktop-services sauf le service Avahi :

Autrement, la macro modify-services peut être utilisée :

Inspecting Services

As you work on your system configuration, you might wonder why some system service doesn’t show up or why the system is not as you expected. There are several ways to inspect and troubleshoot problems.

First, you can inspect the dependency graph of Shepherd services like so:

guix system shepherd-graph /etc/config.scm | \
  guix shell xdot -- xdot -

This lets you visualize the Shepherd services as defined in /etc/config.scm. Each box is a service as would be shown by sudo herd status on the running system, and each arrow denotes a dependency (in the sense that if service A depends on B, then B must be started before A).

Not all “services” are Shepherd services though, since Guix System uses a broader definition of the term (voir Services). To visualize system services and their relations at a higher level, run:

guix system extension-graph /etc/config.scm | \
  guix shell xdot -- xdot -

This lets you view the service extension graph: how services “extend” each other, for instance by contributing to their configuration. Voir Composition de services, to understand the meaning of this graph.

Last, you may also find it useful to inspect your system configuration at the REPL (voir Utiliser Guix de manière interactive). Here is an example session:

$ guix repl
scheme@(guix-user)> ,use (gnu)
scheme@(guix-user)> (define os (load "config.scm"))
scheme@(guix-user)> ,pp (map service-kind (operating-system-services os))
$1 = (#<service-type localed cabba93>
      …)

Voir Référence de service, to learn about the Scheme interface to manipulate and inspect services.

Instancier le système

Assuming the operating-system declaration is stored in the config.scm file, the sudo guix system reconfigure config.scm command instantiates that configuration, and makes it the default boot entry. Voir Guide de démarrage, for an overview.

Pour changer la configuration du système, on met normalement à jour ce fichier et on relance guix system reconfigure. On ne devrait jamais avoir à modifier de fichiers dans /etc ou à lancer des commandes qui modifient l’état du système comme useradd ou grub-install. En fait, vous devez les éviter parce que non seulement ça annulerait vos garanties, mais ça empêcherait aussi de revenir à des versions précédents du système, si vous en avez besoin.

L’interface de programmation

Au niveau Scheme, la grosse déclaration operating-system est instanciée avec la procédure monadique suivante (voir La monade du dépôt) :

Procédure monadique :operating-system-derivation os

Renvoie une dérivation qui construit os, un objet operating-system (voir Dérivations).

La sortie de la dérivation est un répertoire qui se réfère à tous les paquets et d’autres fichiers supports requis pour instancier os.

Cette procédure est fournie par le module (gnu system). Avec (gnu services) (voir Services), ce module contient les entrailles du système Guix. Ouvrez-le un jour !


Suivant: Référence de operating-system, Précédent: Guide de démarrage, Monter: Configuration du système   [Table des matières][Index]