diff options
Diffstat (limited to 'gnu/services')
-rw-r--r-- | gnu/services/base.scm | 4 | ||||
-rw-r--r-- | gnu/services/ganeti.scm | 1109 | ||||
-rw-r--r-- | gnu/services/networking.scm | 35 | ||||
-rw-r--r-- | gnu/services/nix.scm | 91 | ||||
-rw-r--r-- | gnu/services/science.scm | 57 | ||||
-rw-r--r-- | gnu/services/virtualization.scm | 11 | ||||
-rw-r--r-- | gnu/services/web.scm | 31 |
7 files changed, 1260 insertions, 78 deletions
diff --git a/gnu/services/base.scm b/gnu/services/base.scm index 6ea7ef8e7e..491f35702a 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -177,6 +177,8 @@ pam-limits-service-type pam-limits-service + references-file + %base-services)) ;;; Commentary: @@ -1481,7 +1483,7 @@ archive' public keys, with GUIX." (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 diff --git a/gnu/services/ganeti.scm b/gnu/services/ganeti.scm new file mode 100644 index 0000000000..8d30472371 --- /dev/null +++ b/gnu/services/ganeti.scm @@ -0,0 +1,1109 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2020 Marius Bakke <marius@gnu.org> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (gnu services ganeti) + #:use-module (gnu packages virtualization) + #:use-module (gnu services) + #:use-module (gnu services mcron) + #:use-module (gnu services shepherd) + #:use-module (guix gexp) + #:use-module (guix records) + + #:use-module (srfi srfi-1) + #:use-module (ice-9 match) + + #:export (ganeti-noded-configuration + ganeti-noded-configuration? + ganeti-noded-configuration-ganeti + ganeti-noded-configuration-port + ganeti-noded-configuration-address + ganeti-noded-configuration-interface + ganeti-noded-configuration-max-clients + ganeti-noded-configuration-ssl? + ganeti-noded-configuration-ssl-key + ganeti-noded-configuration-ssl-cert + ganeti-noded-configuration-debug? + ganeti-noded-service-type + + ganeti-confd-configuration + ganeti-confd-configuration? + ganeti-confd-configuration-ganeti + ganeti-confd-configuration-port + ganeti-confd-configuration-address + ganeti-confd-configuration-debug + ganeti-confd-service-type + + ganeti-wconfd-configuration + ganeti-wconfd-configuration? + ganeti-wconfd-configuration-ganeti + ganeti-wconfd-configuration-no-voting? + ganeti-wconfd-configuration-debug? + ganeti-wconfd-service-type + + ganeti-luxid-configuration + ganeti-luxid-configuration? + ganeti-luxid-configuration-ganeti + ganeti-luxid-configuration-no-voting? + ganeti-luxid-configuration-debug? + ganeti-luxid-service-type + + ganeti-rapi-configuration + ganeti-rapi-configuration? + ganeti-rapi-configuration-ganeti + ganeti-rapi-configuration-require-authentication? + ganeti-rapi-configuration-port + ganeti-rapi-configuration-address + ganeti-rapi-configuration-interface + ganeti-rapi-configuration-max-clients + ganeti-rapi-configuration-ssl? + ganeti-rapi-configuration-ssl-key + ganeti-rapi-configuration-ssl-cert + ganeti-rapi-configuration-debug? + ganeti-rapi-service-type + + ganeti-kvmd-configuration + ganeti-kvmd-configuration? + ganeti-kvmd-configuration-ganeti + ganeti-kvmd-configuration-debug? + ganeti-kvmd-service-type + + ganeti-mond-configuration + ganeti-mond-configuration? + ganeti-mond-configuration-ganeti + ganeti-mond-configuration-port + ganeti-mond-configuration-address + ganeti-mond-configuration-debug? + ganeti-mond-service-type + + ganeti-metad-configuration + ganeti-metad-configuration? + ganeti-metad-configuration-ganeti + ganeti-metad-configuration-port + ganeti-metad-configuration-address + ganeti-metad-configuration-debug? + ganeti-metad-service-type + + ganeti-watcher-configuration + ganeti-watcher-configuration? + ganeti-watcher-configuration-ganeti + ganeti-watcher-configuration-schedule + ganeti-watcher-configuration-rapi-ip + ganeti-watcher-configuration-job-age + ganeti-watcher-configuration-verify-disks? + ganeti-watcher-configuration-debug? + ganeti-watcher-service-type + + ganeti-cleaner-configuration + ganeti-cleaner-configuration? + ganeti-cleaner-configuration-ganeti + ganeti-cleaner-configuration-master-schedule + ganeti-cleaner-configuration-node-schedule + ganeti-cleaner-service-type + + ganeti-os + ganeti-os? + ganeti-os-name + ganeti-os-extension + ganeti-os-variants + + ganeti-os-variant + ganeti-os-variant? + ganeti-os-variant-name + ganeti-os-variant-configuration + + %debootstrap-interfaces-hook + %debootstrap-grub-hook + %default-debootstrap-hooks + %default-debootstrap-extra-pkgs + debootstrap-configuration + debootstrap-configuration? + debootstrap-configuration-hooks + debootstrap-configuration-proxy + debootstrap-configuration-mirror + debootstrap-configuration-arch + debootstrap-configuration-suite + debootstrap-configuration-extra-pkgs + debootstrap-configuration-components + debootstrap-configuration-generate-cache? + debootstrap-configuration-clean-cache + debootstrap-configuration-partition-style + debootstrap-configuration-partition-alignment + + debootstrap-variant + debootstrap-os + %default-debootstrap-variants + + guix-variant + guix-os + %default-guix-variants + + %default-ganeti-os + + ganeti-configuration + ganeti-configuration? + ganeti-configuration-noded-configuration + ganeti-configuration-confd-configuration + ganeti-configuration-wconfd-configuration + ganeti-configuration-luxid-configuration + ganeti-configuration-rapi-configuration + ganeti-configuration-kvmd-configuration + ganeti-configuration-mond-configuration + ganeti-configuration-metad-configuration + ganeti-configuration-watcher-configuration + ganeti-configuration-cleaner-configuration + ganeti-configuration-file-storage-paths + ganeti-configuration-os + ganeti-service-type)) + +;;; +;;; Service definitions for running a Ganeti cluster. +;;; +;;; Planned improvements: run daemons (except ganeti-noded) under unprivileged +;;; user accounts and/or containers. The account names must match the ones +;;; given to Ganetis configure script. metad needs "setcap" or root in order +;;; to bind on port 80. + +;; Set PATH so the various daemons are able to find the 'ip' executable, LVM, +;; Ceph, Gluster, etc, without having to add absolute references to everything. +(define %default-ganeti-environment-variables + (list (string-append "PATH=" + (string-join '("/run/setuid-programs" + "/run/current-system/profile/sbin" + "/run/current-system/profile/bin") + ":")))) + +(define-record-type* <ganeti-noded-configuration> + ganeti-noded-configuration make-ganeti-noded-configuration + ganeti-noded-configuration? + (ganeti ganeti-noded-configuration-ganeti ;<package> + (default ganeti)) + (port ganeti-noded-configuration-port ;integer + (default 1811)) + (address ganeti-noded-configuration-address ;string + (default "0.0.0.0")) + (interface ganeti-noded-configuration-interface ;string | #f + (default #f)) + (max-clients ganeti-noded-configuration-max-clients ;integer + (default 20)) + (ssl? ganeti-noded-configuration-ssl? ;Boolean + (default #t)) + (ssl-key ganeti-noded-configuration-ssl-key ;string + (default "/var/lib/ganeti/server.pem")) + (ssl-cert ganeti-noded-configuration-ssl-cert ;string + (default "/var/lib/ganeti/server.pem")) + (debug? ganeti-noded-configuration-debug? ;Boolean + (default #f))) + +(define ganeti-noded-service + (match-lambda + (($ <ganeti-noded-configuration> ganeti port address interface max-clients + ssl? ssl-key ssl-cert debug?) + (list (shepherd-service + (documentation "Run the Ganeti node daemon.") + (provision '(ganeti-noded)) + (requirement '(user-processes networking)) + + ;; If the daemon stops, it is probably for a good reason; + ;; otherwise ganeti-watcher will restart it for us anyway. + (respawn? #f) + + (start #~(make-forkexec-constructor + (list #$(file-append ganeti "/sbin/ganeti-noded") + #$(string-append "--port=" (number->string port)) + #$(string-append "--bind=" address) + #$@(if interface + #~((string-append "--interface=" #$interface)) + #~()) + #$(string-append "--max-clients=" + (number->string max-clients)) + #$@(if ssl? + #~((string-append "--ssl-key=" #$ssl-key) + (string-append "--ssl-cert=" #$ssl-cert)) + #~("--no-ssl")) + #$@(if debug? + #~("--debug") + #~())) + #:environment-variables + '#$%default-ganeti-environment-variables + #:pid-file "/var/run/ganeti/ganeti-noded.pid")) + (stop #~(make-kill-destructor))))))) + +(define ganeti-noded-service-type + (service-type (name 'ganeti-noded) + (extensions + (list (service-extension shepherd-root-service-type + ganeti-noded-service))) + (default-value (ganeti-noded-configuration)) + (description + "@command{ganeti-noded} is the daemon which is responsible +for the node functions in the Ganeti system."))) + +(define-record-type* <ganeti-confd-configuration> + ganeti-confd-configuration make-ganeti-confd-configuration + ganeti-confd-configuration? + (ganeti ganeti-confd-configuration-ganeti ;<package> + (default ganeti)) + (port ganeti-confd-configuration-port ;integer + (default 1814)) + (address ganeti-confd-configuration-address ;string + (default "0.0.0.0")) + (debug? ganeti-confd-configuration-debug? ;Boolean + (default #f))) + +(define ganeti-confd-service + (match-lambda + (($ <ganeti-confd-configuration> ganeti port address debug?) + (list (shepherd-service + (documentation "Run the Ganeti confd daemon.") + (provision '(ganeti-confd)) + (requirement '(user-processes networking)) + (respawn? #f) + (start #~(make-forkexec-constructor + (list #$(file-append ganeti "/sbin/ganeti-confd") + #$(string-append "--port=" (number->string port)) + #$(string-append "--bind=" address) + #$@(if debug? + #~("--debug") + #~())) + #:environment-variables + '#$%default-ganeti-environment-variables + #:pid-file "/var/run/ganeti/ganeti-confd.pid")) + (stop #~(make-kill-destructor))))))) + +(define ganeti-confd-service-type + (service-type (name 'ganeti-confd) + (extensions + (list (service-extension shepherd-root-service-type + ganeti-confd-service))) + (default-value (ganeti-confd-configuration)) + (description + "@command{ganeti-confd} is a daemon used to answer queries +related to the configuration of a Ganeti cluster."))) + +(define-record-type* <ganeti-wconfd-configuration> + ganeti-wconfd-configuration make-ganeti-wconfd-configuration + ganeti-wconfd-configuration? + (ganeti ganeti-wconfd-configuration-ganeti ;<package> + (default ganeti)) + (no-voting? ganeti-wconfd-configuration-no-voting? ;Boolean + (default #f)) + (debug? ganeti-wconfd-configuration-debug? ;Boolean + (default #f))) + +;; If this file exists, the wconfd daemon will be forcefully started even on +;; non-master nodes. It is used to accommodate a master-failover scenario. +(define %wconfd-force-node-hint + "/var/lib/ganeti/guix_wconfd_force_node_hint") + +(define (wconfd-wrapper ganeti args) + ;; Wrapper for the wconfd daemon that looks for the force-node hint. + (program-file + "wconfd-wrapper" + #~(begin + (let ((wconfd #$(file-append ganeti "/sbin/ganeti-wconfd")) + (force-node? (file-exists? #$%wconfd-force-node-hint))) + (if force-node? + (execl wconfd wconfd "--force-node" "--no-voting" "--yes-do-it" #$@args) + (execl wconfd wconfd #$@args)))))) + +(define shepherd-wconfd-force-start-action + ;; Shepherd action to create the force-node hint and start wconfd. + (shepherd-action + (name 'force-start) + (documentation + "Forcefully start wconfd even on non-master nodes (dangerous!).") + (procedure #~(lambda _ + (format #t "Forcefully starting the wconfd daemon...~%") + (action 'ganeti-wconfd 'enable) + (dynamic-wind + (lambda () + (false-if-exception + (call-with-output-file #$%wconfd-force-node-hint + (lambda (port) + (const #t))))) + (lambda () + (action 'ganeti-wconfd 'restart)) + (lambda () + (delete-file #$%wconfd-force-node-hint))) + #t)))) + +(define ganeti-wconfd-service + (match-lambda + (($ <ganeti-wconfd-configuration> ganeti no-voting? debug?) + (list (shepherd-service + (documentation "Run the Ganeti wconfd daemon.") + (provision '(ganeti-wconfd)) + (requirement '(user-processes)) + + ;; Shepherd action to support a master-failover scenario. It is + ;; automatically invoked during 'gnt-cluster master-failover' (see + ;; related Ganeti patch) and not intended for interactive use. + (actions (list shepherd-wconfd-force-start-action)) + + ;; wconfd will disable itself when not running on the master + ;; node. Don't attempt to restart it. + (respawn? #f) + + (start + #~(make-forkexec-constructor + (list #$(wconfd-wrapper ganeti + (append + (if no-voting? + '("--no-voting" "--yes-do-it") + '()) + (if debug? + '("--debug") + '())))) + #:environment-variables + '#$%default-ganeti-environment-variables + #:pid-file "/var/run/ganeti/ganeti-wconfd.pid")) + (stop #~(make-kill-destructor))))))) + +(define ganeti-wconfd-service-type + (service-type (name 'ganeti-wconfd) + (extensions + (list (service-extension shepherd-root-service-type + ganeti-wconfd-service))) + (default-value (ganeti-wconfd-configuration)) + (description + "@command{ganeti-wconfd} is the daemon that has authoritative +knowledge about the configuration and is the only entity that can accept changes +to it. All jobs that need to modify the configuration will do so by sending +appropriate requests to this daemon."))) + +(define-record-type* <ganeti-luxid-configuration> + ganeti-luxid-configuration make-ganeti-luxid-configuration + ganeti-luxid-configuration? + (ganeti ganeti-luxid-configuration-ganeti ;<package> + (default ganeti)) + (no-voting? ganeti-luxid-configuration-no-voting? ;Boolean + (default #f)) + (debug? ganeti-luxid-configuration-debug? ;Boolean + (default #f))) + +(define ganeti-luxid-service + (match-lambda + (($ <ganeti-luxid-configuration> ganeti no-voting? debug?) + (list (shepherd-service + (documentation "Run the Ganeti LUXI daemon.") + (provision '(ganeti-luxid)) + (requirement '(user-processes)) + + ;; This service will automatically disable itself when not + ;; running on the master node. Don't attempt to restart it. + (respawn? #f) + + (start #~(make-forkexec-constructor + (list #$(file-append ganeti "/sbin/ganeti-luxid") + #$@(if no-voting? + #~("--no-voting" "--yes-do-it") + #~()) + #$@(if debug? + #~("--debug") + #~())) + #:environment-variables + '#$%default-ganeti-environment-variables + #:pid-file "/var/run/ganeti/ganeti-luxid.pid")) + (stop #~(make-kill-destructor))))))) + +(define ganeti-luxid-service-type + (service-type (name 'ganeti-luxid) + (extensions + (list (service-extension shepherd-root-service-type + ganeti-luxid-service))) + (default-value (ganeti-luxid-configuration)) + (description + "@command{ganeti-luxid} is a daemon used to answer queries +related to the configuration and the current live state of a Ganeti cluster. +Additionally, it is the autorative daemon for the Ganeti job queue. Jobs can +be submitted via this daemon and it schedules and starts them."))) + +(define-record-type* <ganeti-rapi-configuration> + ganeti-rapi-configuration make-ganeti-rapi-configuration + ganeti-rapi-configuration? + (ganeti ganeti-rapi-configuration-ganeti ;<package> + (default ganeti)) + (require-authentication? + ganeti-rapi-configuration-require-authentication? ;Boolean + (default #f)) + (port ganeti-rapi-configuration-port ;integer + (default 5080)) + (address ganeti-rapi-configuration-address ;string + (default "0.0.0.0")) + (interface ganeti-rapi-configuration-interface ;string | #f + (default #f)) + (max-clients ganeti-rapi-configuration-max-clients ;integer + (default 20)) + (ssl? ganeti-rapi-configuration-ssl? ;Boolean + (default #t)) + (ssl-key ganeti-rapi-configuration-ssl-key ;string + (default "/var/lib/ganeti/server.pem")) + (ssl-cert ganeti-rapi-configuration-ssl-cert ;string + (default "/var/lib/ganeti/server.pem")) + (debug? ganeti-rapi-configuration-debug? ;Boolean + (default #f))) + +(define ganeti-rapi-service + (match-lambda + (($ <ganeti-rapi-configuration> ganeti require-authentication? port address + interface max-clients ssl? ssl-key ssl-cert + debug?) + (list (shepherd-service + (documentation "Run the Ganeti RAPI daemon.") + (provision '(ganeti-rapi)) + (requirement '(user-processes networking)) + + ;; This service will automatically disable itself when not + ;; running on the master node. Don't attempt to restart it. + (respawn? #f) + + (start #~(make-forkexec-constructor + (list #$(file-append ganeti "/sbin/ganeti-rapi") + #$@(if require-authentication? + #~("--require-authentication") + #~()) + #$(string-append "--port=" (number->string port)) + #$(string-append "--bind=" address) + #$@(if interface + #~((string-append "--interface=" #$interface)) + #~()) + #$(string-append "--max-clients=" + (number->string max-clients)) + #$@(if ssl? + #~((string-append "--ssl-key=" #$ssl-key) + (string-append "--ssl-cert=" #$ssl-cert)) + #~("--no-ssl")) + #$@(if debug? + #~("--debug") + #~())) + #:environment-variables + '#$%default-ganeti-environment-variables + #:pid-file "/var/run/ganeti/ganeti-rapi.pid")) + (stop #~(make-kill-destructor))))))) + +(define ganeti-rapi-service-type + (service-type (name 'ganeti-rapi) + (extensions + (list (service-extension shepherd-root-service-type + ganeti-rapi-service))) + (default-value (ganeti-rapi-configuration)) + (description + "@command{ganeti-rapi} is the daemon providing a remote API +for Ganeti clusters."))) + +(define-record-type* <ganeti-kvmd-configuration> + ganeti-kvmd-configuration make-ganeti-kvmd-configuration + ganeti-kvmd-configuration? + (ganeti ganeti-kvmd-configuration-ganeti ;<package> + (default ganeti)) + (debug? ganeti-kvmd-configuration-debug? ;Boolean + (default #f))) + +(define ganeti-kvmd-service + (match-lambda + (($ <ganeti-kvmd-configuration> ganeti debug?) + (list (shepherd-service + (documentation "Run the Ganeti KVM daemon.") + (provision '(ganeti-kvmd)) + (requirement '(user-processes)) + + ;; This service will automatically disable itself when not + ;; needed. Don't attempt to restart it. + (respawn? #f) + + (start #~(make-forkexec-constructor + (list #$(file-append ganeti "/sbin/ganeti-kvmd") + #$@(if debug? + #~("--debug") + #~())) + #:environment-variables + '#$%default-ganeti-environment-variables + #:pid-file "/var/run/ganeti/ganeti-kvmd.pid")) + (stop #~(make-kill-destructor))))))) + +(define ganeti-kvmd-service-type + (service-type (name 'ganeti-kvmd) + (extensions + (list (service-extension shepherd-root-service-type + ganeti-kvmd-service))) + (default-value (ganeti-kvmd-configuration)) + (description + "@command{ganeti-kvmd} is responsible for determining whether +a given KVM instance was shutdown by an administrator or a user. + +The KVM daemon monitors, using @code{inotify}, KVM instances through their QMP +sockets, which are provided by KVM. Using the QMP sockets, the KVM daemon +listens for particular shutdown, powerdown, and stop events which will determine +if a given instance was shutdown by the user or Ganeti, and this result is +communicated to Ganeti via a special file in the filesystem."))) + +(define-record-type* <ganeti-mond-configuration> + ganeti-mond-configuration make-ganeti-mond-configuration + ganeti-mond-configuration? + (ganeti ganeti-mond-configuration-ganeti ;<package> + (default ganeti)) + (port ganeti-mond-configuration-port ;integer + (default 1815)) + (address ganeti-mond-configuration-address ;string + (default "0.0.0.0")) + (debug? ganeti-mond-configuration-debug? ;Boolean + (default #f))) + +(define ganeti-mond-service + (match-lambda + (($ <ganeti-mond-configuration> ganeti port address debug?) + (list (shepherd-service + (documentation "Run the Ganeti monitoring daemon.") + (provision '(ganeti-mond)) + (requirement '(user-processes networking)) + (respawn? #f) + (start #~(make-forkexec-constructor + (list #$(file-append ganeti "/sbin/ganeti-mond") + #$(string-append "--port=" (number->string port)) + #$(string-append "--bind=" address) + #$@(if debug? + #~("--debug") + #~())) + #:pid-file "/var/run/ganeti/ganeti-mond.pid")) + (stop #~(make-kill-destructor))))))) + +(define ganeti-mond-service-type + (service-type (name 'ganeti-mond) + (extensions + (list (service-extension shepherd-root-service-type + ganeti-mond-service))) + (default-value (ganeti-mond-configuration)) + (description + "@command{ganeti-mond} is a daemon providing monitoring +functionality. It is responsible for running the data collectors and to +provide the collected information through a HTTP interface."))) + +(define-record-type* <ganeti-metad-configuration> + ganeti-metad-configuration make-ganeti-metad-configuration + ganeti-metad-configuration? + (ganeti ganeti-metad-configuration-ganeti ;<package> + (default ganeti)) + (port ganeti-metad-configuration-port ;integer + (default 80)) + (address ganeti-metad-configuration-address ;string | #f + (default #f)) + (debug? ganeti-metad-configuration-debug? ;Boolean + (default #f))) + +(define ganeti-metad-service + (match-lambda + (($ <ganeti-metad-configuration> ganeti port address debug?) + (list (shepherd-service + (documentation "Run the Ganeti metadata daemon.") + (provision '(ganeti-metad)) + (requirement '(user-processes networking)) + (respawn? #f) + (start #~(make-forkexec-constructor + (list #$(file-append ganeti "/sbin/ganeti-metad") + #$(string-append "--port=" (number->string port)) + #$@(if address + #~((string-append "--bind=" #$address)) + #~()) + #$@(if debug? + #~("--debug") + #~())) + #:pid-file "/var/run/ganeti/ganeti-metad.pid")) + (stop #~(make-kill-destructor))))))) + +(define ganeti-metad-service-type + (service-type (name 'ganeti-metad) + (extensions + (list (service-extension shepherd-root-service-type + ganeti-metad-service))) + (default-value (ganeti-metad-configuration)) + (description + "@command{ganeti-metad} is a daemon that can be used to pass +information to OS install scripts or instances."))) + +(define-record-type* <ganeti-watcher-configuration> + ganeti-watcher-configuration make-ganeti-watcher-configuration + ganeti-watcher-configuration? + (ganeti ganeti-watcher-configuration-ganeti ;<package> + (default ganeti)) + (schedule ganeti-watcher-configuration-schedule ;list | string + (default '(next-second-from + ;; Run every five minutes. + (next-minute (range 0 60 5))))) + (rapi-ip ganeti-watcher-configuration-rapi-ip ;#f | string + (default #f)) + (job-age ganeti-watcher-configuration-job-age ;integer + (default (* 6 3600))) + (verify-disks? ganeti-watcher-configuration-verify-disks? ;Boolean + (default #t)) + (debug? ganeti-watcher-configuration-debug? ;Boolean + (default #f))) + +(define ganeti-watcher-command + (match-lambda + (($ <ganeti-watcher-configuration> ganeti _ rapi-ip job-age verify-disks? + debug?) + #~(lambda () + (system* #$(file-append ganeti "/sbin/ganeti-watcher") + #$@(if rapi-ip + #~((string-append "--rapi-ip=" #$rapi-ip)) + #~()) + #$(string-append "--job-age=" (number->string job-age)) + #$@(if verify-disks? + #~() + #~("--no-verify-disks")) + #$@(if debug? + #~("--debug") + #~())))))) + +(define (ganeti-watcher-jobs config) + (match config + (($ <ganeti-watcher-configuration> _ schedule) + (list + #~(job #$@(match schedule + ((? string?) + #~(#$schedule)) + ((? list?) + #~('#$schedule))) + #$(ganeti-watcher-command config)))))) + +(define ganeti-watcher-service-type + (service-type (name 'ganeti-watcher) + (extensions + (list (service-extension mcron-service-type + ganeti-watcher-jobs))) + (default-value (ganeti-watcher-configuration)) + (description + "@command{ganeti-watcher} is a periodically run script that +performs a number of maintenance actions on the cluster. It will automatically +restart instances that are marked as ERROR_down, i.e., instances that should be +running, but are not; and it will also try to repair DRBD links in case a +secondary node has rebooted. In addition it is responsible for archiving old +cluster jobs, and it will restart any down Ganeti daemons that are appropriate +for the current node. If the cluster parameter @code{maintain_node_health} is +enabled, the watcher will also shutdown instances and DRBD devices if the node +is declared offline by known master candidates."))) + +(define-record-type* <ganeti-cleaner-configuration> + ganeti-cleaner-configuration make-ganeti-cleaner-configuration + ganeti-cleaner-configuration? + (ganeti ganeti-cleaner-configuration-ganeti ;<package> + (default ganeti)) + (master-schedule ganeti-cleaner-configuration-master-schedule ;list | string + ;; Run the master cleaner at 01:45 every day. + (default "45 1 * * *")) + (node-schedule ganeti-cleaner-configuration-node-schedule ;list | string + ;; Run the node cleaner at 02:45 every day. + (default "45 2 * * *"))) + +(define ganeti-cleaner-jobs + (match-lambda + (($ <ganeti-cleaner-configuration> ganeti master-schedule node-schedule) + (list + #~(job #$@(match master-schedule + ((? string?) + #~(#$master-schedule)) + ((? list?) + #~('#$master-schedule))) + (lambda () + (system* #$(file-append ganeti "/sbin/ganeti-cleaner") + "master"))) + #~(job #$@(match node-schedule + ((? string?) + #~(#$node-schedule)) + ((? list?) + #~('#$node-schedule))) + (lambda () + (system* #$(file-append ganeti "/sbin/ganeti-cleaner") + "node"))))))) + +(define ganeti-cleaner-service-type + (service-type (name 'ganeti-cleaner) + (extensions + (list (service-extension mcron-service-type + ganeti-cleaner-jobs))) + (default-value (ganeti-cleaner-configuration)) + (description + "@command{ganeti-cleaner} is a script that removes old files +from the cluster. When called with @code{node} as argument it removes expired +X509 certificates and keys from @file{/var/run/ganeti/crypto}, as well as +outdated @command{ganeti-watcher} information. + +When called with @code{master} as argument, it instead removes files older +than 21 days from @file{/var/lib/ganeti/queue/archive}."))) + +(define-record-type* <ganeti-configuration> + ganeti-configuration make-ganeti-configuration + ganeti-configuration? + (ganeti ganeti-configuration-ganeti + (default ganeti)) + (noded-configuration ganeti-configuration-noded-configuration + (default (ganeti-noded-configuration))) + (confd-configuration ganeti-configuration-confd-configuration + (default (ganeti-confd-configuration))) + (wconfd-configuration ganeti-configuration-wconfd-configuration + (default (ganeti-wconfd-configuration))) + (luxid-configuration ganeti-configuration-luxid-configuration + (default (ganeti-luxid-configuration))) + (rapi-configuration ganeti-configuration-rapi-configuration + (default (ganeti-rapi-configuration))) + (kvmd-configuration ganeti-configuration-kvmd-configuration + (default (ganeti-kvmd-configuration))) + (mond-configuration ganeti-configuration-mond-configuration + (default (ganeti-mond-configuration))) + (metad-configuration ganeti-configuration-metad-configuration + (default (ganeti-metad-configuration))) + (watcher-configuration ganeti-configuration-watcher-configuration + (default (ganeti-watcher-configuration))) + (cleaner-configuration ganeti-configuration-cleaner-configuration + (default (ganeti-cleaner-configuration))) + (file-storage-paths ganeti-configuration-file-storage-paths ;list of strings | gexp + (default '())) + (os ganeti-configuration-os ;list of <ganeti-os> + (default '()))) + +(define (ganeti-activation config) + (with-imported-modules '((guix build utils)) + #~(begin + (use-modules (guix build utils)) + (for-each mkdir-p + '("/var/log/ganeti" + "/var/log/ganeti/kvm" + "/var/log/ganeti/os" + "/var/lib/ganeti/rapi" + "/var/lib/ganeti/queue" + "/var/lib/ganeti/queue/archive" + "/var/run/ganeti/bdev-cache" + "/var/run/ganeti/crypto" + "/var/run/ganeti/socket" + "/var/run/ganeti/instance-disks" + "/var/run/ganeti/instance-reason" + "/var/run/ganeti/livelocks"))))) + +(define ganeti-shepherd-services + (match-lambda + (($ <ganeti-configuration> _ noded confd wconfd luxid rapi kvmd mond metad) + (append (ganeti-noded-service noded) + (ganeti-confd-service confd) + (ganeti-wconfd-service wconfd) + (ganeti-luxid-service luxid) + (ganeti-rapi-service rapi) + (ganeti-kvmd-service kvmd) + (ganeti-mond-service mond) + (ganeti-metad-service metad))))) + +(define ganeti-mcron-jobs + (match-lambda + (($ <ganeti-configuration> _ _ _ _ _ _ _ _ _ watcher cleaner) + (append (ganeti-watcher-jobs watcher) + (ganeti-cleaner-jobs cleaner))))) + +(define-record-type* <ganeti-os> + ganeti-os make-ganeti-os ganeti-os? + (name ganeti-os-name) ;string + (extension ganeti-os-extension) ;string + (variants ganeti-os-variants ;list of <ganeti-os-variant> + (default '()))) + +(define-record-type* <ganeti-os-variant> + ganeti-os-variant make-ganeti-os-variant ganeti-os-variant? + (name ganeti-os-variant-name) ;string + (configuration ganeti-os-variant-configuration)) ;<file-like> + +(define %debootstrap-interfaces-hook + (file-append ganeti-instance-debootstrap + "/share/doc/ganeti-instance-debootstrap/examples/interfaces")) + +;; The GRUB hook shipped with instance-debootstrap does not work with GRUB2. +;; For convenience, provide one that work with modern Debians here. +;; Note: it would be neat to reuse Guix' bootloader infrastructure instead. +(define %debootstrap-grub-hook + (plain-file "grub" + "#!/usr/bin/env bash +CLEANUP=( ) +cleanup() { + if [ ${#CLEANUP[*]} -gt 0 ]; then + LAST_ELEMENT=$((${#CLEANUP[*]}-1)) + REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0) + for i in $REVERSE_INDEXES; do + ${CLEANUP[$i]} + done + fi +} + +trap cleanup EXIT + +mount -t proc proc $TARGET/proc +CLEANUP+=(\"umount $TARGET/proc\") +mount -t sysfs sysfs $TARGET/sys +CLEANUP+=(\"umount $TARGET/sys\") +mount -o bind /dev $TARGET/dev +CLEANUP+=(\"umount $TARGET/dev\") + +echo ' +GRUB_TIMEOUT_STYLE=menu +GRUB_CMDLINE_LINUX_DEFAULT=\"console=ttyS0,115200 net.ifnames=0\" +GRUB_TERMINAL=\"serial\" +GRUB_SERIAL_COMMAND=\"serial --unit=0 --speed=115200\" +' >> $TARGET/etc/default/grub + +# This PATH is propagated into the chroot and necessary to make grub-install +# and related commands visible. +export PATH=\"/usr/sbin:/usr/bin:/sbin:/bin:$PATH\" + +chroot \"$TARGET\" grub-install $BLOCKDEV +chroot \"$TARGET\" update-grub + +cleanup +trap - EXIT +")) + +(define %default-debootstrap-hooks + `((10-interfaces . ,%debootstrap-interfaces-hook) + (90-grub . ,%debootstrap-grub-hook))) + +(define %default-debootstrap-extra-pkgs + ;; Packages suitable for a fully virtualized KVM guest. + '("acpi-support-base" "udev" "linux-image-amd64" "openssh-server" + "locales-all" "grub-pc")) + +(define-record-type* <debootstrap-configuration> + debootstrap-configuration make-debootstrap-configuration + debootstrap-configuration? + (hooks debootstrap-configuration-hooks ;#f | gexp | '((name . gexp)) + (default %default-debootstrap-hooks)) + (proxy debootstrap-configuration-proxy (default #f)) ;#f | string + (mirror debootstrap-configuration-mirror ;#f | string + (default #f)) + (arch debootstrap-configuration-arch (default #f)) ;#f | string + (suite debootstrap-configuration-suite ;#f | string + (default "stable")) + (extra-pkgs debootstrap-configuration-extra-pkgs ;list of strings + (default %default-debootstrap-extra-pkgs)) + (components debootstrap-configuration-components ;list of strings + (default '())) + (generate-cache? debootstrap-configuration-generate-cache? ;Boolean + (default #t)) + (clean-cache debootstrap-configuration-clean-cache ;#f | integer + (default 14)) + (partition-style debootstrap-configuration-partition-style ;#f | symbol | string + (default 'msdos)) + (partition-alignment debootstrap-configuration-partition-alignment ;#f | integer + (default 2048))) + +(define (hooks->directory hooks) + (match hooks + ((? file-like?) + hooks) + ((? list?) + (let ((names (map car hooks)) + (files (map cdr hooks))) + (with-imported-modules '((guix build utils)) + (computed-file "hooks-union" + #~(begin + (use-modules (guix build utils) + (ice-9 match)) + (mkdir-p #$output) + (with-directory-excursion #$output + (for-each (match-lambda + ((name hook) + (let ((file-name (string-append + #$output "/" + (symbol->string name)))) + ;; Copy to the destination to ensure + ;; the file is executable. + (copy-file hook file-name) + (chmod file-name #o555)))) + '#$(zip names files)))))))) + (_ #f))) + +(define-gexp-compiler (debootstrap-configuration-compiler + (file <debootstrap-configuration>) system target) + (match file + (($ <debootstrap-configuration> hooks proxy mirror arch suite extra-pkgs + components generate-cache? clean-cache + partition-style partition-alignment) + (let ((customize-dir (hooks->directory hooks))) + (gexp->derivation + "debootstrap-variant" + #~(call-with-output-file (ungexp output "out") + (lambda (port) + (display + (string-append + (ungexp-splicing + `(,@(if proxy + `("PROXY=" ,proxy "\n") + '()) + ,@(if mirror + `("MIRROR=" ,mirror "\n") + '()) + ,@(if arch + `("ARCH=" ,arch "\n") + '()) + ,@(if suite + `("SUITE=" ,suite "\n") + '()) + ,@(if (not (null? extra-pkgs)) + `("EXTRA_PKGS=" ,(string-join extra-pkgs ",") "\n") + '()) + ,@(if (not (null? components)) + `("COMPONENTS=" ,(string-join components ",") "\n") + '()) + ,@(if customize-dir + `("CUSTOMIZE_DIR=" ,customize-dir "\n") + '()) + ,@(if generate-cache? + '("GENERATE_CACHE=yes\n") + '("GENERATE_CACHE=no\n")) + ,@(if clean-cache + `("CLEAN_CACHE=" ,(number->string clean-cache) "\n") + '()) + ,@(if partition-style + (if (symbol? partition-style) + `("PARTITION_STYLE=" + ,(symbol->string partition-style) "\n") + `("PARTITION_STYLE=" ,partition-style "\n")) + '()) + ,@(if partition-alignment + `("PARTITION_ALIGNMENT=" + ,(number->string partition-alignment) "\n") + '())))) + port))) + #:local-build? #t))))) + +(define (ganeti-os->directory os) + "Return the derivation to build the configuration directory to be installed +in /etc/ganeti/instance-$os for OS." + (let* ((name (ganeti-os-name os)) + (extension (ganeti-os-extension os)) + (variants (ganeti-os-variants os)) + (names (map ganeti-os-variant-name variants)) + (configs (map ganeti-os-variant-configuration variants))) + (with-imported-modules '((guix build utils)) + (define builder + #~(begin + (use-modules (guix build utils) + (ice-9 format) + (ice-9 match) + (srfi srfi-1)) + (mkdir-p #$output) + (unless (null? '#$names) + (let ((variants-dir (string-append #$output "/variants"))) + (mkdir-p variants-dir) + (call-with-output-file (string-append variants-dir "/variants.list") + (lambda (port) + (format port "~a~%" + (string-join '#$names "\n")))) + (for-each (match-lambda + ((name file) + (symlink file + (string-append variants-dir "/" name + #$extension)))) + + '#$(zip names configs)))))) + + (computed-file (string-append name "-os") builder)))) + +(define (ganeti-directory file-storage-file os) + (let ((dirs (map ganeti-os->directory os)) + (names (map ganeti-os-name os))) + (define builder + #~(begin + (use-modules (ice-9 match)) + (mkdir #$output) + (when #$file-storage-file + (symlink #$file-storage-file + (string-append #$output "/file-storage-paths"))) + (for-each (match-lambda + ((name dest) + (symlink dest + (string-append #$output "/instance-" name)))) + '#$(zip names dirs)))) + (computed-file "etc-ganeti" builder))) + +(define (file-storage-file paths) + (match paths + ((? null?) #f) + ((? list?) (plain-file + "file-storage-paths" + (string-join paths "\n"))) + (_ paths))) + +(define (ganeti-etc-service config) + (list `("ganeti" ,(ganeti-directory + (file-storage-file + (ganeti-configuration-file-storage-paths config)) + (ganeti-configuration-os config))))) + +(define (debootstrap-os variants) + (ganeti-os + (name "debootstrap") + (extension ".conf") + (variants variants))) + +(define (debootstrap-variant name configuration) + (ganeti-os-variant + (name name) + (configuration configuration))) + +(define %default-debootstrap-variants + (list (debootstrap-variant + "default" + (debootstrap-configuration)))) + +(define (guix-os variants) + (ganeti-os + (name "guix") + (extension ".scm") + (variants variants))) + +(define (guix-variant name configuration) + (ganeti-os-variant + (name name) + (configuration configuration))) + +(define %default-guix-variants + (list (guix-variant + "default" + (file-append ganeti-instance-guix + "/share/doc/ganeti-instance-guix/examples/dynamic.scm")))) + +;; The OS configurations usually come with a default OS. To make them work +;; out of the box, follow suit. +(define %default-ganeti-os + (list (debootstrap-os %default-debootstrap-variants) + (guix-os %default-guix-variants))) + +(define ganeti-service-type + (service-type (name 'ganeti) + (extensions + (list (service-extension activation-service-type + ganeti-activation) + (service-extension shepherd-root-service-type + ganeti-shepherd-services) + (service-extension etc-service-type + ganeti-etc-service) + (service-extension profile-service-type + (compose list ganeti-configuration-ganeti)) + (service-extension mcron-service-type + ganeti-mcron-jobs))) + (default-value (ganeti-configuration (os %default-ganeti-os))) + (description + "Ganeti is a family of services that are designed to run +on a fleet of machines and facilitate deployment and maintenance of virtual +servers (@dfn{instances}). It can migrate instances between nodes, automatically +restart failed instances, evacuate nodes, and much more."))) diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index d6b0aee357..353fdce2bb 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -13,6 +13,7 @@ ;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; Copyright © 2019 Sou Bunnbu <iyzsong@member.fsf.org> ;;; Copyright © 2019 Alex Griffin <a@ajgrf.com> +;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re> ;;; ;;; This file is part of GNU Guix. ;;; @@ -33,6 +34,7 @@ #:use-module (gnu services) #:use-module (gnu services base) #:use-module (gnu services configuration) + #:use-module (gnu services linux) #:use-module (gnu services shepherd) #:use-module (gnu services dbus) #:use-module (gnu system shadow) @@ -130,10 +132,10 @@ usb-modeswitch-configuration-usb-modeswitch-data usb-modeswitch-service-type - <wpa-supplicant-configuration> wpa-supplicant-configuration wpa-supplicant-configuration? wpa-supplicant-configuration-wpa-supplicant + wpa-supplicant-configuration-requirement wpa-supplicant-configuration-pid-file wpa-supplicant-configuration-dbus? wpa-supplicant-configuration-interface @@ -1320,6 +1322,8 @@ whatever the thing is supposed to do)."))) wpa-supplicant-configuration? (wpa-supplicant wpa-supplicant-configuration-wpa-supplicant ;<package> (default wpa-supplicant)) + (requirement wpa-supplicant-configuration-requirement ;list of symbols + (default '(user-processes dbus-system loopback syslogd))) (pid-file wpa-supplicant-configuration-pid-file ;string (default "/var/run/wpa_supplicant.pid")) (dbus? wpa-supplicant-configuration-dbus? ;Boolean @@ -1333,12 +1337,12 @@ whatever the thing is supposed to do)."))) (define wpa-supplicant-shepherd-service (match-lambda - (($ <wpa-supplicant-configuration> wpa-supplicant pid-file dbus? interface - config-file extra-options) + (($ <wpa-supplicant-configuration> wpa-supplicant requirement pid-file dbus? + interface config-file extra-options) (list (shepherd-service (documentation "Run the WPA supplicant daemon") (provision '(wpa-supplicant)) - (requirement '(user-processes dbus-system loopback syslogd)) + (requirement requirement) (start #~(make-forkexec-constructor (list (string-append #$wpa-supplicant "/sbin/wpa_supplicant") @@ -1440,10 +1444,10 @@ simulation." (append (hostapd-shepherd-services config #:requirement '(unblocked-wifi - mac-simulation-module)) + kernel-module-loader)) (list (shepherd-service (provision '(unblocked-wifi)) - (requirement '(file-systems mac-simulation-module)) + (requirement '(file-systems kernel-module-loader)) (documentation "Unblock WiFi devices for use by mac80211_hwsim.") (start #~(lambda _ @@ -1451,21 +1455,6 @@ simulation." "unblock" "0") (invoke #$(file-append util-linux "/sbin/rfkill") "unblock" "1"))) - (one-shot? #t)) - (shepherd-service - (provision '(mac-simulation-module)) - (requirement '(file-systems)) - (modules '((guix build utils))) - (documentation - "Load the mac80211_hwsim Linux kernel module.") - (start (with-imported-modules '((guix build utils)) - #~(lambda _ - ;; XXX: We can't use 'load-linux-module*' here because it - ;; expects a flat module directory. - (setenv "LINUX_MODULE_DIRECTORY" - "/run/booted-system/kernel/lib/modules") - (invoke #$(file-append kmod "/bin/modprobe") - "mac80211_hwsim")))) (one-shot? #t))))) (define simulated-wifi-service-type @@ -1473,7 +1462,9 @@ simulation." (name 'simulated-wifi) (extensions (list (service-extension shepherd-root-service-type - simulated-wifi-shepherd-services))) + simulated-wifi-shepherd-services) + (service-extension kernel-module-loader-service-type + (const '("mac80211_hwsim"))))) (default-value (hostapd-configuration (interface "wlan1") (ssid "Test Network"))) diff --git a/gnu/services/nix.scm b/gnu/services/nix.scm index 3c0065207d..75b2df02dc 100644 --- a/gnu/services/nix.scm +++ b/gnu/services/nix.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2019 Oleg Pykhalov <go.wigust@gmail.com> +;;; Copyright © 2019, 2020 Oleg Pykhalov <go.wigust@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -31,7 +31,9 @@ #:use-module (guix store) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) + #:use-module (ice-9 match) #:use-module (ice-9 format) + #:use-module (guix modules) #:export (nix-service-type)) ;;; Commentary: @@ -40,10 +42,17 @@ ;;; ;;; Code: - -;;; -;;; Accounts -;;; +(define-record-type* <nix-configuration> + nix-configuration make-nix-configuration + nix-configuration? + (package nix-configuration-package ;package + (default nix)) + (sandbox nix-configuration-sandbox ;boolean + (default #t)) + (build-sandbox-items nix-configuration-build-sandbox-items ;list of strings + (default '())) + (extra-config nix-configuration-extra-options ;list of strings + (default '()))) ;; Copied from gnu/services/base.scm (define* (nix-build-accounts count #:key @@ -74,32 +83,50 @@ GID." (id 40000)) (nix-build-accounts 10 #:group "nixbld"))) -(define (nix-activation _) - "Return the activation gexp." - (with-imported-modules '((guix build utils)) - #~(begin - (use-modules (guix build utils) - (srfi srfi-26)) - (for-each (cut mkdir-p <>) '("/nix/store" "/nix/var/log" - "/nix/var/nix/gcroots/per-user" - "/nix/var/nix/profiles/per-user")) - (chown "/nix/store" - (passwd:uid (getpw "root")) (group:gid (getpw "nixbld01"))) - (chmod "/nix/store" #o775) - (for-each (cut chmod <> #o777) '("/nix/var/nix/profiles" - "/nix/var/nix/profiles/per-user"))))) +(define nix-activation + ;; Return the activation gexp. + (match-lambda + (($ <nix-configuration> package sandbox build-sandbox-items extra-config) + (with-imported-modules (source-module-closure + '((guix build store-copy))) + #~(begin + (use-modules (guix build utils) + (ice-9 format) + (srfi srfi-1) + (srfi srfi-26)) + (for-each (cut mkdir-p <>) '("/nix/store" "/nix/var/log" + "/nix/var/nix/gcroots/per-user" + "/nix/var/nix/profiles/per-user")) + (chown "/nix/store" + (passwd:uid (getpw "root")) (group:gid (getpw "nixbld01"))) + (chmod "/nix/store" #o775) + (for-each (cut chmod <> #o777) '("/nix/var/nix/profiles" + "/nix/var/nix/profiles/per-user")) + (mkdir-p "/etc/nix") + (with-output-to-file "/etc/nix/nix.conf" + (lambda _ + (format #t "sandbox = ~a~%" (if #$sandbox "true" "false")) + ;; config.nix captures store file names. + (format #t "build-sandbox-paths = ~{~a ~}~%" + (append (append-map (cut call-with-input-file <> read) + '#$(map references-file + (list package))) + '#$build-sandbox-items)) + (for-each (cut display <>) '#$extra-config)))))))) -(define (nix-shepherd-service _) - "Return a <shepherd-service> for Nix." - (list - (shepherd-service - (provision '(nix-daemon)) - (documentation "Run nix-daemon.") - (requirement '()) - (start #~(make-forkexec-constructor - (list (string-append #$nix "/bin/nix-daemon")))) - (respawn? #f) - (stop #~(make-kill-destructor))))) +(define nix-shepherd-service + ;; Return a <shepherd-service> for Nix. + (match-lambda + (($ <nix-configuration> package _ ...) + (list + (shepherd-service + (provision '(nix-daemon)) + (documentation "Run nix-daemon.") + (requirement '()) + (start #~(make-forkexec-constructor + (list (string-append #$package "/bin/nix-daemon")))) + (respawn? #f) + (stop #~(make-kill-destructor))))))) (define nix-service-type (service-type @@ -108,7 +135,7 @@ GID." (list (service-extension shepherd-root-service-type nix-shepherd-service) (service-extension account-service-type nix-accounts) (service-extension activation-service-type nix-activation))) - (default-value '()) - (description "Run the Nix daemon."))) + (description "Run the Nix daemon.") + (default-value (nix-configuration)))) ;;; nix.scm ends here diff --git a/gnu/services/science.scm b/gnu/services/science.scm new file mode 100644 index 0000000000..94ff0f36f2 --- /dev/null +++ b/gnu/services/science.scm @@ -0,0 +1,57 @@ +(define-module (gnu services science) + #:export (<rshiny-configuration> + rshiny-configuration + rshiny-configuration? + rshiny-configuration-package + rshiny-configuration-binary + rshiny-shepherd-service + rshiny-service-type)) + +(use-modules (gnu) + (guix records) + (ice-9 match)) +(use-service-modules shepherd) +(use-package-modules cran) + +(define-record-type* <rshiny-configuration> + rshiny-configuration + make-rshiny-configuration + rshiny-configuration? + (package rshiny-configuration-package ; package + (default r-shiny)) + (binary rshiny-configuration-binary ; string + (default "rshiny"))) + +(define rshiny-shepherd-service + (match-lambda + (($ <rshiny-configuration> package binary) + (list + (shepherd-service + (documentation (string-append "R-Shiny service for " binary)) + (provision (list (symbol-append 'rshiny- (string->symbol + (string-take binary 9))))) + (requirement '(networking)) + (start + #~(exec-command + (list + #$(string-append "/run/current-system/profile/bin/" binary)) + ;#:log-file #$(string-append "/var/log/" binary ".log") ; kills shepherd + #:environment-variables + (list "R_LIBS_USER=/run/current-system/profile/site-library/"))) + (stop #~(make-kill-destructor))))))) + +(define rshiny-service-type + (service-type + (name 'rshiny) + (extensions + (list + (service-extension shepherd-root-service-type + rshiny-shepherd-service) + (service-extension profile-service-type + ;; We want the package installed so that it + ;; pulls in the propagated inputs as well. + (lambda (config) + (list + (rshiny-configuration-package config)))))) + (description + "Run an R-Shiny webapp as a Guix Service."))) diff --git a/gnu/services/virtualization.scm b/gnu/services/virtualization.scm index 36b1738921..b93ed70099 100644 --- a/gnu/services/virtualization.scm +++ b/gnu/services/virtualization.scm @@ -52,10 +52,17 @@ #:export (%hurd-vm-operating-system hurd-vm-configuration + hurd-vm-configuration? + hurd-vm-configuration-os + hurd-vm-configuration-qemu + hurd-vm-configuration-image + hurd-vm-configuration-disk-size + hurd-vm-configuration-memory-size + hurd-vm-configuration-options + hurd-vm-configuration-id + hurd-vm-configuration-net-options hurd-vm-disk-image - hurd-vm-id hurd-vm-net-options - hurd-vm-options hurd-vm-service-type libvirt-configuration diff --git a/gnu/services/web.scm b/gnu/services/web.scm index 63d2324b91..3b9f9e40be 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -37,6 +37,7 @@ #:use-module (gnu system pam) #:use-module (gnu system shadow) #:use-module (gnu packages admin) + #:use-module (gnu packages base) #:use-module (gnu packages databases) #:use-module (gnu packages web) #:use-module (gnu packages patchutils) @@ -58,20 +59,17 @@ #:use-module (srfi srfi-9) #:use-module (ice-9 match) #:use-module (ice-9 format) - #:export (<httpd-configuration> - httpd-configuration + #:export (httpd-configuration httpd-configuration? httpd-configuration-package httpd-configuration-pid-file httpd-configuration-config - <httpd-virtualhost> httpd-virtualhost httpd-virtualhost? httpd-virtualhost-addresses-and-ports httpd-virtualhost-contents - <httpd-config-file> httpd-config-file httpd-config-file? httpd-config-file-modules @@ -83,14 +81,12 @@ httpd-config-file-user httpd-config-file-group - <httpd-module> httpd-module httpd-module? %default-httpd-modules httpd-service-type - <nginx-configuration> nginx-configuration nginx-configuration? nginx-configuartion-nginx @@ -105,7 +101,6 @@ nginx-configuration-extra-content nginx-configuration-file - <nginx-server-configuration> nginx-server-configuration nginx-server-configuration? nginx-server-configuration-listen @@ -118,19 +113,16 @@ nginx-server-configuration-server-tokens? nginx-server-configuration-raw-content - <nginx-upstream-configuration> nginx-upstream-configuration nginx-upstream-configuration? nginx-upstream-configuration-name nginx-upstream-configuration-servers - <nginx-location-configuration> nginx-location-configuration nginx-location-configuration? nginx-location-configuration-uri nginx-location-configuration-body - <nginx-named-location-configuration> nginx-named-location-configuration nginx-named-location-configuration? nginx-named-location-configuration-name @@ -143,7 +135,6 @@ fcgiwrap-configuration? fcgiwrap-service-type - <php-fpm-configuration> php-fpm-configuration make-php-fpm-configuration php-fpm-configuration? @@ -161,7 +152,6 @@ php-fpm-configuration-workers-log-file php-fpm-configuration-file - <php-fpm-dynamic-process-manager-configuration> php-fpm-dynamic-process-manager-configuration make-php-fpm-dynamic-process-manager-configuration php-fpm-dynamic-process-manager-configuration? @@ -170,13 +160,11 @@ php-fpm-dynamic-process-manager-configuration-min-spare-servers php-fpm-dynamic-process-manager-configuration-max-spare-servers - <php-fpm-static-process-manager-configuration> php-fpm-static-process-manager-configuration make-php-fpm-static-process-manager-configuration php-fpm-static-process-manager-configuration? php-fpm-static-process-manager-configuration-max-children - <php-fpm-on-demand-process-manager-configuration> php-fpm-on-demand-process-manager-configuration make-php-fpm-on-demand-process-manager-configuration php-fpm-on-demand-process-manager-configuration? @@ -192,7 +180,6 @@ hpcguix-web-configuration? hpcguix-web-service-type - <tailon-configuration-file> tailon-configuration-file tailon-configuration-file? tailon-configuration-file-files @@ -206,7 +193,6 @@ tailon-configuration-file-http-auth tailon-configuration-file-users - <tailon-configuration> tailon-configuration tailon-configuration? tailon-configuration-config-file @@ -214,7 +200,6 @@ tailon-service-type - <varnish-configuration> varnish-configuration varnish-configuration? varnish-configuration-package @@ -228,7 +213,6 @@ varnish-service-type - <patchwork-database-configuration> patchwork-database-configuration patchwork-database-configuration? patchwork-database-configuration-engine @@ -238,7 +222,6 @@ patchwork-database-configuration-host patchwork-database-configuration-port - <patchwork-settings-module> patchwork-settings-module patchwork-settings-module? patchwork-settings-module-database-configuration @@ -253,7 +236,6 @@ patchwork-settings-module-force-https-links? patchwork-settings-module-extra-settings - <patchwork-configuration> patchwork-configuration patchwork-configuration? patchwork-configuration-patchwork @@ -263,7 +245,6 @@ patchwork-virtualhost patchwork-service-type - <mumi-configuration> mumi-configuration mumi-configuration? mumi-configuration-mumi @@ -1720,6 +1701,11 @@ WSGIPassAuthorization On (shell (file-append shadow "/sbin/nologin"))))) (define (mumi-shepherd-services config) + (define environment + #~(list "LC_ALL=en_US.utf8" + (string-append "GUIX_LOCPATH=" #$glibc-utf8-locales + "/lib/locale"))) + (match config (($ <mumi-configuration> mumi mailer? sender smtp) (list (shepherd-service @@ -1729,6 +1715,7 @@ WSGIPassAuthorization On (start #~(make-forkexec-constructor `(#$(file-append mumi "/bin/mumi") "web" ,@(if #$mailer? '() '("--disable-mailer"))) + #:environment-variables #$environment #:user "mumi" #:group "mumi" #:log-file "/var/log/mumi.log")) (stop #~(make-kill-destructor))) @@ -1738,6 +1725,7 @@ WSGIPassAuthorization On (requirement '(networking)) (start #~(make-forkexec-constructor '(#$(file-append mumi "/bin/mumi") "worker") + #:environment-variables #$environment #:user "mumi" #:group "mumi" #:log-file "/var/log/mumi.worker.log")) (stop #~(make-kill-destructor))) @@ -1753,6 +1741,7 @@ WSGIPassAuthorization On ,@(if #$smtp (list (string-append "--smtp=" #$smtp)) '())) + #:environment-variables #$environment #:user "mumi" #:group "mumi" #:log-file "/var/log/mumi.mailer.log")) (stop #~(make-kill-destructor))))))) |