From 2e328698248b4b5d7ed07af89796acd9bfadbaff Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 24 Nov 2016 21:27:21 +0100 Subject: services: Move polkit to (gnu services dbus). * gnu/services/desktop.scm (, %polkit-accounts) (%polkit-pam-services, polkit-directory, polkit-etc-files) (polkit-setuid-programs, polkit-service-type, polkit-service): Move to... * gnu/services/dbus.scm: ... here. --- gnu/services/dbus.scm | 94 +++++++++++++++++++++++++++++++++++++++++++++++- gnu/services/desktop.scm | 93 ----------------------------------------------- 2 files changed, 93 insertions(+), 94 deletions(-) (limited to 'gnu/services') diff --git a/gnu/services/dbus.scm b/gnu/services/dbus.scm index 876f56d45f..26390a4acd 100644 --- a/gnu/services/dbus.scm +++ b/gnu/services/dbus.scm @@ -21,7 +21,9 @@ #:use-module (gnu services) #:use-module (gnu services shepherd) #:use-module (gnu system shadow) + #:use-module (gnu system pam) #:use-module ((gnu packages glib) #:select (dbus)) + #:use-module (gnu packages polkit) #:use-module (gnu packages admin) #:use-module (guix gexp) #:use-module (guix records) @@ -30,7 +32,10 @@ #:export (dbus-configuration dbus-configuration? dbus-root-service-type - dbus-service)) + dbus-service + + polkit-service-type + polkit-service)) ;;; ;;; D-Bus. @@ -218,4 +223,91 @@ and policy files. For example, to allow avahi-daemon to use the system bus, (dbus-configuration (dbus dbus) (services services)))) + +;;; +;;; Polkit privilege management service. +;;; + +(define-record-type* + polkit-configuration make-polkit-configuration + polkit-configuration? + (polkit polkit-configuration-polkit ; + (default polkit)) + (actions polkit-configuration-actions ;list of + (default '()))) + +(define %polkit-accounts + (list (user-group (name "polkitd") (system? #t)) + (user-account + (name "polkitd") + (group "polkitd") + (system? #t) + (comment "Polkit daemon user") + (home-directory "/var/empty") + (shell "/run/current-system/profile/sbin/nologin")))) + +(define %polkit-pam-services + (list (unix-pam-service "polkit-1"))) + +(define (polkit-directory packages) + "Return a directory containing an @file{actions} and possibly a +@file{rules.d} sub-directory, for use as @file{/etc/polkit-1}." + (with-imported-modules '((guix build union)) + (computed-file "etc-polkit-1" + #~(begin + (use-modules (guix build union) (srfi srfi-26)) + + (union-build #$output + (map (cut string-append <> + "/share/polkit-1") + (list #$@packages))))))) + +(define polkit-etc-files + (match-lambda + (($ polkit packages) + `(("polkit-1" ,(polkit-directory (cons polkit packages))))))) + +(define polkit-setuid-programs + (match-lambda + (($ polkit) + (list (file-append polkit "/lib/polkit-1/polkit-agent-helper-1") + (file-append polkit "/bin/pkexec"))))) + +(define polkit-service-type + (service-type (name 'polkit) + (extensions + (list (service-extension account-service-type + (const %polkit-accounts)) + (service-extension pam-root-service-type + (const %polkit-pam-services)) + (service-extension dbus-root-service-type + (compose + list + polkit-configuration-polkit)) + (service-extension etc-service-type + polkit-etc-files) + (service-extension setuid-program-service-type + polkit-setuid-programs))) + + ;; Extensions are lists of packages that provide polkit rules + ;; or actions under share/polkit-1/{actions,rules.d}. + (compose concatenate) + (extend (lambda (config actions) + (polkit-configuration + (inherit config) + (actions + (append (polkit-configuration-actions config) + actions))))))) + +(define* (polkit-service #:key (polkit polkit)) + "Return a service that runs the +@uref{http://www.freedesktop.org/wiki/Software/polkit/, Polkit privilege +management service}, which allows system administrators to grant access to +privileged operations in a structured way. By querying the Polkit service, a +privileged system component can know when it should grant additional +capabilities to ordinary users. For example, an ordinary user can be granted +the capability to suspend the system if the user is logged in locally." + (service polkit-service-type + (polkit-configuration (polkit polkit)))) + ;;; dbus.scm ends here diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm index dfd1ea6e92..7555780ade 100644 --- a/gnu/services/desktop.scm +++ b/gnu/services/desktop.scm @@ -37,7 +37,6 @@ #:use-module (gnu packages gnome) #:use-module (gnu packages xfce) #:use-module (gnu packages avahi) - #:use-module (gnu packages polkit) #:use-module (gnu packages xdisorg) #:use-module (gnu packages suckless) #:use-module (gnu packages linux) @@ -68,11 +67,6 @@ bluetooth-service - polkit-configuration - polkit-configuration? - polkit-service - polkit-service-type - elogind-configuration elogind-configuration? elogind-service @@ -413,93 +407,6 @@ Users need to be in the @code{lp} group to access the D-Bus service. " (service bluetooth-service-type bluez)) - -;;; -;;; Polkit privilege management service. -;;; - -(define-record-type* - polkit-configuration make-polkit-configuration - polkit-configuration? - (polkit polkit-configuration-polkit ; - (default polkit)) - (actions polkit-configuration-actions ;list of - (default '()))) - -(define %polkit-accounts - (list (user-group (name "polkitd") (system? #t)) - (user-account - (name "polkitd") - (group "polkitd") - (system? #t) - (comment "Polkit daemon user") - (home-directory "/var/empty") - (shell "/run/current-system/profile/sbin/nologin")))) - -(define %polkit-pam-services - (list (unix-pam-service "polkit-1"))) - -(define (polkit-directory packages) - "Return a directory containing an @file{actions} and possibly a -@file{rules.d} sub-directory, for use as @file{/etc/polkit-1}." - (with-imported-modules '((guix build union)) - (computed-file "etc-polkit-1" - #~(begin - (use-modules (guix build union) (srfi srfi-26)) - - (union-build #$output - (map (cut string-append <> - "/share/polkit-1") - (list #$@packages))))))) - -(define polkit-etc-files - (match-lambda - (($ polkit packages) - `(("polkit-1" ,(polkit-directory (cons polkit packages))))))) - -(define polkit-setuid-programs - (match-lambda - (($ polkit) - (list (file-append polkit "/lib/polkit-1/polkit-agent-helper-1") - (file-append polkit "/bin/pkexec"))))) - -(define polkit-service-type - (service-type (name 'polkit) - (extensions - (list (service-extension account-service-type - (const %polkit-accounts)) - (service-extension pam-root-service-type - (const %polkit-pam-services)) - (service-extension dbus-root-service-type - (compose - list - polkit-configuration-polkit)) - (service-extension etc-service-type - polkit-etc-files) - (service-extension setuid-program-service-type - polkit-setuid-programs))) - - ;; Extensions are lists of packages that provide polkit rules - ;; or actions under share/polkit-1/{actions,rules.d}. - (compose concatenate) - (extend (lambda (config actions) - (polkit-configuration - (inherit config) - (actions - (append (polkit-configuration-actions config) - actions))))))) - -(define* (polkit-service #:key (polkit polkit)) - "Return a service that runs the -@uref{http://www.freedesktop.org/wiki/Software/polkit/, Polkit privilege -management service}, which allows system administrators to grant access to -privileged operations in a structured way. By querying the Polkit service, a -privileged system component can know when it should grant additional -capabilities to ordinary users. For example, an ordinary user can be granted -the capability to suspend the system if the user is logged in locally." - (service polkit-service-type - (polkit-configuration (polkit polkit)))) - ;;; ;;; Colord D-Bus service. -- cgit 1.4.1 From 89007a0bb76fb4e0404e0baf72b939f5d91f08f0 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 24 Nov 2016 21:29:13 +0100 Subject: services: network-manager: Install polkit actions. Reported by Chris Marusich at . * gnu/services/networking.scm (network-manager-service-type)[extensions]: Add POLKIT-SERVICE-TYPE. --- gnu/services/networking.scm | 1 + 1 file changed, 1 insertion(+) (limited to 'gnu/services') diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index 5a83240d77..7d3626b935 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -695,6 +695,7 @@ and @command{wicd-curses} user interfaces." (list (service-extension shepherd-root-service-type network-manager-shepherd-service) (service-extension dbus-root-service-type list) + (service-extension polkit-service-type list) (service-extension activation-service-type (const %network-manager-activation)) ;; Add network-manager to the system profile. -- cgit 1.4.1 From 030f59fac939b4c747f3fa8037b2db6c1030f0eb Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 24 Nov 2016 21:35:57 +0100 Subject: services: network-manager: Depend on 'wpa-supplicant'. Suggested by Chris Marusich . * gnu/services/networking.scm (network-manager-shepherd-service) [requirement]: Add 'wpa-supplicant'. --- gnu/services/networking.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnu/services') diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index 7d3626b935..bbb9053008 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -682,7 +682,7 @@ and @command{wicd-curses} user interfaces." (list (shepherd-service (documentation "Run the NetworkManager.") (provision '(networking)) - (requirement '(user-processes dbus-system loopback)) + (requirement '(user-processes dbus-system wpa-supplicant loopback)) (start #~(make-forkexec-constructor (list (string-append #$network-manager "/sbin/NetworkManager") -- cgit 1.4.1 From f88371e86602a9b3d86f2030709f719778613552 Mon Sep 17 00:00:00 2001 From: 宋文武 Date: Mon, 21 Nov 2016 20:41:17 +0800 Subject: services: Add opensmtpd service. * gnu/services/mail.scm (): New record type. (%default-opensmtpd-config-file, %opensmtpd-accounts): New variables. (opensmtpd-shepherd-service, opensmtpd-activation): New procedures. (opensmtpd-service-type): New variable. * doc/guix.texi (Mail Services): Document it. --- doc/guix.texi | 42 ++++++++++++++++++++------ gnu/services/mail.scm | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 10 deletions(-) (limited to 'gnu/services') diff --git a/doc/guix.texi b/doc/guix.texi index b8e37055e6..137fec8d7a 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -10075,16 +10075,11 @@ For MariaDB, the root password is empty. @cindex mail @cindex email The @code{(gnu services mail)} module provides Guix service definitions -for mail services. Currently the only implemented service is Dovecot, -an IMAP, POP3, and LMTP server. +for email services: IMAP, POP3, and LMTP servers, as well as mail +transport agents (MTAs). Lots of acronyms! These services are detailed +in the subsections below. -Guix does not yet have a mail transfer agent (MTA), although for some -lightweight purposes the @code{esmtp} relay-only MTA may suffice. Help -is needed to properly integrate a full MTA, such as Postfix. Patches -welcome! - -To add an IMAP/POP3 server to a GuixSD system, add a -@code{dovecot-service} to the operating system definition: +@subsubheading Dovecot Service @deffn {Scheme Procedure} dovecot-service [#:config (dovecot-configuration)] Return a service that runs the Dovecot IMAP/POP3/LMTP mail server. @@ -11440,6 +11435,35 @@ could instantiate a dovecot service like this: (string ""))) @end example +@subsubheading OpenSMTPD Service + +@deffn {Scheme Variable} opensmtpd-service-type +This is the type of the @uref{https://www.opensmtpd.org, OpenSMTPD} +service, whose value should be an @code{opensmtpd-configuration} object +as in this example: + +@example +(service opensmtpd-service-type + (opensmtpd-configuration + (config-file (local-file "./my-smtpd.conf")))) +@end example +@end deffn + +@deftp {Data Type} opensmtpd-configuration +Data type regresenting the configuration of opensmtpd. + +@table @asis +@item @code{package} (default: @var{opensmtpd}) +Package object of the OpenSMTPD SMTP server. + +@item @code{config-file} (default: @var{%default-opensmtpd-file}) +File-like object of the OpenSMTPD configuration file to use. By default +it listens on the loopback network interface, and allows for mail from +users and daemons on the local machine, as well as permitting email to +remote servers. Run @command{man smtpd.conf} for more information. + +@end table +@end deftp @node Kerberos Services @subsubsection Kerberos Services diff --git a/gnu/services/mail.scm b/gnu/services/mail.scm index cb0f119f43..f7ab9516ba 100644 --- a/gnu/services/mail.scm +++ b/gnu/services/mail.scm @@ -51,7 +51,12 @@ protocol-configuration plugin-configuration mailbox-configuration - namespace-configuration)) + namespace-configuration + + opensmtpd-configuration + opensmtpd-configuration? + opensmtpd-service-type + %default-opensmtpd-config-file)) ;;; Commentary: ;;; @@ -1691,3 +1696,78 @@ by @code{dovecot-configuration}. @var{config} may also be created by (format #t "@end deftypevr\n\n"))) fields)))) (generate 'dovecot-configuration)) + + +;;; +;;; OpenSMTPD. +;;; + +(define-record-type* + opensmtpd-configuration make-opensmtpd-configuration + opensmtpd-configuration? + (package opensmtpd-configuration-package + (default opensmtpd)) + (config-file opensmtpd-configuration-config-file + (default %default-opensmtpd-config-file))) + +(define %default-opensmtpd-config-file + (plain-file "smtpd.conf" " +listen on lo +accept from any for local deliver to mbox +accept from local for any relay +")) + +(define opensmtpd-shepherd-service + (match-lambda + (($ package config-file) + (list (shepherd-service + (provision '(smtpd)) + (requirement '(loopback)) + (documentation "Run the OpenSMTPD daemon.") + (start (let ((smtpd (file-append package "/sbin/smtpd"))) + #~(make-forkexec-constructor + (list #$smtpd "-f" #$config-file) + #:pid-file "/var/run/smtpd.pid"))) + (stop #~(make-kill-destructor))))))) + +(define %opensmtpd-accounts + (list (user-group + (name "smtpq") + (system? #t)) + (user-account + (name "smtpd") + (group "nogroup") + (system? #t) + (comment "SMTP Daemon") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin"))) + (user-account + (name "smtpq") + (group "smtpq") + (system? #t) + (comment "SMTPD Queue") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin"))))) + +(define opensmtpd-activation + (match-lambda + (($ package config-file) + (let ((smtpd (file-append package "/sbin/smtpd"))) + #~(begin + ;; Create mbox and spool directories. + (mkdir-p "/var/mail") + (mkdir-p "/var/spool/smtpd") + (chmod "/var/spool/smtpd" #o711)))))) + +(define opensmtpd-service-type + (service-type + (name 'opensmtpd) + (extensions + (list (service-extension account-service-type + (const %opensmtpd-accounts)) + (service-extension activation-service-type + opensmtpd-activation) + (service-extension profile-service-type + (compose list opensmtpd-configuration-package)) + (service-extension shepherd-root-service-type + opensmtpd-shepherd-service))))) -- cgit 1.4.1 From fc5dc4e81cacc4e0dcd81863e505ce5b314264c6 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Thu, 24 Nov 2016 08:15:55 +0100 Subject: gnu: Whitespace changes * gnu/services/kerberos.scm: Fold lines to 80 character limit. --- gnu/services/kerberos.scm | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'gnu/services') diff --git a/gnu/services/kerberos.scm b/gnu/services/kerberos.scm index 144c71bba0..a56f63082c 100644 --- a/gnu/services/kerberos.scm +++ b/gnu/services/kerberos.scm @@ -38,15 +38,17 @@ "Return a PAM service for Kerberos authentication." (lambda (pam) (define pam-krb5-module - #~(string-append #$(pam-krb5-configuration-pam-krb5 config) "/lib/security/pam_krb5.so")) + #~(string-append #$(pam-krb5-configuration-pam-krb5 config) + "/lib/security/pam_krb5.so")) (let ((pam-krb5-sufficient (pam-entry (control "sufficient") (module pam-krb5-module) - (arguments (list - (format #f "minimum_uid=~a" - (pam-krb5-configuration-minimum-uid config))))))) + (arguments + (list + (format #f "minimum_uid=~a" + (pam-krb5-configuration-minimum-uid config))))))) (pam-service (inherit pam) (auth (cons* pam-krb5-sufficient -- cgit 1.4.1 From 5305ed20027a32ff1221cac6a131849852e807ba Mon Sep 17 00:00:00 2001 From: Julien Lepiller Date: Wed, 23 Nov 2016 21:43:42 +0100 Subject: services: Factorize configuration abstraction. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gnu/services/mail.scm and gnu/services/cups.scm (&configuration-error) (configuration-error, configuration-field-error) (configuration-missing-field, configuration-field, serialize-configuration) (validate-configuration, define-configuration, uglify-field-name) (serialize-field, serialize-package, serialize-string) (serialize-space-separated-string-list, space-separated-string-list?) (serialize-file-name, file-name?, serialize-field-name) (generate-documentation): Move duplicate code... * gnu/services/configuration.scm: ...to this new file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add configuration.scm. Signed-off-by: Ludovic Courtès --- gnu/local.mk | 1 + gnu/services/configuration.scm | 205 +++++++++++++++++++++++++++++++++++++++++ gnu/services/cups.scm | 180 +++--------------------------------- gnu/services/mail.scm | 183 +++--------------------------------- 4 files changed, 233 insertions(+), 336 deletions(-) create mode 100644 gnu/services/configuration.scm (limited to 'gnu/services') diff --git a/gnu/local.mk b/gnu/local.mk index 1b2bb4786d..f3f8772337 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -399,6 +399,7 @@ GNU_SYSTEM_MODULES = \ %D%/services/admin.scm \ %D%/services/avahi.scm \ %D%/services/base.scm \ + %D%/services/configuration.scm \ %D%/services/cups.scm \ %D%/services/databases.scm \ %D%/services/dbus.scm \ diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm new file mode 100644 index 0000000000..9f28aabc96 --- /dev/null +++ b/gnu/services/configuration.scm @@ -0,0 +1,205 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2015 Andy Wingo +;;; +;;; 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 . + +(define-module (gnu services configuration) + #:use-module (guix packages) + #:use-module (guix records) + #:use-module (guix gexp) + #:autoload (texinfo) (texi-fragment->stexi) + #:autoload (texinfo serialize) (stexi->texi) + #:use-module (ice-9 match) + #:use-module ((srfi srfi-1) #:select (append-map)) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) + #:export (configuration-field + configuration-field-name + configuration-missing-field + configuration-field-error + serialize-configuration + define-configuration + validate-configuration + generate-documentation + serialize-field + serialize-string + serialize-name + serialize-space-separated-string-list + space-separated-string-list? + serialize-file-name + file-name? + serialize-boolean + serialize-package)) + +;;; Commentary: +;;; +;;; Syntax for creating Scheme bindings to complex configuration files. +;;; +;;; Code: + +(define-condition-type &configuration-error &error + configuration-error?) + +(define (configuration-error message) + (raise (condition (&message (message message)) + (&configuration-error)))) +(define (configuration-field-error field val) + (configuration-error + (format #f "Invalid value for field ~a: ~s" field val))) +(define (configuration-missing-field kind field) + (configuration-error + (format #f "~a configuration missing required field ~a" kind field))) + +(define-record-type* + configuration-field make-configuration-field configuration-field? + (name configuration-field-name) + (type configuration-field-type) + (getter configuration-field-getter) + (predicate configuration-field-predicate) + (serializer configuration-field-serializer) + (default-value-thunk configuration-field-default-value-thunk) + (documentation configuration-field-documentation)) + +(define (serialize-configuration config fields) + (for-each (lambda (field) + ((configuration-field-serializer field) + (configuration-field-name field) + ((configuration-field-getter field) config))) + fields)) + +(define (validate-configuration config fields) + (for-each (lambda (field) + (let ((val ((configuration-field-getter field) config))) + (unless ((configuration-field-predicate field) val) + (configuration-field-error + (configuration-field-name field) val)))) + fields)) + +(define-syntax define-configuration + (lambda (stx) + (define (id ctx part . parts) + (let ((part (syntax->datum part))) + (datum->syntax + ctx + (match parts + (() part) + (parts (symbol-append part + (syntax->datum (apply id ctx parts)))))))) + (syntax-case stx () + ((_ stem (field (field-type def) doc) ...) + (with-syntax (((field-getter ...) + (map (lambda (field) + (id #'stem #'stem #'- field)) + #'(field ...))) + ((field-predicate ...) + (map (lambda (type) + (id #'stem type #'?)) + #'(field-type ...))) + ((field-serializer ...) + (map (lambda (type) + (id #'stem #'serialize- type)) + #'(field-type ...)))) + #`(begin + (define-record-type* #,(id #'stem #'< #'stem #'>) + #,(id #'stem #'% #'stem) + #,(id #'stem #'make- #'stem) + #,(id #'stem #'stem #'?) + (field field-getter (default def)) + ...) + (define #,(id #'stem #'stem #'-fields) + (list (configuration-field + (name 'field) + (type 'field-type) + (getter field-getter) + (predicate field-predicate) + (serializer field-serializer) + (default-value-thunk (lambda () def)) + (documentation doc)) + ...)) + (define-syntax-rule (stem arg (... ...)) + (let ((conf (#,(id #'stem #'% #'stem) arg (... ...)))) + (validate-configuration conf + #,(id #'stem #'stem #'-fields)) + conf)))))))) + +(define (uglify-field-name field-name) + (let ((str (symbol->string field-name))) + (string-concatenate + (map string-titlecase + (string-split (if (string-suffix? "?" str) + (substring str 0 (1- (string-length str))) + str) + #\-))))) + +(define (serialize-field field-name val) + (format #t "~a ~a\n" (uglify-field-name field-name) val)) + +(define (serialize-package field-name val) + #f) + +(define (serialize-string field-name val) + (serialize-field field-name val)) + +(define (space-separated-string-list? val) + (and (list? val) + (and-map (lambda (x) + (and (string? x) (not (string-index x #\space)))) + val))) +(define (serialize-space-separated-string-list field-name val) + (serialize-field field-name (string-join val " "))) + +(define (file-name? val) + (and (string? val) + (string-prefix? "/" val))) +(define (serialize-file-name field-name val) + (serialize-string field-name val)) + +(define (serialize-boolean field-name val) + (serialize-string field-name (if val "yes" "no"))) + +;; A little helper to make it easier to document all those fields. +(define (generate-documentation documentation documentation-name) + (define (str x) (object->string x)) + (define (generate configuration-name) + (match (assq-ref documentation configuration-name) + ((fields . sub-documentation) + `((para "Available " (code ,(str configuration-name)) " fields are:") + ,@(map + (lambda (f) + (let ((field-name (configuration-field-name f)) + (field-type (configuration-field-type f)) + (field-docs (cdr (texi-fragment->stexi + (configuration-field-documentation f)))) + (default (catch #t + (configuration-field-default-value-thunk f) + (lambda _ '%invalid)))) + (define (show-default? val) + (or (string? default) (number? default) (boolean? default) + (and (symbol? val) (not (eq? val '%invalid))) + (and (list? val) (and-map show-default? val)))) + `(deftypevr (% (category + (code ,(str configuration-name)) " parameter") + (data-type ,(str field-type)) + (name ,(str field-name))) + ,@field-docs + ,@(if (show-default? default) + `((para "Defaults to " (samp ,(str default)) ".")) + '()) + ,@(append-map + generate + (or (assq-ref sub-documentation field-name) '()))))) + fields))))) + (stexi->texi `(*fragment* . ,(generate documentation-name)))) diff --git a/gnu/services/cups.scm b/gnu/services/cups.scm index 7542ee26c0..391046a75f 100644 --- a/gnu/services/cups.scm +++ b/gnu/services/cups.scm @@ -19,6 +19,7 @@ (define-module (gnu services cups) #:use-module (gnu services) #:use-module (gnu services shepherd) + #:use-module (gnu services configuration) #:use-module (gnu system shadow) #:use-module (gnu packages admin) #:use-module (gnu packages cups) @@ -26,16 +27,9 @@ #:use-module (guix packages) #:use-module (guix records) #:use-module (guix gexp) - #:use-module (texinfo) - #:use-module (texinfo serialize) #:use-module (ice-9 match) #:use-module ((srfi srfi-1) #:select (append-map)) - #:use-module (srfi srfi-34) - #:use-module (srfi srfi-35) - #:export (&cups-configuation-error - cups-configuration-error? - - cups-service-type + #:export (cups-service-type cups-configuration opaque-cups-configuration @@ -51,91 +45,6 @@ ;;; ;;; Code: -(define-condition-type &cups-configuration-error &error - cups-configuration-error?) - -(define (cups-error message) - (raise (condition (&message (message message)) - (&cups-configuration-error)))) -(define (cups-configuration-field-error field val) - (cups-error - (format #f "Invalid value for field ~a: ~s" field val))) -(define (cups-configuration-missing-field kind field) - (cups-error - (format #f "~a configuration missing required field ~a" kind field))) - -(define-record-type* - configuration-field make-configuration-field configuration-field? - (name configuration-field-name) - (type configuration-field-type) - (getter configuration-field-getter) - (predicate configuration-field-predicate) - (serializer configuration-field-serializer) - (default-value-thunk configuration-field-default-value-thunk) - (documentation configuration-field-documentation)) - -(define (serialize-configuration config fields) - (for-each (lambda (field) - ((configuration-field-serializer field) - (configuration-field-name field) - ((configuration-field-getter field) config))) - fields)) - -(define (validate-configuration config fields) - (for-each (lambda (field) - (let ((val ((configuration-field-getter field) config))) - (unless ((configuration-field-predicate field) val) - (cups-configuration-field-error - (configuration-field-name field) val)))) - fields)) - -(define-syntax define-configuration - (lambda (stx) - (define (id ctx part . parts) - (let ((part (syntax->datum part))) - (datum->syntax - ctx - (match parts - (() part) - (parts (symbol-append part - (syntax->datum (apply id ctx parts)))))))) - (syntax-case stx () - ((_ stem (field (field-type def) doc) ...) - (with-syntax (((field-getter ...) - (map (lambda (field) - (id #'stem #'stem #'- field)) - #'(field ...))) - ((field-predicate ...) - (map (lambda (type) - (id #'stem type #'?)) - #'(field-type ...))) - ((field-serializer ...) - (map (lambda (type) - (id #'stem #'serialize- type)) - #'(field-type ...)))) - #`(begin - (define-record-type* #,(id #'stem #'< #'stem #'>) - #,(id #'stem #'% #'stem) - #,(id #'stem #'make- #'stem) - #,(id #'stem #'stem #'?) - (field field-getter (default def)) - ...) - (define #,(id #'stem #'stem #'-fields) - (list (configuration-field - (name 'field) - (type 'field-type) - (getter field-getter) - (predicate field-predicate) - (serializer field-serializer) - (default-value-thunk (lambda () def)) - (documentation doc)) - ...)) - (define-syntax-rule (stem arg (... ...)) - (let ((conf (#,(id #'stem #'% #'stem) arg (... ...)))) - (validate-configuration conf - #,(id #'stem #'stem #'-fields)) - conf)))))))) - (define %cups-accounts (list (user-group (name "lp") (system? #t)) (user-group (name "lpadmin") (system? #t)) @@ -147,24 +56,6 @@ (home-directory "/var/empty") (shell (file-append shadow "/sbin/nologin"))))) -(define (uglify-field-name field-name) - (let ((str (symbol->string field-name))) - (string-concatenate - (map string-titlecase - (string-split (if (string-suffix? "?" str) - (substring str 0 (1- (string-length str))) - str) - #\-))))) - -(define (serialize-field field-name val) - (format #t "~a ~a\n" (uglify-field-name field-name) val)) - -(define (serialize-package field-name val) - #f) - -(define (serialize-string field-name val) - (serialize-field field-name val)) - (define (multiline-string-list? val) (and (list? val) (and-map (lambda (x) @@ -173,28 +64,11 @@ (define (serialize-multiline-string-list field-name val) (for-each (lambda (str) (serialize-field field-name str)) val)) -(define (space-separated-string-list? val) - (and (list? val) - (and-map (lambda (x) - (and (string? x) (not (string-index x #\space)))) - val))) -(define (serialize-space-separated-string-list field-name val) - (serialize-field field-name (string-join val " "))) - (define (space-separated-symbol-list? val) (and (list? val) (and-map symbol? val))) (define (serialize-space-separated-symbol-list field-name val) (serialize-field field-name (string-join (map symbol->string val) " "))) -(define (file-name? val) - (and (string? val) - (string-prefix? "/" val))) -(define (serialize-file-name field-name val) - (serialize-string field-name val)) - -(define (serialize-boolean field-name val) - (serialize-string field-name (if val "yes" "no"))) - (define (non-negative-integer? val) (and (exact-integer? val) (not (negative? val)))) (define (serialize-non-negative-integer field-name val) @@ -333,7 +207,7 @@ methods. Otherwise apply to only the listed methods.") (define-configuration location-access-control (path - (file-name (cups-configuration-missing-field 'location-access-control 'path)) + (file-name (configuration-missing-field 'location-access-control 'path)) "Specifies the URI path to which the access control applies.") (access-controls (access-control-list '()) @@ -359,7 +233,7 @@ methods. Otherwise apply to only the listed methods.") (define-configuration policy-configuration (name - (string (cups-configuration-missing-field 'policy-configuration 'name)) + (string (configuration-missing-field 'policy-configuration 'name)) "Name of the policy.") (job-private-access (string "@OWNER @SYSTEM") @@ -925,12 +799,12 @@ IPP specifications.") (package-list '()) "Drivers and other extensions to the CUPS package.") (cupsd.conf - (string (cups-configuration-missing-field 'opaque-cups-configuration - 'cupsd.conf)) + (string (configuration-missing-field 'opaque-cups-configuration + 'cupsd.conf)) "The contents of the @code{cupsd.conf} to use.") (cups-files.conf - (string (cups-configuration-missing-field 'opaque-cups-configuration - 'cups-files.conf)) + (string (configuration-missing-field 'opaque-cups-configuration + 'cups-files.conf)) "The contents of the @code{cups-files.conf} to use.")) (define %cups-activation @@ -1117,8 +991,8 @@ extensions that it uses." extensions))))))))) ;; A little helper to make it easier to document all those fields. -(define (generate-documentation) - (define documentation +(define (generate-cups-documentation) + (generate-documentation `((cups-configuration ,cups-configuration-fields (files-configuration files-configuration) @@ -1132,35 +1006,5 @@ extensions that it uses." ,location-access-control-fields (method-access-controls method-access-controls)) (operation-access-controls ,operation-access-control-fields) - (method-access-controls ,method-access-control-fields))) - (define (str x) (object->string x)) - (define (generate configuration-name) - (match (assq-ref documentation configuration-name) - ((fields . sub-documentation) - `((para "Available " (code ,(str configuration-name)) " fields are:") - ,@(map - (lambda (f) - (let ((field-name (configuration-field-name f)) - (field-type (configuration-field-type f)) - (field-docs (cdr (texi-fragment->stexi - (configuration-field-documentation f)))) - (default (catch #t - (configuration-field-default-value-thunk f) - (lambda _ '%invalid)))) - (define (show-default? val) - (or (string? default) (number? default) (boolean? default) - (and (symbol? val) (not (eq? val '%invalid))) - (and (list? val) (and-map show-default? val)))) - `(deftypevr (% (category - (code ,(str configuration-name)) " parameter") - (data-type ,(str field-type)) - (name ,(str field-name))) - ,@field-docs - ,@(if (show-default? default) - `((para "Defaults to " (samp ,(str default)) ".")) - '()) - ,@(append-map - generate - (or (assq-ref sub-documentation field-name) '()))))) - fields))))) - (stexi->texi `(*fragment* . ,(generate 'cups-configuration)))) + (method-access-controls ,method-access-control-fields)) + 'cups-configuration)) diff --git a/gnu/services/mail.scm b/gnu/services/mail.scm index f7ab9516ba..c1381405d8 100644 --- a/gnu/services/mail.scm +++ b/gnu/services/mail.scm @@ -21,6 +21,7 @@ (define-module (gnu services mail) #:use-module (gnu services) #:use-module (gnu services base) + #:use-module (gnu services configuration) #:use-module (gnu services shepherd) #:use-module (gnu system pam) #:use-module (gnu system shadow) @@ -30,13 +31,8 @@ #:use-module (guix records) #:use-module (guix packages) #:use-module (guix gexp) - #:use-module (srfi srfi-34) - #:use-module (srfi srfi-35) #:use-module (ice-9 match) - #:export (&dovecot-configuation-error - dovecot-configuration-error? - - dovecot-service + #:export (dovecot-service dovecot-service-type dovecot-configuration opaque-dovecot-configuration @@ -65,112 +61,6 @@ ;;; ;;; Code: -(define-condition-type &dovecot-configuration-error &error - dovecot-configuration-error?) - -(define (dovecot-error message) - (raise (condition (&message (message message)) - (&dovecot-configuration-error)))) -(define (dovecot-configuration-field-error field val) - (dovecot-error - (format #f "Invalid value for field ~a: ~s" field val))) -(define (dovecot-configuration-missing-field kind field) - (dovecot-error - (format #f "~a configuration missing required field ~a" kind field))) - -(define-record-type* - configuration-field make-configuration-field configuration-field? - (name configuration-field-name) - (type configuration-field-type) - (getter configuration-field-getter) - (predicate configuration-field-predicate) - (serializer configuration-field-serializer) - (default-value-thunk configuration-field-default-value-thunk) - (documentation configuration-field-documentation)) - -(define-syntax define-configuration - (lambda (stx) - (define (id ctx part . parts) - (let ((part (syntax->datum part))) - (datum->syntax - ctx - (match parts - (() part) - (parts (symbol-append part - (syntax->datum (apply id ctx parts)))))))) - (syntax-case stx () - ((_ stem (field (field-type def) doc) ...) - (with-syntax (((field-getter ...) - (map (lambda (field) - (id #'stem #'stem #'- field)) - #'(field ...))) - ((field-predicate ...) - (map (lambda (type) - (id #'stem type #'?)) - #'(field-type ...))) - ((field-serializer ...) - (map (lambda (type) - (id #'stem #'serialize- type)) - #'(field-type ...)))) - #`(begin - (define-record-type* #,(id #'stem #'< #'stem #'>) - stem #,(id #'stem #'make- #'stem) #,(id #'stem #'stem #'?) - (field field-getter (default def)) - ...) - (define #,(id #'stem #'stem #'-fields) - (list (configuration-field - (name 'field) - (type 'field-type) - (getter field-getter) - (predicate field-predicate) - (serializer field-serializer) - (default-value-thunk (lambda () def)) - (documentation doc)) - ...)))))))) - -(define (serialize-configuration config fields) - (for-each (lambda (field) - ((configuration-field-serializer field) - (configuration-field-name field) - ((configuration-field-getter field) config))) - fields)) - -(define (validate-configuration config fields) - (for-each (lambda (field) - (let ((val ((configuration-field-getter field) config))) - (unless ((configuration-field-predicate field) val) - (dovecot-configuration-field-error - (configuration-field-name field) val)))) - fields)) - -(define (validate-package field-name package) - (unless (package? package) - (dovecot-configuration-field-error field-name package))) - -(define (uglify-field-name field-name) - (let ((str (symbol->string field-name))) - (string-join (string-split (if (string-suffix? "?" str) - (substring str 0 (1- (string-length str))) - str) - #\-) - "_"))) - -(define (serialize-package field-name val) - #f) - -(define (serialize-field field-name val) - (format #t "~a=~a\n" (uglify-field-name field-name) val)) - -(define (serialize-string field-name val) - (serialize-field field-name val)) - -(define (space-separated-string-list? val) - (and (list? val) - (and-map (lambda (x) - (and (string? x) (not (string-index x #\space)))) - val))) -(define (serialize-space-separated-string-list field-name val) - (serialize-field field-name (string-join val " "))) (define (comma-separated-string-list? val) (and (list? val) @@ -180,12 +70,6 @@ (define (serialize-comma-separated-string-list field-name val) (serialize-field field-name (string-join val ","))) -(define (file-name? val) - (and (string? val) - (string-prefix? "/" val))) -(define (serialize-file-name field-name val) - (serialize-string field-name val)) - (define (colon-separated-file-name-list? val) (and (list? val) ;; Trailing slashes not needed and not @@ -193,9 +77,6 @@ (define (serialize-colon-separated-file-name-list field-name val) (serialize-field field-name (string-join val ":"))) -(define (serialize-boolean field-name val) - (serialize-string field-name (if val "yes" "no"))) - (define (non-negative-integer? val) (and (exact-integer? val) (not (negative? val)))) (define (serialize-non-negative-integer field-name val) @@ -276,7 +157,7 @@ (define-configuration unix-listener-configuration (path - (file-name (dovecot-configuration-missing-field 'unix-listener 'path)) + (file-name (configuration-missing-field 'unix-listener 'path)) "The file name on which to listen.") (mode (string "0600") @@ -295,7 +176,7 @@ (define-configuration fifo-listener-configuration (path - (file-name (dovecot-configuration-missing-field 'fifo-listener 'path)) + (file-name (configuration-missing-field 'fifo-listener 'path)) "The file name on which to listen.") (mode (string "0600") @@ -314,14 +195,14 @@ (define-configuration inet-listener-configuration (protocol - (string (dovecot-configuration-missing-field 'inet-listener 'protocol)) + (string (configuration-missing-field 'inet-listener 'protocol)) "The protocol to listen for.") (address (string "") "The address on which to listen, or empty for all addresses.") (port (non-negative-integer - (dovecot-configuration-missing-field 'inet-listener 'port)) + (configuration-missing-field 'inet-listener 'port)) "The port on which to listen.") (ssl? (boolean #t) @@ -345,7 +226,7 @@ (serialize-fifo-listener-configuration field-name val)) ((inet-listener-configuration? val) (serialize-inet-listener-configuration field-name val)) - (else (dovecot-configuration-field-error field-name val)))) + (else (configuration-field-error field-name val)))) (define (listener-configuration-list? val) (and (list? val) (and-map listener-configuration? val))) (define (serialize-listener-configuration-list field-name val) @@ -355,7 +236,7 @@ (define-configuration service-configuration (kind - (string (dovecot-configuration-missing-field 'service 'kind)) + (string (configuration-missing-field 'service 'kind)) "The service kind. Valid values include @code{director}, @code{imap-login}, @code{pop3-login}, @code{lmtp}, @code{imap}, @code{pop3}, @code{auth}, @code{auth-worker}, @code{dict}, @@ -393,7 +274,7 @@ this.")) (define-configuration protocol-configuration (name - (string (dovecot-configuration-missing-field 'protocol 'name)) + (string (configuration-missing-field 'protocol 'name)) "The name of the protocol.") (auth-socket-path (string "/var/run/dovecot/auth-userdb") @@ -1497,8 +1378,8 @@ greyed out, instead of only later giving \"not selectable\" popup error. "The dovecot package.") (string - (string (dovecot-configuration-missing-field 'opaque-dovecot-configuration - 'string)) + (string (configuration-missing-field 'opaque-dovecot-configuration + 'string)) "The contents of the @code{dovecot.conf} to use.")) (define %dovecot-accounts @@ -1634,8 +1515,8 @@ by @code{dovecot-configuration}. @var{config} may also be created by (service dovecot-service-type config)) ;; A little helper to make it easier to document all those fields. -(define (generate-documentation) - (define documentation +(define (generate-dovecot-documentation) + (generate-documentation `((dovecot-configuration ,dovecot-configuration-fields (dict dict-configuration) @@ -1660,42 +1541,8 @@ by @code{dovecot-configuration}. @var{config} may also be created by ,service-configuration-fields (listeners unix-listener-configuration fifo-listener-configuration inet-listener-configuration)) - (protocol-configuration ,protocol-configuration-fields))) - (define (generate configuration-name) - (match (assq-ref documentation configuration-name) - ((fields . sub-documentation) - (format #t "\nAvailable @code{~a} fields are:\n\n" configuration-name) - (for-each - (lambda (f) - (let ((field-name (configuration-field-name f)) - (field-type (configuration-field-type f)) - (field-docs (string-trim-both - (configuration-field-documentation f))) - (default (catch #t - (configuration-field-default-value-thunk f) - (lambda _ 'nope)))) - (define (escape-chars str chars escape) - (with-output-to-string - (lambda () - (string-for-each (lambda (c) - (when (char-set-contains? chars c) - (display escape)) - (display c)) - str)))) - (define (show-default? val) - (or (string? default) (number? default) (boolean? default) - (and (list? val) (and-map show-default? val)))) - (format #t "@deftypevr {@code{~a} parameter} ~a ~a\n~a\n" - configuration-name field-type field-name field-docs) - (when (show-default? default) - (format #t "Defaults to @samp{~a}.\n" - (escape-chars (format #f "~s" default) - (char-set #\@ #\{ #\}) - #\@))) - (for-each generate (or (assq-ref sub-documentation field-name) '())) - (format #t "@end deftypevr\n\n"))) - fields)))) - (generate 'dovecot-configuration)) + (protocol-configuration ,protocol-configuration-fields)) + 'dovecot-configuration)) ;;; -- cgit 1.4.1 From a7cf4eb6d99838606d8ecfa776f7e4920dfbb7f5 Mon Sep 17 00:00:00 2001 From: Mathieu Lirzin Date: Sun, 23 Oct 2016 15:14:18 +0200 Subject: services: Add 'cuirass-service'. * gnu/services/cuirass.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. * doc/guix.texi (Continuous integration): New node. --- doc/guix.texi | 79 ++++++++++++++++++++++++++++++++ gnu/local.mk | 1 + gnu/services/cuirass.scm | 115 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 gnu/services/cuirass.scm (limited to 'gnu/services') diff --git a/doc/guix.texi b/doc/guix.texi index 125e5f0d62..53d29e45be 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -7926,6 +7926,7 @@ declaration. * Kerberos Services:: Kerberos services. * Web Services:: Web servers. * Network File System:: NFS related services. +* Continuous Integration:: The Cuirass service. * Miscellaneous Services:: Other services. @end menu @@ -11747,6 +11748,84 @@ If it is @code{#f} then the daemon will use the host's fully qualified domain na @end table @end deftp +@node Continuous Integration +@subsubsection Continuous Integration + +@cindex continuous integration +@uref{https://notabug.org/mthl/cuirass, Cuirass} is a continuous +integration tool for Guix. It can be used both for development and for +providing substitutes to others (@pxref{Substitutes}). + +The @code{(gnu services cuirass)} module provides the following service. + +@deffn {Scheme Procedure} cuirass-service @ + [#:config @code{(cuirass-configuration)}] +Return a service that runs @command{cuirass}. + +The @var{#:config} keyword argument specifies the configuration for +@command{cuirass}, which must be a @code{} +object, by default it doesn't provide any build job. If you want to +provide your own configuration you will most likely use the +@code{cuirass-configuration} special form which returns such objects. +@end deffn + +In order to add build jobs you will have to set the +@code{specifications} field. Here is an example of a cuirass service +defining a build job based on a specification that can be found in +Cuirass source tree. + +@example +(let ((spec `((#:name . "guix") + (#:url . "git://git.savannah.gnu.org/guix.git") + (#:load-path . ".") + ;; Adapt to a valid absolute file name. + (#:file . "/.../cuirass/tests/gnu-system.scm") + (#:proc . hydra-jobs) + (#:arguments (subset . "hello")) + (#:branch . "master")))) + (cuirass-service #:config (cuirass-configuration + (specifications (list spec))))) +@end example + +While information related to build jobs are located directly in the +specifications, global settings for the @command{cuirass} process are +accessible in other @code{cuirass-configuration} fields. + +@deftp {Data Type} cuirass-configuration +Data type representing the configuration of Cuirass. + +@table @asis +@item @code{cache-directory} (default: @code{""}) +Location of the repository cache. + +@item @code{user} (default: @code{"cuirass"}) +Owner of the @code{cuirass} process. + +@item @code{group} (default: @code{"cuirass"}) +Owner's group of the @code{cuirass} process. + +@item @code{interval} (default: @code{60}) +Number of seconds between the poll of the repositories followed by the +Cuirass jobs. + +@item @code{database} (default: @code{"/var/run/cuirass/cuirass.db"}) +Location of sqlite database which contains the build results and previously +added specifications. + +@item @code{specifications} (default: @code{'()}) +A list of specifications, where a specification is an association list +(@pxref{Associations Lists,,, guile, GNU Guile Reference Manual}) whose +keys are keywords (@code{#:keyword-example}) as shown in the example +above. + +@item @code{use-substitutes?} (default: @code{#f}) +This allows using substitutes to avoid building every dependencies of a job +from source. + +@item @code{one-shot?} (default: @code{#f}) +Only evaluate specifications and build derivations once. +@end table +@end deftp @node Miscellaneous Services @subsubsection Miscellaneous Services diff --git a/gnu/local.mk b/gnu/local.mk index c6461aa9c6..d9ec24a22e 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -402,6 +402,7 @@ GNU_SYSTEM_MODULES = \ %D%/services/avahi.scm \ %D%/services/base.scm \ %D%/services/configuration.scm \ + %D%/services/cuirass.scm \ %D%/services/cups.scm \ %D%/services/databases.scm \ %D%/services/dbus.scm \ diff --git a/gnu/services/cuirass.scm b/gnu/services/cuirass.scm new file mode 100644 index 0000000000..d843c07335 --- /dev/null +++ b/gnu/services/cuirass.scm @@ -0,0 +1,115 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2016 Mathieu Lirzin +;;; +;;; 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 . + +(define-module (gnu services cuirass) + #:use-module (guix gexp) + #:use-module (guix records) + #:use-module (gnu packages admin) + #:autoload (gnu packages ci) (cuirass) + #:use-module (gnu services) + #:use-module (gnu services base) + #:use-module (gnu services shepherd) + #:use-module (gnu system shadow) + #:export ( + cuirass-configuration + cuirass-configuration? + + cuirass-service-type + cuirass-service)) + +;;;; Commentary: +;;; +;;; This module implements a service that to run instances of Cuirass, a +;;; continuous integration tool. +;;; +;;;; Code: + +(define-record-type* + cuirass-configuration make-cuirass-configuration + cuirass-configuration? + (cache-directory cuirass-configuration-cache-directory ;string (dir-name) + (default "")) + (user cuirass-configuration-user ;string + (default "cuirass")) + (group cuirass-configuration-group ;string + (default "cuirass")) + (interval cuirass-configuration-interval ;integer (seconds) + (default 60)) + (database cuirass-configuration-database ;string (file-name) + (default "/var/run/cuirass/cuirass.db")) + (specifications cuirass-configuration-specifications ;string (file-name) + (default "")) + (use-substitutes? cuirass-configuration-use-substitutes? ;boolean + (default #f)) + (one-shot? cuirass-configuration-one-shot? ;boolean + (default #f))) + +(define (cuirass-shepherd-service config) + "Return a for the Cuirass service with CONFIG." + (and + (cuirass-configuration? config) + (let ((cache-directory (cuirass-configuration-cache-directory config)) + (interval (cuirass-configuration-interval config)) + (database (cuirass-configuration-database config)) + (specifications (cuirass-configuration-specifications config)) + (use-substitutes? (cuirass-configuration-use-substitutes? config)) + (one-shot? (cuirass-configuration-one-shot? config))) + (list (shepherd-service + (documentation "Run Cuirass.") + (provision '(cuirass)) + (requirement '(guix-daemon)) + (start #~(make-forkexec-constructor + (list (string-append #$cuirass "/bin/cuirass") + #$@(if (string=? "" cache-directory) + '() + (list "--cache-directory" cache-directory)) + #$@(if (string=? "" specifications) + '() + (list "--specifications" specifications)) + "--database" #$database + "--interval" #$(number->string interval) + #$@(if use-substitutes? '("--use-substitutes") '()) + #$@(if one-shot? '("--one-shot") '())))) + (stop #~(make-kill-destructor))))))) + +(define (cuirass-account config) + "Return the user accounts and user groups for CONFIG." + (let ((cuirass-user (cuirass-configuration-user config)) + (cuirass-group (cuirass-configuration-group config))) + (list (user-group + (name cuirass-group) + (system? #t)) + (user-account + (name cuirass-user) + (group cuirass-group) + (system? #t) + (comment "Cuirass privilege separation user") + (home-directory (string-append "/var/run/" cuirass-user)) + (shell #~(string-append #$shadow "/sbin/nologin")))))) + +(define cuirass-service-type + (service-type + (name 'cuirass) + (extensions + (list + (service-extension shepherd-root-service-type cuirass-shepherd-service) + (service-extension account-service-type cuirass-account))))) + +(define* (cuirass-service #:key (config (cuirass-configuration))) + "Return a service that runs cuirass according to CONFIG." + (service cuirass-service-type config)) -- cgit 1.4.1 From 819c1945d1ddb0d3237c48cc3c4975640f9bf08d Mon Sep 17 00:00:00 2001 From: Ricardo Wurmus Date: Wed, 30 Nov 2016 15:59:45 +0100 Subject: services: nginx: Join strings with spaces. * gnu/services/web.scm (config-domain-strings, config-index-strings): Use "string-join" to join strings with spaces. --- gnu/services/web.scm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gnu/services') diff --git a/gnu/services/web.scm b/gnu/services/web.scm index 59e1e54e04..8f6e5bf6b7 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -72,7 +72,7 @@ (define (config-domain-strings names) "Return a string denoting the nginx config representation of NAMES, a list of domain names." - (string-concatenate + (string-join (map (match-lambda ('default "_") ((? string? str) str)) @@ -81,7 +81,7 @@ of domain names." (define (config-index-strings names) "Return a string denoting the nginx config representation of NAMES, a list of index files." - (string-concatenate + (string-join (map (match-lambda ((? string? str) str)) names))) -- cgit 1.4.1