Nächste: , Vorige: , Nach oben: Systemkonfiguration   [Inhalt][Index]


11.2 Das Konfigurationssystem nutzen

Im letzten Abschnitt haben Sie kennengelernt, wie die Administration einer Maschine mit Guix System abläuft (siehe Einstieg). Werfen wir jetzt einen genaueren Blick darauf, was in der Systemkonfigurationsdatei steht.

Das Betriebssystem können Sie konfigurieren, indem Sie eine operating-system-Deklaration in einer Datei speichern, die Sie dann dem Befehl guix system übergeben (siehe guix system aufrufen), wie zuvor gezeigt. Eine einfache Konfiguration mit dem vorgegebenen Linux-Libre als Kernel, mit einer initialen RAM-Disk und ein paar Systemdiensten zusätzlich zu den vorgegebenen sieht so aus:

;; -*- 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)))

Die Konfiguration ist deklarativ. Es handelt sich um Programmcode, der in der Sprache Scheme geschrieben ist. Der gesamte (operating-system …)-Ausdruck legt ein Verbundsobjekt an mit mehreren Feldern. Manche der Felder oben, wie etwa host-name und bootloader, müssen angegeben werden. Andere sind optional, wie etwa packages und services; werden sie nicht angegeben, nehmen sie einen Vorgabewert an. Siehe operating-system-Referenz für Details zu allen verfügbaren Feldern.

Im Folgenden werden die Effekte von einigen der wichtigsten Feldern erläutert.

Problembehandlung: Die Konfigurationsdatei ist ein Scheme-Programm und ein Fehler in Syntax oder Semantik kann leicht passieren. Syntaxfehler wie eine falsch gesetzte Klammer lassen sich oft finden, indem Sie die Datei umformatieren lassen:

guix style -f config.scm

Im Kochbuch gibt es einen kurzen Abschnitt, wie man mit der Scheme-Sprache anfängt. Dort werden die Grundlagen erklärt, was ihnen beim Schreiben Ihrer Konfiguration helfen wird. Siehe Ein Schnellkurs in Scheme in GNU-Guix-Kochbuch.

Bootloader

Das bootloader-Feld beschreibt, mit welcher Methode Ihr System „gebootet“ werden soll. Maschinen, die auf Intel-Prozessoren basieren, können im alten „Legacy“-BIOS-Modus gebootet werden, wie es im obigen Beispiel der Fall wäre. Neuere Maschinen benutzen stattdessen das Unified Extensible Firmware Interface (UEFI) zum Booten. In diesem Fall sollte das bootloader-Feld in etwa so aussehen:

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

Siehe den Abschnitt Bootloader-Konfiguration für weitere Informationen zu den verfügbaren Konfigurationsoptionen.

Global sichtbare Pakete

Im Feld packages werden Pakete aufgeführt, die auf dem System für alle Benutzerkonten global sichtbar sein sollen, d.h. in der PATH-Umgebungsvariablen jedes Nutzers, zusätzlich zu den nutzereigenen Profilen (siehe guix package aufrufen). Die Variable %base-packages bietet alle Werkzeuge, die man für grundlegende Nutzer- und Administratortätigkeiten erwarten würde, einschließlich der GNU Core Utilities, der GNU Networking Utilities, des leichtgewichtigen Texteditors mg, find, grep und so weiter. Obiges Beispiel fügt zu diesen noch das Programm GNU Screen hinzu, welches aus dem Modul (gnu packages screen) genommen wird (siehe Paketmodule). Die Syntax (list package output) kann benutzt werden, um eine bestimmte Ausgabe eines Pakets auszuwählen:

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

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

Sich auf Pakete anhand ihres Variablennamens zu beziehen, wie oben bei isc-bind, hat den Vorteil, dass der Name eindeutig ist; Tippfehler werden direkt als „unbound variables“ gemeldet. Der Nachteil ist, dass man wissen muss, in welchem Modul ein Paket definiert wird, um die Zeile mit use-package-modules entsprechend zu ergänzen. Um dies zu vermeiden, kann man auch die Prozedur specification->package aus dem Modul (gnu packages) aufrufen, welche das einem angegebenen Namen oder Name-Versions-Paar zu Grunde liegende Paket liefert:

