diff options
Diffstat (limited to 'gnu/services')
-rw-r--r-- | gnu/services/admin.scm | 6 | ||||
-rw-r--r-- | gnu/services/base.scm | 32 | ||||
-rw-r--r-- | gnu/services/herd.scm | 20 | ||||
-rw-r--r-- | gnu/services/networking.scm | 16 | ||||
-rw-r--r-- | gnu/services/shepherd.scm | 39 | ||||
-rw-r--r-- | gnu/services/version-control.scm | 180 |
6 files changed, 247 insertions, 46 deletions
diff --git a/gnu/services/admin.scm b/gnu/services/admin.scm index f08c896334..d7bda61ed7 100644 --- a/gnu/services/admin.scm +++ b/gnu/services/admin.scm @@ -125,11 +125,9 @@ for ROTATION." (define (default-jobs rottlog) (list #~(job '(next-hour '(0)) ;midnight - (lambda () - (system* #$(file-append rottlog "/sbin/rottlog")))) + #$(file-append rottlog "/sbin/rottlog")) #~(job '(next-hour '(12)) ;noon - (lambda () - (system* #$(file-append rottlog "/sbin/rottlog")))))) + #$(file-append rottlog "/sbin/rottlog")))) (define-record-type* <rottlog-configuration> rottlog-configuration make-rottlog-configuration diff --git a/gnu/services/base.scm b/gnu/services/base.scm index 5ba2c6b86d..47c7d8bb27 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -685,17 +685,20 @@ to add @var{device} to the kernel's entropy pool. The service will fail if (shepherd-service-type 'virtual-terminal (lambda (utf8?) - (shepherd-service - (documentation "Set virtual terminals in UTF-8 module.") - (provision '(virtual-terminal)) - (requirement '(root-file-system)) - (start #~(lambda _ - (call-with-output-file - "/sys/module/vt/parameters/default_utf8" - (lambda (port) - (display 1 port))) - #t)) - (stop #~(const #f)))) + (let ((knob "/sys/module/vt/parameters/default_utf8")) + (shepherd-service + (documentation "Set virtual terminals in UTF-8 module.") + (provision '(virtual-terminal)) + (requirement '(root-file-system)) + (start #~(lambda _ + ;; In containers /sys is read-only so don't insist on + ;; writing to this file. + (unless (= 1 (call-with-input-file #$knob read)) + (call-with-output-file #$knob + (lambda (port) + (display 1 port)))) + #t)) + (stop #~(const #f))))) #t)) ;default to UTF-8 (define console-keymap-service-type @@ -1881,7 +1884,12 @@ item of @var{packages}." (string-append linux-module-directory "/" kernel-release)) (old-umask (umask #o022))) - (make-static-device-nodes directory) + ;; If we're in a container, DIRECTORY might not exist, + ;; for instance because the host runs a different + ;; kernel. In that case, skip it; we'll just miss a few + ;; nodes like /dev/fuse. + (when (file-exists? directory) + (make-static-device-nodes directory)) (umask old-umask)) (let ((pid (fork+exec-command (list udevd)))) diff --git a/gnu/services/herd.scm b/gnu/services/herd.scm index 8c96b70731..8ff817759d 100644 --- a/gnu/services/herd.scm +++ b/gnu/services/herd.scm @@ -50,6 +50,7 @@ unload-services unload-service load-services + load-services/safe start-service stop-service)) @@ -232,6 +233,25 @@ returns a shepherd <service> object." `(primitive-load ,file)) files)))) +(define (load-services/safe files) + "This is like 'load-services', but make sure only the subset of FILES that +can be safely reloaded is actually reloaded. + +This is done to accommodate the Shepherd < 0.15.0 where services lacked the +'replacement' slot, and where 'register-services' would throw an exception +when passed a service with an already-registered name." + (eval-there `(let* ((services (map primitive-load ',files)) + (slots (map slot-definition-name + (class-slots <service>))) + (can-replace? (memq 'replacement slots))) + (define (registered? service) + (not (null? (lookup-services (canonical-name service))))) + + (apply register-services + (if can-replace? + services + (remove registered? services)))))) + (define (start-service name) (with-shepherd-action name ('start) result result)) diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index bd1d5a2706..3fdb2bb9f7 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org> ;;; Copyright © 2016, 2018 Efraim Flashner <efraim@flashner.co.il> ;;; Copyright © 2016 John Darrington <jmd@gnu.org> @@ -191,19 +191,7 @@ fe80::1%lo0 apps.facebook.com\n") (cons* #$dhclient "-nw" "-pf" #$pid-file ifaces)))) (and (zero? (cdr (waitpid pid))) - (let loop () - (catch 'system-error - (lambda () - (call-with-input-file #$pid-file read)) - (lambda args - ;; 'dhclient' returned before PID-FILE was created, - ;; so try again. - (let ((errno (system-error-errno args))) - (if (= ENOENT errno) - (begin - (sleep 1) - (loop)) - (apply throw args)))))))))) + (read-pid-file #$pid-file))))) (stop #~(make-kill-destructor)))))) (define* (dhcp-client-service #:key (dhcp isc-dhcp)) diff --git a/gnu/services/shepherd.scm b/gnu/services/shepherd.scm index 4cd2249841..49d08cc30f 100644 --- a/gnu/services/shepherd.scm +++ b/gnu/services/shepherd.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2018 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org> +;;; Copyright © 2018 Carlo Zancanaro <carlo@zancanaro.id.au> ;;; ;;; This file is part of GNU Guix. ;;; @@ -58,6 +59,7 @@ %default-modules shepherd-service-file + %containerized-shepherd-service shepherd-service-lookup-procedure shepherd-service-back-edges @@ -326,10 +328,25 @@ symbols provided/required by a service." (lambda (service) (vhash-foldq* cons '() service edges))) +(define %containerized-shepherd-service + ;; XXX: This service works around a bug in the Shepherd 0.5.0: shepherd + ;; calls reboot(2) (via 'disable-reboot-on-ctrl-alt-del') when it starts, + ;; but in a container that fails with EINVAL. This was fixed in Shepherd + ;; commit 92e806bac1abaeeaf5d60f0ab50d1ae85ba6a62f. + (simple-service 'containerized-shepherd + shepherd-root-service-type + (list (shepherd-service + (provision '(containerized-shepherd)) + (start #~(lambda () + (set! (@@ (shepherd) + disable-reboot-on-ctrl-alt-del) + (const #t)) + #t)))))) + (define (shepherd-service-upgrade live target) "Return two values: the subset of LIVE (a list of <live-service>) that needs to be unloaded, and the subset of TARGET (a list of <shepherd-service>) that -needs to be loaded." +need to be restarted to complete their upgrade." (define (essential? service) (memq (first (live-service-provision service)) '(root shepherd))) @@ -346,12 +363,6 @@ needs to be loaded." (and=> (lookup-live (shepherd-service-canonical-name service)) live-service-running)) - (define (stopped service) - (match (lookup-live (shepherd-service-canonical-name service)) - (#f #f) - (service (and (not (live-service-running service)) - service)))) - (define live-service-dependents (shepherd-service-back-edges live #:provision live-service-provision @@ -362,16 +373,14 @@ needs to be loaded." (#f (every obsolete? (live-service-dependents service))) (_ #f))) - (define to-load - ;; Only load services that are either new or currently stopped. - (remove running? target)) + (define to-restart + ;; Restart services that are currently running. + (filter running? target)) (define to-unload - ;; Unload services that are (1) no longer required, or (2) are in TO-LOAD. - (remove essential? - (append (filter obsolete? live) - (filter-map stopped to-load)))) + ;; Unload services that are no longer required. + (remove essential? (filter obsolete? live))) - (values to-unload to-load)) + (values to-unload to-restart)) ;;; shepherd.scm ends here diff --git a/gnu/services/version-control.scm b/gnu/services/version-control.scm index 58274c8bee..13669925ab 100644 --- a/gnu/services/version-control.scm +++ b/gnu/services/version-control.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org> ;;; Copyright © 2017 Oleg Pykhalov <go.wigust@gmail.com> ;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org> +;;; Copyright © 2018 Christopher Baines <mail@cbaines.net> ;;; ;;; This file is part of GNU Guix. ;;; @@ -32,6 +33,7 @@ #:use-module (guix store) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) + #:use-module (ice-9 format) #:use-module (ice-9 match) #:export (git-daemon-service git-daemon-service-type @@ -40,7 +42,23 @@ git-http-configuration git-http-configuration? - git-http-nginx-location-configuration)) + git-http-nginx-location-configuration + + <gitolite-configuration> + gitolite-configuration + gitolite-configuration-package + gitolite-configuration-user + gitolite-configuration-rc-file + gitolite-configuration-admin-pubkey + + <gitolite-rc-file> + gitolite-rc-file + gitolite-rc-file-umask + gitolite-rc-file-git-config-keys + gitolite-rc-file-roles + gitolite-rc-file-enable + + gitolite-service-type)) ;;; Commentary: ;;; @@ -197,3 +215,163 @@ access to exported repositories under @file{/srv/git}." "") (list "fastcgi_param GIT_PROJECT_ROOT " git-root ";") "fastcgi_param PATH_INFO $1;")))))) + + +;;; +;;; Gitolite +;;; + +(define-record-type* <gitolite-rc-file> + gitolite-rc-file make-gitolite-rc-file + gitolite-rc-file? + (umask gitolite-rc-file-umask + (default #o0077)) + (git-config-keys gitolite-rc-file-git-config-keys + (default "")) + (roles gitolite-rc-file-roles + (default '(("READERS" . 1) + ("WRITERS" . 1)))) + (enable gitolite-rc-file-enable + (default '("help" + "desc" + "info" + "perms" + "writable" + "ssh-authkeys" + "git-config" + "daemon" + "gitweb")))) + +(define-gexp-compiler (gitolite-rc-file-compiler + (file <gitolite-rc-file>) system target) + (match file + (($ <gitolite-rc-file> umask git-config-keys roles enable) + (apply text-file* "gitolite.rc" + `("%RC = (\n" + " UMASK => " ,(format #f "~4,'0o" umask) ",\n" + " GIT_CONFIG_KEYS => '" ,git-config-keys "',\n" + " ROLES => {\n" + ,@(map (match-lambda + ((role . value) + (simple-format #f " ~A => ~A,\n" role value))) + roles) + " },\n" + "\n" + " ENABLE => [\n" + ,@(map (lambda (value) + (simple-format #f " '~A',\n" value)) + enable) + " ],\n" + ");\n" + "\n" + "1;\n"))))) + +(define-record-type* <gitolite-configuration> + gitolite-configuration make-gitolite-configuration + gitolite-configuration? + (package gitolite-configuration-package + (default gitolite)) + (user gitolite-configuration-user + (default "git")) + (group gitolite-configuration-group + (default "git")) + (home-directory gitolite-configuration-home-directory + (default "/var/lib/gitolite")) + (rc-file gitolite-configuration-rc-file + (default (gitolite-rc-file))) + (admin-pubkey gitolite-configuration-admin-pubkey)) + +(define gitolite-accounts + (match-lambda + (($ <gitolite-configuration> package user group home-directory + rc-file admin-pubkey) + ;; User group and account to run Gitolite. + (list (user-group (name user) (system? #t)) + (user-account + (name user) + (group group) + (system? #t) + (comment "Gitolite user") + (home-directory home-directory)))))) + +(define gitolite-activation + (match-lambda + (($ <gitolite-configuration> package user group home + rc-file admin-pubkey) + #~(begin + (use-modules (ice-9 match) + (guix build utils)) + + (let* ((user-info (getpwnam #$user)) + (admin-pubkey #$admin-pubkey) + (pubkey-file (string-append + #$home "/" + (basename + (strip-store-file-name admin-pubkey))))) + + (simple-format #t "guix: gitolite: installing ~A\n" #$rc-file) + (copy-file #$rc-file #$(string-append home "/.gitolite.rc")) + + ;; The key must be writable, so copy it from the store + (copy-file admin-pubkey pubkey-file) + + (chmod pubkey-file #o500) + (chown pubkey-file + (passwd:uid user-info) + (passwd:gid user-info)) + + ;; Set the git configuration, to avoid gitolite trying to use + ;; the hostname command, as the network might not be up yet + (with-output-to-file #$(string-append home "/.gitconfig") + (lambda () + (display "[user] + name = GNU Guix + email = guix@localhost +"))) + ;; Run Gitolite setup, as this updates the hooks and include the + ;; admin pubkey if specified. The admin pubkey is required for + ;; initial setup, and will replace the previous key if run after + ;; initial setup + (match (primitive-fork) + (0 + ;; Exit with a non-zero status code if an exception is thrown. + (dynamic-wind + (const #t) + (lambda () + (setenv "HOME" (passwd:dir user-info)) + (setenv "USER" #$user) + (setgid (passwd:gid user-info)) + (setuid (passwd:uid user-info)) + (primitive-exit + (system* #$(file-append package "/bin/gitolite") + "setup" + "-m" "gitolite setup by GNU Guix" + "-pk" pubkey-file))) + (lambda () + (primitive-exit 1)))) + (pid (waitpid pid))) + + (when (file-exists? pubkey-file) + (delete-file pubkey-file))))))) + +(define gitolite-service-type + (service-type + (name 'gitolite) + (extensions + (list (service-extension activation-service-type + gitolite-activation) + (service-extension account-service-type + gitolite-accounts) + (service-extension profile-service-type + ;; The Gitolite package in Guix uses + ;; gitolite-shell in the authorized_keys file, so + ;; gitolite-shell needs to be on the PATH for + ;; gitolite to work. + (lambda (config) + (list + (gitolite-configuration-package config)))))) + (description + "Setup @command{gitolite}, a Git hosting tool providing access over SSH.. +By default, the @code{git} user is used, but this is configurable. +Additionally, Gitolite can integrate with with tools like gitweb or cgit to +provide a web interface to view selected repositories."))) |