aboutsummaryrefslogtreecommitdiff
path: root/gnu/services
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/services')
-rw-r--r--gnu/services/admin.scm151
-rw-r--r--gnu/services/cuirass.scm7
-rw-r--r--gnu/services/databases.scm73
-rw-r--r--gnu/services/networking.scm11
-rw-r--r--gnu/services/ssh.scm96
5 files changed, 316 insertions, 22 deletions
diff --git a/gnu/services/admin.scm b/gnu/services/admin.scm
index b9e3fa70a4..1044833fef 100644
--- a/gnu/services/admin.scm
+++ b/gnu/services/admin.scm
@@ -20,14 +20,19 @@
(define-module (gnu services admin)
#:use-module (gnu packages admin)
#:use-module (gnu packages base)
+ #:use-module (gnu packages logging)
#:use-module (gnu services)
#:use-module (gnu services mcron)
#:use-module (gnu services shepherd)
+ #:use-module (gnu services web)
+ #:use-module (gnu system shadow)
#:use-module (guix gexp)
+ #:use-module (guix store)
#:use-module (guix packages)
#:use-module (guix records)
#:use-module (srfi srfi-1)
#:use-module (ice-9 vlist)
+ #:use-module (ice-9 match)
#:export (%default-rotations
%rotated-files
@@ -41,7 +46,27 @@
rottlog-configuration
rottlog-configuration?
rottlog-service
- rottlog-service-type))
+ rottlog-service-type
+
+ <tailon-configuration-file>
+ tailon-configuration-file
+ tailon-configuration-file?
+ tailon-configuration-file-files
+ tailon-configuration-file-bind
+ tailon-configuration-file-relative-root
+ tailon-configuration-file-allow-transfers?
+ tailon-configuration-file-follow-names?
+ tailon-configuration-file-tail-lines
+ tailon-configuration-file-allowed-commands
+ tailon-configuration-file-debug?
+
+ <tailon-configuration>
+ tailon-configuration
+ tailon-configuration?
+ tailon-configuration-config-file
+ tailon-configuration-package
+
+ tailon-service-type))
;;; Commentary:
;;;
@@ -172,4 +197,128 @@ for ROTATION."
rotations)))))
(default-value (rottlog-configuration))))
+
+;;;
+;;; Tailon
+;;;
+
+(define-record-type* <tailon-configuration-file>
+ tailon-configuration-file make-tailon-configuration-file
+ tailon-configuration-file?
+ (files tailon-configuration-file-files
+ (default '("/var/log")))
+ (bind tailon-configuration-file-bind
+ (default "localhost:8080"))
+ (relative-root tailon-configuration-file-relative-root
+ (default #f))
+ (allow-transfers? tailon-configuration-file-allow-transfers?
+ (default #t))
+ (follow-names? tailon-configuration-file-follow-names?
+ (default #t))
+ (tail-lines tailon-configuration-file-tail-lines
+ (default 200))
+ (allowed-commands tailon-configuration-file-allowed-commands
+ (default '("tail" "grep" "awk")))
+ (debug? tailon-configuration-file-debug?
+ (default #f)))
+
+(define (tailon-configuration-files-string files)
+ (string-append
+ "\n"
+ (string-join
+ (map
+ (lambda (x)
+ (string-append
+ " - "
+ (cond
+ ((string? x)
+ (simple-format #f "'~A'" x))
+ ((list? x)
+ (string-join
+ (cons (simple-format #f "'~A':" (car x))
+ (map
+ (lambda (x) (simple-format #f " - '~A'" x))
+ (cdr x)))
+ "\n"))
+ (else (error x)))))
+ files)
+ "\n")))
+
+(define-gexp-compiler (tailon-configuration-file-compiler
+ (file <tailon-configuration-file>) system target)
+ (match file
+ (($ <tailon-configuration-file> files bind relative-root
+ allow-transfers? follow-names?
+ tail-lines allowed-commands debug?)
+ (text-file
+ "tailon-config.yaml"
+ (string-concatenate
+ (filter-map
+ (match-lambda
+ ((key . #f) #f)
+ ((key . value) (string-append key ": " value "\n")))
+
+ `(("files" . ,(tailon-configuration-files-string files))
+ ("bind" . ,bind)
+ ("relative-root" . ,relative-root)
+ ("allow-transfers" . ,(if allow-transfers? "true" "false"))
+ ("follow-names" . ,(if follow-names? "true" "false"))
+ ("tail-lines" . ,(number->string tail-lines))
+ ("commands" . ,(string-append "["
+ (string-join allowed-commands ", ")
+ "]"))
+ ,@(if debug? '(("debug" . "true")) '()))))))))
+
+(define-record-type* <tailon-configuration>
+ tailon-configuration make-tailon-configuration
+ tailon-configuration?
+ (config-file tailon-configuration-config-file
+ (default (tailon-configuration-file)))
+ (package tailon-configuration-package
+ (default tailon)))
+
+(define tailon-shepherd-service
+ (match-lambda
+ (($ <tailon-configuration> config-file package)
+ (list (shepherd-service
+ (provision '(tailon))
+ (documentation "Run the tailon daemon.")
+ (start #~(make-forkexec-constructor
+ `(,(string-append #$package "/bin/tailon")
+ "-c" ,#$config-file)
+ #:user "tailon"
+ #:group "tailon"))
+ (stop #~(make-kill-destructor)))))))
+
+(define %tailon-accounts
+ (list (user-group (name "tailon") (system? #t))
+ (user-account
+ (name "tailon")
+ (group "tailon")
+ (system? #t)
+ (comment "tailon")
+ (home-directory "/var/empty")
+ (shell (file-append shadow "/sbin/nologin")))))
+
+(define tailon-service-type
+ (service-type
+ (name 'tailon)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ tailon-shepherd-service)
+ (service-extension account-service-type
+ (const %tailon-accounts))))
+ (compose concatenate)
+ (extend (lambda (parameter files)
+ (tailon-configuration
+ (inherit parameter)
+ (config-file
+ (let ((old-config-file
+ (tailon-configuration-config-file parameter)))
+ (tailon-configuration-file
+ (inherit old-config-file)
+ (files (append (tailon-configuration-file-files old-config-file)
+ files))))))))
+ (default-value (tailon-configuration))))
+
;;; admin.scm ends here
diff --git a/gnu/services/cuirass.scm b/gnu/services/cuirass.scm
index d27a2bbc44..73a30b2402 100644
--- a/gnu/services/cuirass.scm
+++ b/gnu/services/cuirass.scm
@@ -23,6 +23,7 @@
#:use-module (guix records)
#:use-module (gnu packages admin)
#:autoload (gnu packages ci) (cuirass)
+ #:autoload (gnu packages version-control) (git)
#:use-module (gnu services)
#:use-module (gnu services base)
#:use-module (gnu services shepherd)
@@ -105,6 +106,12 @@
#$@(if fallback? '("--fallback") '())
#$@(if (null? load-path) '()
`("--load-path" ,(string-join load-path ":"))))
+
+ #:environment-variables
+ (list "GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt"
+ (string-append "GIT_EXEC_PATH=" #$git
+ "/libexec/git-core"))
+
#:user #$user
#:group #$group
#:log-file #$log-file))
diff --git a/gnu/services/databases.scm b/gnu/services/databases.scm
index 3ecc8aff78..3b64d0e075 100644
--- a/gnu/services/databases.scm
+++ b/gnu/services/databases.scm
@@ -25,6 +25,7 @@
#:use-module (gnu system shadow)
#:use-module (gnu packages admin)
#:use-module (gnu packages databases)
+ #:use-module (guix modules)
#:use-module (guix records)
#:use-module (guix gexp)
#:use-module (ice-9 match)
@@ -33,6 +34,16 @@
postgresql-service
postgresql-service-type
+ memcached-service-type
+ <memcached-configuration>
+ memcached-configuration
+ memcached-configuration?
+ memcached-configuration-memecached
+ memcached-configuration-interfaces
+ memcached-configuration-tcp-port
+ memcached-configuration-udp-port
+ memcached-configuration-additional-options
+
mysql-service
mysql-service-type
mysql-configuration
@@ -178,6 +189,68 @@ and stores the database cluster in @var{data-directory}."
;;;
+;;; Memcached
+;;;
+
+(define-record-type* <memcached-configuration>
+ memcached-configuration make-memcached-configuration
+ memcached-configuration?
+ (memcached memcached-configuration-memcached ;<package>
+ (default memcached))
+ (interfaces memcached-configuration-interfaces
+ (default '("0.0.0.0")))
+ (tcp-port memcached-configuration-tcp-port
+ (default 11211))
+ (udp-port memcached-configuration-udp-port
+ (default 11211))
+ (additional-options memcached-configuration-additional-options
+ (default '())))
+
+(define %memcached-accounts
+ (list (user-group (name "memcached") (system? #t))
+ (user-account
+ (name "memcached")
+ (group "memcached")
+ (system? #t)
+ (comment "Memcached server user")
+ (home-directory "/var/empty")
+ (shell (file-append shadow "/sbin/nologin")))))
+
+(define memcached-shepherd-service
+ (match-lambda
+ (($ <memcached-configuration> memcached interfaces tcp-port udp-port
+ additional-options)
+ (with-imported-modules (source-module-closure
+ '((gnu build shepherd)))
+ (list (shepherd-service
+ (provision '(memcached))
+ (documentation "Run the Memcached daemon.")
+ (requirement '(user-processes loopback))
+ (modules '((gnu build shepherd)))
+ (start #~(make-forkexec-constructor
+ `(#$(file-append memcached "/bin/memcached")
+ "-l" #$(string-join interfaces ",")
+ "-p" #$(number->string tcp-port)
+ "-U" #$(number->string udp-port)
+ "--daemon"
+ "-P" "/var/run/memcached.pid"
+ "-u" "memcached"
+ ,#$@additional-options)
+ #:log-file "/var/log/memcached"
+ #:pid-file "/var/run/memcached.pid"))
+ (stop #~(make-kill-destructor))))))))
+
+(define memcached-service-type
+ (service-type (name 'memcached)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ memcached-shepherd-service)
+ (service-extension account-service-type
+ (const %memcached-accounts))))
+ (default-value (memcached-configuration))))
+
+
+;;;
;;; MySQL.
;;;
diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index c381581896..b45008de64 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -334,10 +334,13 @@ Protocol (DHCP) client, on all the non-loopback network interfaces."
(service dhcp-client-service-type dhcp))
(define %ntp-servers
- ;; Default set of NTP servers.
- '("0.pool.ntp.org"
- "1.pool.ntp.org"
- "2.pool.ntp.org"))
+ ;; Default set of NTP servers. These URLs are managed by the NTP Pool project.
+ ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact
+ ;; for this NTP pool "zone".
+ '("0.guix.pool.ntp.org"
+ "1.guix.pool.ntp.org"
+ "2.guix.pool.ntp.org"
+ "3.guix.pool.ntp.org"))
;;;
diff --git a/gnu/services/ssh.scm b/gnu/services/ssh.scm
index 2a6c8d45c2..697bb1b82e 100644
--- a/gnu/services/ssh.scm
+++ b/gnu/services/ssh.scm
@@ -28,6 +28,8 @@
#:use-module (gnu system shadow)
#:use-module (guix gexp)
#:use-module (guix records)
+ #:use-module (guix modules)
+ #:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:use-module (ice-9 match)
#:export (lsh-configuration
@@ -295,7 +297,11 @@ The other options should be self-descriptive."
(default #t))
;; list of two-element lists
(subsystems openssh-configuration-subsystems
- (default '(("sftp" "internal-sftp")))))
+ (default '(("sftp" "internal-sftp"))))
+
+ ;; list of user-name/file-like tuples
+ (authorized-keys openssh-authorized-keys
+ (default '())))
(define %openssh-accounts
(list (user-group (name "sshd") (system? #t))
@@ -309,22 +315,64 @@ The other options should be self-descriptive."
(define (openssh-activation config)
"Return the activation GEXP for CONFIG."
- #~(begin
- (use-modules (guix build utils))
- (mkdir-p "/etc/ssh")
- (mkdir-p (dirname #$(openssh-configuration-pid-file config)))
-
- (define (touch file-name)
- (call-with-output-file file-name (const #t)))
-
- (let ((lastlog "/var/log/lastlog"))
- (when #$(openssh-configuration-print-last-log? config)
- (unless (file-exists? lastlog)
- (touch lastlog))))
-
- ;; Generate missing host keys.
- (system* (string-append #$(openssh-configuration-openssh config)
- "/bin/ssh-keygen") "-A")))
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+
+ (define (touch file-name)
+ (call-with-output-file file-name (const #t)))
+
+ ;; Make sure /etc/ssh can be read by the 'sshd' user.
+ (mkdir-p "/etc/ssh")
+ (chmod "/etc/ssh" #o755)
+ (mkdir-p (dirname #$(openssh-configuration-pid-file config)))
+
+ ;; 'sshd' complains if the authorized-key directory and its parents
+ ;; are group-writable, which rules out /gnu/store. Thus we copy the
+ ;; authorized-key directory to /etc.
+ (catch 'system-error
+ (lambda ()
+ (delete-file-recursively "/etc/authorized_keys.d"))
+ (lambda args
+ (unless (= ENOENT (system-error-errno args))
+ (apply throw args))))
+ (copy-recursively #$(authorized-key-directory
+ (openssh-authorized-keys config))
+ "/etc/ssh/authorized_keys.d")
+
+ (chmod "/etc/ssh/authorized_keys.d" #o555)
+
+ (let ((lastlog "/var/log/lastlog"))
+ (when #$(openssh-configuration-print-last-log? config)
+ (unless (file-exists? lastlog)
+ (touch lastlog))))
+
+ ;; Generate missing host keys.
+ (system* (string-append #$(openssh-configuration-openssh config)
+ "/bin/ssh-keygen") "-A"))))
+
+(define (authorized-key-directory keys)
+ "Return a directory containing the authorized keys specified in KEYS, a list
+of user-name/file-like tuples."
+ (define build
+ (with-imported-modules (source-module-closure '((guix build utils)))
+ #~(begin
+ (use-modules (ice-9 match) (srfi srfi-26)
+ (guix build utils))
+
+ (mkdir #$output)
+ (for-each (match-lambda
+ ((user keys ...)
+ (let ((file (string-append #$output "/" user)))
+ (call-with-output-file file
+ (lambda (port)
+ (for-each (lambda (key)
+ (call-with-input-file key
+ (cut dump-port <> port)))
+ keys))))))
+ '#$keys))))
+
+ (computed-file "openssh-authorized-keys" build))
(define (openssh-config-file config)
"Return the sshd configuration file corresponding to CONFIG."
@@ -367,6 +415,11 @@ The other options should be self-descriptive."
(format port "PrintLastLog ~a\n"
#$(if (openssh-configuration-print-last-log? config)
"yes" "no"))
+
+ ;; Add '/etc/authorized_keys.d/%u', which we populate.
+ (format port "AuthorizedKeysFile \
+ .ssh/authorized_keys .ssh/authorized_keys2 /etc/ssh/authorized_keys.d/%u\n")
+
(for-each
(match-lambda
((name command) (format port "Subsystem\t~a\t~a\n" name command)))
@@ -398,6 +451,13 @@ The other options should be self-descriptive."
#:allow-empty-passwords?
(openssh-configuration-allow-empty-passwords? config))))
+(define (extend-openssh-authorized-keys config keys)
+ "Extend CONFIG with the extra authorized keys listed in KEYS."
+ (openssh-configuration
+ (inherit config)
+ (authorized-keys
+ (append (openssh-authorized-keys config) keys))))
+
(define openssh-service-type
(service-type (name 'openssh)
(extensions
@@ -409,6 +469,8 @@ The other options should be self-descriptive."
openssh-activation)
(service-extension account-service-type
(const %openssh-accounts))))
+ (compose concatenate)
+ (extend extend-openssh-authorized-keys)
(default-value (openssh-configuration))))