;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
-;;; Copyright © 2015, 2016 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2015, 2016, 2020 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
;;; Copyright © 2016, 2017 Leo Famulari <leo@famulari.name>
;;; Copyright © 2016 David Craven <david@craven.ch>
;;; Copyright © 2019 John Soo <jsoo1@asu.edu>
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de>
+;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
;;;
;;; This file is part of GNU Guix.
;;;
#:select (alsa-utils crda eudev e2fsprogs fuse gpm kbd lvm2 rng-tools))
#:use-module (gnu packages bash)
#:use-module ((gnu packages base)
- #:select (canonical-package coreutils glibc glibc-utf8-locales))
+ #:select (coreutils glibc glibc-utf8-locales))
#:use-module (gnu packages package-management)
#:use-module ((gnu packages gnupg) #:select (guile-gcrypt))
#:use-module (gnu packages linux)
#:use-module (srfi srfi-26)
#:use-module (ice-9 match)
#:use-module (ice-9 format)
+ #:re-export (user-processes-service-type ;backwards compatibility
+ %default-substitute-urls)
#:export (fstab-service-type
root-file-system-service
file-system-service-type
swap-service
- user-processes-service-type
host-name-service
console-keymap-service
%default-console-font
udev-service
udev-rule
file->udev-rule
+ udev-rules-service
login-configuration
login-configuration?
agetty-service-type
mingetty-configuration
+ mingetty-configuration-tty
+ mingetty-configuration-auto-login
+ mingetty-configuration-login-program
+ mingetty-configuration-login-pause?
+ mingetty-configuration-clear-on-logout?
+ mingetty-configuration-mingetty
mingetty-configuration?
mingetty-service
mingetty-service-type
pam-limits-service-type
pam-limits-service
+ references-file
+
%base-services))
;;; Commentary:
\f
-;;;
-;;; User processes.
-;;;
-
-(define %do-not-kill-file
- ;; Name of the file listing PIDs of processes that must survive when halting
- ;; the system. Typical example is user-space file systems.
- "/etc/shepherd/do-not-kill")
-
-(define (user-processes-shepherd-service requirements)
- "Return the 'user-processes' Shepherd service with dependencies on
-REQUIREMENTS (a list of service names).
-
-This is a synchronization point used to make sure user processes and daemons
-get started only after crucial initial services have been started---file
-system mounts, etc. This is similar to the 'sysvinit' target in systemd."
- (define grace-delay
- ;; Delay after sending SIGTERM and before sending SIGKILL.
- 4)
-
- (list (shepherd-service
- (documentation "When stopped, terminate all user processes.")
- (provision '(user-processes))
- (requirement requirements)
- (start #~(const #t))
- (stop #~(lambda _
- (define (kill-except omit signal)
- ;; Kill all the processes with SIGNAL except those listed
- ;; in OMIT and the current process.
- (let ((omit (cons (getpid) omit)))
- (for-each (lambda (pid)
- (unless (memv pid omit)
- (false-if-exception
- (kill pid signal))))
- (processes))))
-
- (define omitted-pids
- ;; List of PIDs that must not be killed.
- (if (file-exists? #$%do-not-kill-file)
- (map string->number
- (call-with-input-file #$%do-not-kill-file
- (compose string-tokenize
- (@ (ice-9 rdelim) read-string))))
- '()))
-
- (define (now)
- (car (gettimeofday)))
-
- (define (sleep* n)
- ;; Really sleep N seconds.
- ;; Work around <http://bugs.gnu.org/19581>.
- (define start (now))
- (let loop ((elapsed 0))
- (when (> n elapsed)
- (sleep (- n elapsed))
- (loop (- (now) start)))))
-
- (define lset= (@ (srfi srfi-1) lset=))
-
- (display "sending all processes the TERM signal\n")
-
- (if (null? omitted-pids)
- (begin
- ;; Easy: terminate all of them.
- (kill -1 SIGTERM)
- (sleep* #$grace-delay)
- (kill -1 SIGKILL))
- (begin
- ;; Kill them all except OMITTED-PIDS. XXX: We would
- ;; like to (kill -1 SIGSTOP) to get a fixed list of
- ;; processes, like 'killall5' does, but that seems
- ;; unreliable.
- (kill-except omitted-pids SIGTERM)
- (sleep* #$grace-delay)
- (kill-except omitted-pids SIGKILL)
- (delete-file #$%do-not-kill-file)))
-
- (let wait ()
- ;; Reap children, if any, so that we don't end up with
- ;; zombies and enter an infinite loop.
- (let reap-children ()
- (define result
- (false-if-exception
- (waitpid WAIT_ANY (if (null? omitted-pids)
- 0
- WNOHANG))))
-
- (when (and (pair? result)
- (not (zero? (car result))))
- (reap-children)))
-
- (let ((pids (processes)))
- (unless (lset= = pids (cons 1 omitted-pids))
- (format #t "waiting for process termination\
- (processes left: ~s)~%"
- pids)
- (sleep* 2)
- (wait))))
-
- (display "all processes have been terminated\n")
- #f))
- (respawn? #f))))
-
-(define user-processes-service-type
- (service-type
- (name 'user-processes)
- (extensions (list (service-extension shepherd-root-service-type
- user-processes-shepherd-service)))
- (compose concatenate)
- (extend append)
-
- ;; The value is the list of Shepherd services 'user-processes' depends on.
- ;; Extensions can add new services to this list.
- (default-value '())
-
- (description "The @code{user-processes} service is responsible for
-terminating all the processes so that the root file system can be re-mounted
-read-only, just before rebooting/halting. Processes still running after a few
-seconds after @code{SIGTERM} has been sent are terminated with
-@code{SIGKILL}.")))
-
-\f
;;;
;;; File systems.
;;;
(define root-file-system-service-type
(shepherd-service-type 'root-file-system
- (const %root-file-system-shepherd-service)))
+ (const %root-file-system-shepherd-service)
+ (description "Take care of syncing the root file
+system and of remounting it read-only when the system shuts down.")))
(define (root-file-system-service)
"Return a service whose sole purpose is to re-mount read-only the root file
(define (mapped-device->shepherd-service-name md)
"Return the symbol that denotes the shepherd service of MD, a <mapped-device>."
(symbol-append 'device-mapping-
- (string->symbol (mapped-device-target md))))
+ (string->symbol (string-join
+ (mapped-device-targets md) "-"))))
(define dependency->shepherd-service-name
(match-lambda
(documentation "Add TRNG to entropy pool.")
(requirement '(udev))
(provision '(trng))
- (start #~(make-forkexec-constructor #$@rngd-command))
- (stop #~(make-kill-destructor))))))
+ (start #~(make-forkexec-constructor '#$rngd-command))
+ (stop #~(make-kill-destructor))))
+ (description "Run the @command{rngd} random number generation daemon to
+supply entropy to the kernel's pool.")))
(define* (rngd-service #:key
(rng-tools rng-tools)
(provision '(host-name))
(start #~(lambda _
(sethostname #$name)))
- (one-shot? #t)))))
+ (one-shot? #t)))
+ (description "Initialize the machine's host name.")))
(define (host-name-service name)
"Return a service that sets the host name to @var{name}."
(display 1 port))))
#t))
(stop #~(const #f)))))
- #t)) ;default to UTF-8
+ #t ;default to UTF-8
+ (description "Ensure the Linux virtual terminals run in UTF-8 mode.")))
(define console-keymap-service-type
(shepherd-service-type
(start #~(lambda _
(zero? (system* #$(file-append kbd "/bin/loadkeys")
#$@files))))
- (respawn? #f)))))
+ (respawn? #f)))
+ (description "@emph{This service is deprecated in favor of the
+@code{keyboard-layout} field of @code{operating-system}.} Load the given list
+of console keymaps with @command{loadkeys}.")))
(define-deprecated (console-keymap-service #:rest files)
#f
(define-record-type* <mingetty-configuration>
mingetty-configuration make-mingetty-configuration
mingetty-configuration?
- (mingetty mingetty-configuration-mingetty ;<package>
- (default mingetty))
- (tty mingetty-configuration-tty) ;string
- (auto-login mingetty-auto-login ;string | #f
- (default #f))
- (login-program mingetty-login-program ;gexp
- (default #f))
- (login-pause? mingetty-login-pause? ;Boolean
- (default #f)))
+ (mingetty mingetty-configuration-mingetty ;<package>
+ (default mingetty))
+ (tty mingetty-configuration-tty) ;string
+ (auto-login mingetty-auto-login ;string | #f
+ (default #f))
+ (login-program mingetty-login-program ;gexp
+ (default #f))
+ (login-pause? mingetty-login-pause? ;Boolean
+ (default #f))
+ (clear-on-logout? mingetty-clear-on-logout? ;Boolean
+ (default #t)))
(define mingetty-shepherd-service
(match-lambda
(($ <mingetty-configuration> mingetty tty auto-login login-program
- login-pause?)
+ login-pause? clear-on-logout?)
(list
(shepherd-service
(documentation "Run mingetty on an tty.")
(start #~(make-forkexec-constructor
(list #$(file-append mingetty "/sbin/mingetty")
- "--noclear"
;; Avoiding 'vhangup' allows us to avoid 'setfont'
;; errors down the path where various ioctls get
;; in Linux.
"--nohangup" #$tty
+ #$@(if clear-on-logout?
+ #~()
+ #~("--noclear"))
#$@(if auto-login
#~("--autologin" #$auto-login)
#~())
(name-services nscd-configuration-name-services ;list of <packages>
(default '()))
(glibc nscd-configuration-glibc ;<package>
- (default (canonical-package glibc))))
+ (default glibc)))
(define-record-type* <nscd-cache> nscd-cache make-nscd-cache
nscd-cache?
(documentation "Run the syslog daemon (syslogd).")
(provision '(syslogd))
(requirement '(user-processes))
- (start #~(make-forkexec-constructor
- (list #$(syslog-configuration-syslogd config)
- "--rcfile" #$(syslog-configuration-config-file config))
- #:pid-file "/var/run/syslog.pid"))
- (stop #~(make-kill-destructor))))))
+ (start #~(let ((spawn (make-forkexec-constructor
+ (list #$(syslog-configuration-syslogd config)
+ "--rcfile"
+ #$(syslog-configuration-config-file config))
+ #:pid-file "/var/run/syslog.pid")))
+ (lambda ()
+ ;; Set the umask such that file permissions are #o640.
+ (let ((mask (umask #o137))
+ (pid (spawn)))
+ (umask mask)
+ pid))))
+ (stop #~(make-kill-destructor))))
+ (description "Run the syslog daemon, @command{syslogd}, which is
+responsible for logging system messages.")))
;; Snippet adapted from the GNU inetutils manual.
(define %default-syslog.conf
(module "pam_limits.so")
(arguments '("conf=/etc/security/limits.conf")))))
(if (member (pam-service-name pam)
- '("login" "su" "slim" "gdm-password"))
+ '("login" "su" "slim" "gdm-password" "sddm"))
(pam-service
(inherit pam)
(session (cons pam-limits
#~(begin
(use-modules (guix build utils))
- (unless (file-exists? "/etc/guix/acl")
- (mkdir-p "/etc/guix")
- (copy-file #+default-acl "/etc/guix/acl")
- (chmod "/etc/guix/acl" #o600)))))
+ ;; If the ACL already exists, move it out of the way. Create a backup
+ ;; if it's a regular file: it's likely that the user manually updated
+ ;; it with 'guix archive --authorize'.
+ (if (file-exists? "/etc/guix/acl")
+ (if (and (symbolic-link? "/etc/guix/acl")
+ (store-file-name? (readlink "/etc/guix/acl")))
+ (delete-file "/etc/guix/acl")
+ (rename-file "/etc/guix/acl" "/etc/guix/acl.bak"))
+ (mkdir-p "/etc/guix"))
+
+ ;; Installed the declared ACL.
+ (symlink #+default-acl "/etc/guix/acl"))))
(define %default-authorized-guix-keys
;; List of authorized substitute keys.
- (list (file-append guix "/share/guix/berlin.guixsd.org.pub")))
+ (list (file-append guix "/share/guix/berlin.guix.gnu.org.pub")))
(define-record-type* <guix-configuration>
guix-configuration make-guix-configuration
(default 0))
(log-compression guix-configuration-log-compression
(default 'bzip2))
+ (discover? guix-configuration-discover?
+ (default #f))
(extra-options guix-configuration-extra-options ;list of strings
(default '()))
(log-file guix-configuration-log-file ;string
(define %default-guix-configuration
(guix-configuration))
+(define shepherd-set-http-proxy-action
+ ;; Shepherd action to change the HTTP(S) proxy.
+ (shepherd-action
+ (name 'set-http-proxy)
+ (documentation
+ "Change the HTTP(S) proxy used by 'guix-daemon' and restart it.")
+ (procedure #~(lambda* (_ #:optional proxy)
+ (let ((environment (environ)))
+ ;; A bit of a hack: communicate PROXY to the 'start'
+ ;; method via environment variables.
+ (if proxy
+ (begin
+ (format #t "changing HTTP/HTTPS \
+proxy of 'guix-daemon' to ~s...~%"
+ proxy)
+ (setenv "http_proxy" proxy))
+ (begin
+ (format #t "clearing HTTP/HTTPS \
+proxy of 'guix-daemon'...~%")
+ (unsetenv "http_proxy")))
+ (action 'guix-daemon 'restart)
+ (environ environment)
+ #t)))))
+
+(define shepherd-discover-action
+ ;; Shepherd action to enable or disable substitute servers discovery.
+ (shepherd-action
+ (name 'discover)
+ (documentation
+ "Enable or disable substitute servers discovery and restart the
+'guix-daemon'.")
+ (procedure #~(lambda* (_ status)
+ (let ((environment (environ)))
+ (if (and status
+ (string=? status "on"))
+ (begin
+ (format #t "enable substitute servers discovery~%")
+ (setenv "discover" "on"))
+ (begin
+ (format #t "disable substitute servers discovery~%")
+ (unsetenv "discover")))
+ (action 'guix-daemon 'restart)
+ (environ environment)
+ #t)))))
+
(define (guix-shepherd-service config)
"Return a <shepherd-service> for the Guix daemon service with CONFIG."
(match-record config <guix-configuration>
(guix build-group build-accounts authorize-key? authorized-keys
use-substitutes? substitute-urls max-silent-time timeout
- log-compression extra-options log-file http-proxy tmpdir
- chroot-directories)
+ log-compression discover? extra-options log-file
+ http-proxy tmpdir chroot-directories)
(list (shepherd-service
(documentation "Run the Guix daemon.")
(provision '(guix-daemon))
(requirement '(user-processes))
- (modules '((srfi srfi-1)))
+ (actions (list shepherd-set-http-proxy-action
+ shepherd-discover-action))
+ (modules '((srfi srfi-1)
+ (ice-9 match)
+ (gnu build shepherd)))
(start
- #~(make-forkexec-constructor
- (cons* #$(file-append guix "/bin/guix-daemon")
- "--build-users-group" #$build-group
- "--max-silent-time" #$(number->string max-silent-time)
- "--timeout" #$(number->string timeout)
- "--log-compression" #$(symbol->string log-compression)
- #$@(if use-substitutes?
- '()
- '("--no-substitutes"))
- "--substitute-urls" #$(string-join substitute-urls)
- #$@extra-options
-
- ;; Add CHROOT-DIRECTORIES and all their dependencies (if
- ;; these are store items) to the chroot.
- (append-map (lambda (file)
- (append-map (lambda (directory)
- (list "--chroot-directory"
- directory))
- (call-with-input-file file
- read)))
- '#$(map references-file chroot-directories)))
-
- #:environment-variables
- (list #$@(if http-proxy
- (list (string-append "http_proxy=" http-proxy))
- '())
- #$@(if tmpdir
- (list (string-append "TMPDIR=" tmpdir))
- '())
-
- ;; Make sure we run in a UTF-8 locale so that 'guix
- ;; offload' correctly restores nars that contain UTF-8
- ;; file names such as 'nss-certs'. See
- ;; <https://bugs.gnu.org/32942>.
- (string-append "GUIX_LOCPATH="
- #$glibc-utf8-locales "/lib/locale")
- "LC_ALL=en_US.utf8")
-
- #:log-file #$log-file))
+ (with-imported-modules `(((guix config) => ,(make-config.scm))
+ ,@(source-module-closure
+ '((gnu build shepherd))
+ #:select? not-config?))
+ #~(lambda args
+ (define proxy
+ ;; HTTP/HTTPS proxy. The 'http_proxy' variable is set by
+ ;; the 'set-http-proxy' action.
+ (or (getenv "http_proxy") #$http-proxy))
+
+ (define discover?
+ (or (getenv "discover") #$discover?))
+
+ ;; Start the guix-daemon from a container, when supported,
+ ;; to solve an installation issue. See the comment below for
+ ;; more details.
+ (fork+exec-command/container
+ (cons* #$(file-append guix "/bin/guix-daemon")
+ "--build-users-group" #$build-group
+ "--max-silent-time"
+ #$(number->string max-silent-time)
+ "--timeout" #$(number->string timeout)
+ "--log-compression"
+ #$(symbol->string log-compression)
+ #$@(if use-substitutes?
+ '()
+ '("--no-substitutes"))
+ (string-append "--discover="
+ (if discover? "yes" "no"))
+ "--substitute-urls" #$(string-join substitute-urls)
+ #$@extra-options
+
+ ;; Add CHROOT-DIRECTORIES and all their dependencies
+ ;; (if these are store items) to the chroot.
+ (append-map
+ (lambda (file)
+ (append-map (lambda (directory)
+ (list "--chroot-directory"
+ directory))
+ (call-with-input-file file
+ read)))
+ '#$(map references-file
+ chroot-directories)))
+
+ ;; When running the installer, we need guix-daemon to
+ ;; operate from within the same MNT namespace as the
+ ;; installation container. In that case only, enter the
+ ;; namespace of the process PID passed as start argument.
+ ;; Otherwise, for symmetry purposes enter the caller
+ ;; namespaces which is a no-op.
+ #:pid (match args
+ ((pid) (string->number pid))
+ (else (getpid)))
+
+ #:environment-variables
+ (append (list #$@(if tmpdir
+ (list (string-append "TMPDIR=" tmpdir))
+ '())
+
+ ;; Make sure we run in a UTF-8 locale so that
+ ;; 'guix offload' correctly restores nars
+ ;; that contain UTF-8 file names such as
+ ;; 'nss-certs'. See
+ ;; <https://bugs.gnu.org/32942>.
+ (string-append "GUIX_LOCPATH="
+ #$glibc-utf8-locales
+ "/lib/locale")
+ "LC_ALL=en_US.utf8")
+ (if proxy
+ (list (string-append "http_proxy=" proxy)
+ (string-append "https_proxy=" proxy))
+ '()))
+
+ #:log-file #$log-file))))
(stop #~(make-kill-destructor))))))
(define (guix-accounts config)
;; otherwise call 'chown' here, but the problem is that on a COW overlayfs,
;; chown leads to an entire copy of the tree, which is a bad idea.
- ;; Optionally authorize substitute server keys.
- (if authorize-key?
- (substitute-key-authorization keys guix)
- #~#f))))
+ ;; Generate a key pair and optionally authorize substitute server keys.
+ #~(begin
+ (unless (file-exists? "/etc/guix/signing-key.pub")
+ (system* #$(file-append guix "/bin/guix") "archive"
+ "--generate-key"))
+
+ #$(if authorize-key?
+ (substitute-key-authorization keys guix)
+ #~#f)))))
(define* (references-file item #:optional (name "references"))
"Return a file that contains the list of references of ITEM."
(if (struct? item) ;lowerable object
(computed-file name
- (with-imported-modules (source-module-closure
- '((guix build store-copy)))
- #~(begin
- (use-modules (guix build store-copy))
-
- (call-with-output-file #$output
- (lambda (port)
- (write (map store-info-item
- (call-with-input-file "graph"
- read-reference-graph))
- port)))))
+ (with-extensions (list guile-gcrypt) ;for store-copy
+ (with-imported-modules (source-module-closure
+ '((guix build store-copy)))
+ #~(begin
+ (use-modules (guix build store-copy))
+
+ (call-with-output-file #$output
+ (lambda (port)
+ (write (map store-info-item
+ (call-with-input-file "graph"
+ read-reference-graph))
+ port))))))
#:options `(#:local-build? #f
#:references-graphs (("graph" ,item))))
(plain-file name "()")))
(default 80))
(host guix-publish-configuration-host ;string
(default "localhost"))
+ (advertise? guix-publish-advertise? ;boolean
+ (default #f))
(compression guix-publish-configuration-compression
(thunked)
(default (default-compression this-record
(default "nar"))
(cache guix-publish-configuration-cache ;#f | string
(default #f))
+ (cache-bypass-threshold guix-publish-configuration-cache-bypass-threshold
+ (default (* 10 (expt 2 20)))) ;integer
(workers guix-publish-configuration-workers ;#f | integer
(default #f))
(ttl guix-publish-configuration-ttl ;#f | integer
lst))))
(match-record config <guix-publish-configuration>
- (guix port host nar-path cache workers ttl)
+ (guix port host nar-path cache workers ttl cache-bypass-threshold
+ advertise?)
(list (shepherd-service
(provision '(guix-publish))
- (requirement '(guix-daemon))
+ (requirement `(user-processes
+ guix-daemon
+ ,@(if advertise? '(avahi-daemon) '())))
(start #~(make-forkexec-constructor
(list #$(file-append guix "/bin/guix")
"publish" "-u" "guix-publish"
#$@(config->compression-options config)
(string-append "--nar-path=" #$nar-path)
(string-append "--listen=" #$host)
+ #$@(if advertise?
+ #~("--advertise")
+ #~())
#$@(if workers
#~((string-append "--workers="
#$(number->string
"s"))
#~())
#$@(if cache
- #~((string-append "--cache=" #$cache))
+ #~((string-append "--cache=" #$cache)
+ #$(string-append
+ "--cache-bypass-threshold="
+ (number->string
+ cache-bypass-threshold)))
#~()))
;; Make sure we run in a UTF-8 locale so we can produce
udev-configuration make-udev-configuration
udev-configuration?
(udev udev-configuration-udev ;<package>
- (default eudev/btrfs-fix))
+ (default eudev))
(rules udev-configuration-rules ;list of <package>
(default '())))
directory dynamically. Get extra rules from the packages listed in the
@code{rules} field of its value, @code{udev-configuration} object.")))
-(define* (udev-service #:key (udev eudev/btrfs-fix) (rules '()))
+(define* (udev-service #:key (udev eudev) (rules '()))
"Run @var{udev}, which populates the @file{/dev} directory dynamically. Get
extra rules from the packages listed in @var{rules}."
(service udev-service-type
(udev-configuration (udev udev) (rules rules))))
+(define* (udev-rules-service name rules #:key (groups '()))
+ "Return a service that extends udev-service-type with RULES and
+account-service-type with GROUPS as system groups. This works by creating a
+singleton service type NAME-udev-rules, of which the returned service is an
+instance."
+ (let* ((name (symbol-append name '-udev-rules))
+ (account-extension
+ (const (map (lambda (group)
+ (user-group (name group) (system? #t)))
+ groups)))
+ (udev-extension (const (list rules)))
+ (type (service-type
+ (name name)
+ (extensions (list
+ (service-extension
+ account-service-type account-extension)
+ (service-extension
+ udev-service-type udev-extension))))))
+ (service type #f)))
+
(define swap-service-type
(shepherd-service-type
'swap
(lambda (device)
(define requirement
- (if (string-prefix? "/dev/mapper/" device)
+ (if (and (string? device)
+ (string-prefix? "/dev/mapper/" device))
(list (symbol-append 'device-mapping-
(string->symbol (basename device))))
'()))
- (shepherd-service
- (provision (list (symbol-append 'swap- (string->symbol device))))
- (requirement `(udev ,@requirement))
- (documentation "Enable the given swap device.")
- (start #~(lambda ()
- (restart-on-EINTR (swapon #$device))
- #t))
- (stop #~(lambda _
- (restart-on-EINTR (swapoff #$device))
- #f))
- (respawn? #f)))))
+ (define (device-lookup device)
+ ;; The generic 'find-partition' procedures could return a partition
+ ;; that's not swap space, but that's unlikely.
+ (cond ((uuid? device)
+ #~(find-partition-by-uuid #$(uuid-bytevector device)))
+ ((file-system-label? device)
+ #~(find-partition-by-label
+ #$(file-system-label->string device)))
+ (else
+ device)))
+
+ (define service-name
+ (symbol-append 'swap-
+ (string->symbol
+ (cond ((uuid? device)
+ (string-take (uuid->string device) 6))
+ ((file-system-label? device)
+ (file-system-label->string device))
+ (else
+ device)))))
+
+ (with-imported-modules (source-module-closure '((gnu build file-systems)))
+ (shepherd-service
+ (provision (list service-name))
+ (requirement `(udev ,@requirement))
+ (documentation "Enable the given swap device.")
+ (modules `((gnu build file-systems)
+ ,@%default-modules))
+ (start #~(lambda ()
+ (let ((device #$(device-lookup device)))
+ (and device
+ (begin
+ (restart-on-EINTR (swapon device))
+ #t)))))
+ (stop #~(lambda _
+ (let ((device #$(device-lookup device)))
+ (when device
+ (restart-on-EINTR (swapoff device)))
+ #f)))
+ (respawn? #f))))
+ (description "Turn on the virtual memory swap area.")))
(define (swap-service device)
"Return a service that uses @var{device} as a swap device."
(requirement '(user-processes udev dbus-system))
(provision (list (symbol-append 'term- (string->symbol virtual-terminal))))
(start #~(make-forkexec-constructor #$kmscon-command))
- (stop #~(make-kill-destructor)))))))
+ (stop #~(make-kill-destructor)))))
+ (description "Start the @command{kmscon} virtual terminal emulator for the
+Linux @dfn{kernel mode setting} (KMS).")))
(define-record-type* <static-networking>
static-networking make-static-networking
(service guix-service-type)
(service nscd-service-type)
+ (service rottlog-service-type)
+
;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
;; used, so enable them by default. The FUSE and ALSA rules are
;; less critical, but handy.
(rules (list lvm2 fuse alsa-utils crda))))
(service special-files-service-type
- `(("/bin/sh" ,(file-append (canonical-package bash)
- "/bin/sh"))
- ("/usr/bin/env" ,(file-append (canonical-package coreutils)
- "/bin/env"))))))
+ `(("/bin/sh" ,(file-append bash "/bin/sh"))
+ ("/usr/bin/env" ,(file-append coreutils "/bin/env"))))))
;;; base.scm ends here