X-Git-Url: https://git.hcoop.net/jackhill/guix/guix.git/blobdiff_plain/072e10615fc786db02dc44f3cd5f25aed2969111..49b6dc2b4e02269850dacc71d9e7ec93139ec5b5:/gnu/services/herd.scm diff --git a/gnu/services/herd.scm b/gnu/services/herd.scm index 03bfbf1d78..8c96b70731 100644 --- a/gnu/services/herd.scm +++ b/gnu/services/herd.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2016 Ludovic Courtès +;;; Copyright © 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2017 Mathieu Othacehe ;;; ;;; This file is part of GNU Guix. ;;; @@ -23,7 +24,9 @@ #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) #:use-module (ice-9 match) - #:export (shepherd-error? + #:export (%shepherd-socket-file + + shepherd-error? service-not-found-error? service-not-found-error-service action-not-found-error? @@ -42,11 +45,13 @@ live-service-requirement live-service-running + with-shepherd-action current-services unload-services unload-service load-services - start-service)) + start-service + stop-service)) ;;; Commentary: ;;; @@ -58,9 +63,9 @@ ;;; Code: (define %shepherd-socket-file - "/var/run/shepherd/socket") + (make-parameter "/var/run/shepherd/socket")) -(define* (open-connection #:optional (file %shepherd-socket-file)) +(define* (open-connection #:optional (file (%shepherd-socket-file))) "Open a connection to the daemon, using the Unix-domain socket at FILE, and return the socket." ;; The protocol is sexp-based and UTF-8-encoded. @@ -79,7 +84,12 @@ return the socket." (define-syntax-rule (with-shepherd connection body ...) "Evaluate BODY... with CONNECTION bound to an open socket to PID 1." (let ((connection (open-connection))) - body ...)) + (dynamic-wind + (const #t) + (lambda () + body ...) + (lambda () + (close-port connection))))) (define-condition-type &shepherd-error &error shepherd-error?) @@ -132,7 +142,8 @@ does not denote an error." (define* (invoke-action service action arguments cont) "Invoke ACTION on SERVICE with ARGUMENTS. On success, call CONT with the -result. Otherwise return #f." +list of results (one result per instance with the name SERVICE). Otherwise +return #f." (with-shepherd sock (write `(shepherd-command (version 0) (action ,action) @@ -143,7 +154,7 @@ result. Otherwise return #f." (force-output sock) (match (read sock) - (('reply ('version 0 _ ...) ('result (result)) ('error #f) + (('reply ('version 0 _ ...) ('result result) ('error #f) ('messages messages)) (for-each display-message messages) (cont result)) @@ -158,6 +169,8 @@ result. Otherwise return #f." (define-syntax-rule (with-shepherd-action service (action args ...) result body ...) + "Invoke ACTION on SERVICE with the given ARGS, and evaluate BODY with RESULT +bound to the action's result." (invoke-action service action (list args ...) (lambda (result) body ...))) @@ -182,30 +195,34 @@ of pairs." "Return the list of currently defined Shepherd services, represented as objects. Return #f if the list of services could not be obtained." - (with-shepherd-action 'root ('status) services - (match services - ((('service ('version 0 _ ...) _ ...) ...) - (map (lambda (service) - (alist-let* service (provides requires running) - (live-service provides requires running))) - services)) - (x - #f)))) + (with-shepherd-action 'root ('status) results + ;; We get a list of results, one for each service with the name 'root'. + ;; In practice there's only one such service though. + (match results + ((services _ ...) + (match services + ((('service ('version 0 _ ...) _ ...) ...) + (map (lambda (service) + (alist-let* service (provides requires running) + (live-service provides requires running))) + services)) + (x + #f)))))) (define (unload-service service) "Unload SERVICE, a symbol name; return #t on success." (with-shepherd-action 'root ('unload (symbol->string service)) result - result)) + (first result))) (define (%load-file file) "Load FILE in the Shepherd." (with-shepherd-action 'root ('load file) result - result)) + (first result))) (define (eval-there exp) "Eval EXP in the Shepherd." (with-shepherd-action 'root ('eval (object->string exp)) result - result)) + (first result))) (define (load-services files) "Load and register the services from FILES, where FILES contain code that @@ -219,6 +236,10 @@ returns a shepherd object." (with-shepherd-action name ('start) result result)) +(define (stop-service name) + (with-shepherd-action name ('stop) result + result)) + ;; Local Variables: ;; eval: (put 'alist-let* 'scheme-indent-function 2) ;; eval: (put 'with-shepherd 'scheme-indent-function 1)