(use-modules (gnu packages))

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

Wenn ein Paket mehr als eine Ausgabe hat, kann man auch ohne größere Umstände auf eine bestimmte Ausgabe außer der Standardausgabe out verweisen, indem man die Prozedur specifications->packages aus dem Modul (gnu packages) verwendet. Zum Beispiel:

(use-modules (gnu packages))

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

Systemdienste

Das Feld services listet Systemdienste auf, die zur Verfügung stehen sollen, wenn das System startet (siehe Dienste). Die operating-system-Deklaration oben legt fest, dass wir neben den grundlegenden Basis-Diensten auch wollen, dass der OpenSSH-Secure-Shell-Daemon auf Port 2222 lauscht (siehe openssh-service-type). Intern sorgt der openssh-service-type dafür, dass sshd mit den richtigen Befehlszeilenoptionen aufgerufen wird, je nach Systemkonfiguration werden auch für dessen Betrieb nötige Konfigurationsdateien erstellt (siehe Dienste definieren).

Gelegentlich werden Sie die Basis-Dienste nicht einfach so, wie sie sind, benutzen, sondern anpassen wollen. Benutzen Sie modify-services (siehe modify-services), um die Liste der Basis-Dienste zu modifizieren.

Wenn Sie zum Beispiel guix-daemon und Mingetty (das Programm, womit Sie sich auf der Konsole anmelden) in der %base-services-Liste modifizieren möchten (siehe %base-services), schreiben Sie das Folgende in Ihre Betriebssystemdeklaration:

(define %my-services
  ;; Meine ganz eigene Liste von Diensten.
  (modify-services %base-services
    (guix-service-type config =>
                       (guix-configuration
                        (inherit config)
                        ;; Substitute von example.org herunterladen.
                        (substitute-urls
                          (list "https://example.org/guix"
                                "https://ci.guix.gnu.org"))))
    (mingetty-service-type config =>
                           (mingetty-configuration
                            (inherit config)
                            ;; Automatisch als "gast" anmelden.
                            (auto-login "gast")))))

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

Dadurch ändert sich die Konfiguration – d.h. die Dienst-Parameter – der guix-service-type-Instanz und die aller mingetty-service-type-Instanzen in der %base-services-Liste (siehe das Kochbuch in GNU Guix Cookbook für eine Anleitung, wie man damit ein Benutzerkonto automatisch auf nur einem TTY anmelden ließe). Das funktioniert so: Zunächst arrangieren wir, dass die ursprüngliche Konfiguration an den Bezeichner config im Rumpf gebunden wird, dann schreiben wir den Rumpf, damit er zur gewünschten Konfiguration ausgewertet wird. Beachten Sie insbesondere, wie wir mit inherit eine neue Konfiguration erzeugen, die dieselben Werte wie die alte Konfiguration hat, aber mit ein paar Modifikationen.

Die Konfiguration für typische Nutzung auf Heim- und Arbeitsrechnern, mit einer verschlüsselten Partition für das Wurzeldateisystem, darauf einer Swap-Datei, einem X11-Anzeigeserver, GNOME und Xfce (Benutzer können im Anmeldebildschirm auswählen, welche dieser Arbeitsumgebungen sie möchten, indem sie die Taste F1 drücken), Netzwerkverwaltung, Verwaltungswerkzeugen für den Energieverbrauch, und Weiteres, würde so aussehen:

;; -*- 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))

Ein grafisches System mit einer Auswahl an leichtgewichtigen Fenster-Managern statt voll ausgestatteten Arbeitsumgebungen würde so aussehen:

;; -*- 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))

Dieses Beispiel bezieht sich auf das Dateisystem hinter /boot/efi über dessen UUID, 1234-ABCD. Schreiben Sie statt dieser UUID die richtige UUID für Ihr System, wie sie der Befehl blkid liefert.

Im Abschnitt Desktop-Dienste finden Sie eine genaue Liste der unter %desktop-services angebotenen Dienste.

