diff options
Diffstat (limited to 'gnu/services/base.scm')
-rw-r--r-- | gnu/services/base.scm | 278 |
1 files changed, 111 insertions, 167 deletions
diff --git a/gnu/services/base.scm b/gnu/services/base.scm index 8d9a563e2b..2913478e4a 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -12,6 +12,7 @@ ;;; 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. ;;; @@ -61,11 +62,11 @@ #:use-module (srfi srfi-26) #:use-module (ice-9 match) #:use-module (ice-9 format) + #:re-export (user-processes-service-type) ;backwards compatibility #: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 @@ -92,6 +93,7 @@ udev-service udev-rule file->udev-rule + udev-rules-service login-configuration login-configuration? @@ -187,128 +189,6 @@ ;;; -;;; 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}."))) - - -;;; ;;; File systems. ;;; @@ -679,7 +559,7 @@ down."))) (documentation "Add TRNG to entropy pool.") (requirement '(udev)) (provision '(trng)) - (start #~(make-forkexec-constructor #$@rngd-command)) + (start #~(make-forkexec-constructor '#$rngd-command)) (stop #~(make-kill-destructor)))))) (define* (rngd-service #:key @@ -1436,10 +1316,17 @@ Service Switch}, for an example." (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")) + (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)))))) ;; Snippet adapted from the GNU inetutils manual. @@ -1633,6 +1520,30 @@ archive' public keys, with GUIX." (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 (guix-shepherd-service config) "Return a <shepherd-service> for the Guix daemon service with CONFIG." (match-record config <guix-configuration> @@ -1644,47 +1555,58 @@ archive' public keys, with GUIX." (documentation "Run the Guix daemon.") (provision '(guix-daemon)) (requirement '(user-processes)) + (actions (list shepherd-set-http-proxy-action)) (modules '((srfi srfi-1))) (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)) + #~(lambda _ + (define proxy + ;; HTTP/HTTPS proxy. The 'http_proxy' variable is set by + ;; the 'set-http-proxy' action. + (or (getenv "http_proxy") #$http-proxy)) + + (fork+exec-command + (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 + (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) @@ -2122,6 +2044,26 @@ 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 @@ -2444,6 +2386,8 @@ to handle." (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. |