Beachten Sie, dass %desktop-services nur eine Liste von die Dienste repräsentierenden service-Objekten ist. Wenn Sie Dienste daraus entfernen möchten, können Sie dazu die Prozeduren zum Filtern von Listen benutzen (siehe SRFI-1 Filtering and Partitioning in Referenzhandbuch zu GNU Guile). Beispielsweise liefert der folgende Ausdruck eine Liste mit allen Diensten von %desktop-services außer dem Avahi-Dienst.

Alternativ können Sie das Makro modify-services benutzen:

Dienste untersuchen

Bei der Arbeit an Ihrer Systemkonfiguration kann es vorkommen, dass ein Systemdienst nicht auftaucht oder sich das System falsch verhält und Sie sich fragen, warum. Dann gibt es mehrere Ansätze, wie Sie Ihr System untersuchen und auf Fehlersuche gehen können.

Zunächst können Sie den Abhängigkeitsgraphen der Shepherd-Dienste untersuchen, und zwar so:

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

So können Sie sich veranschaulichen, welche Shepherd-Dienste in /etc/config.scm definiert sind. Jeder Kasten steht für einen Dienst, wie ihn sudo herd status auf dem laufenden System anzeigt, und jeder Pfeil steht für eine Abhängigkeit (in dem Sinn, dass, wenn Dienst A von B abhängt, B vor A gestartet sein muss).

Allerdings ist nicht jeder „Dienst“ auch ein Shepherd-Dienst, weil die Definition des Begriffs Dienst in Guix System weit ist (siehe Dienste). Um allgemein jeden Systemdienst und die Beziehung zwischen solchen zu veranschaulichen, geben Sie ein:

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

So können Sie den Diensterweiterungsgraphen sehen, also welche Dienste welche anderen „erweitern“ und so zum Beispiel zu deren Konfiguration beitragen. Siehe Dienstkompositionen, um mehr über die Bedeutung des Graphen zu erfahren.

Zu guter Letzt könnte Ihnen helfen, Ihre Systemkonfiguration auf der REPL zu untersuchen (Interaktiv mit Guix arbeiten). Hier sehen Sie eine Beispielsitzung:

$ 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>
      …)

Siehe Service-Referenz, um mehr über die Scheme-Schnittstelle zum Verändern und Untersuchen von Diensten zu lernen.

Das System instanziieren

Angenommen, Sie haben die operating-system-Deklaration in einer Datei config.scm gespeichert, dann instanziiert der Befehl sudo guix system reconfigure config.scm diese Konfiguration und macht sie zum voreingestellten GRUB-Boot-Eintrag. Siehe Einstieg für einen Überblick.

Der normale Weg, die Systemkonfiguration nachträglich zu ändern, ist, die Datei zu aktualisieren und guix system reconfigure erneut auszuführen. Man sollte nie die Dateien in /etc bearbeiten oder den Systemzustand mit Befehlen wie useradd oder grub-install verändern. Tatsächlich müssen Sie das ausdrücklich vermeiden, sonst verfällt nicht nur Ihre Garantie, sondern Sie können Ihr System auch nicht mehr auf eine alte Version des Systems zurücksetzen, falls das jemals notwendig wird.

Die Programmierschnittstelle

Auf der Ebene von Scheme wird der Großteil der operating-system-Deklaration mit der folgenden monadischen Prozedur instanziiert (siehe Die Store-Monade):

Monadische Prozedur: operating-system-derivation os

Liefert eine Ableitung, mit der ein operating-system-Objekt os erstellt wird (siehe Ableitungen).

Die Ausgabe der Ableitung ist ein einzelnes Verzeichnis mit Verweisen auf alle Pakete, Konfigurationsdateien und andere unterstützenden Dateien, die nötig sind, um os zu instanziieren.

Diese Prozedur wird vom Modul (gnu system) angeboten. Zusammen mit (gnu services) (siehe Dienste) deckt dieses Modul den Kern von „Guix System“ ab. Schauen Sie es sich mal an!


Nächste: operating-system-Referenz, Vorige: Einstieg, Nach oben: Systemkonfiguration   [Inhalt][Index]