guix system: Simply warn if we cannot talk to the shepherd.
Before that 'open-connection' would return #f, and thus 'current-services' would return a single #f value when its continuation expects two. Reported by calher on #guix. * gnu/services/herd.scm (open-connection): Rethrow system-error exceptions. (with-shepherd): Expect CONNECTION to always be true; remove useless 'dynamic-wind'. * guix/scripts/system.scm (warn-on-system-error): New macro. (upgrade-shepherd-services): Wrap body in 'warn-on-system-error'.
This commit is contained in:
parent
6b55ee8889
commit
1d6b7d5847
|
@ -52,20 +52,14 @@ return the socket."
|
||||||
(connect sock address)
|
(connect sock address)
|
||||||
(setvbuf sock _IOFBF 1024)
|
(setvbuf sock _IOFBF 1024)
|
||||||
sock)
|
sock)
|
||||||
(lambda (key proc format-string format-args errno . rest)
|
(lambda args
|
||||||
(warning (_ "cannot connect to ~a: ~a~%") file
|
(close-port sock)
|
||||||
(apply format #f format-string format-args))
|
(apply throw args))))))
|
||||||
#f)))))
|
|
||||||
|
|
||||||
(define-syntax-rule (with-shepherd connection body ...)
|
(define-syntax-rule (with-shepherd connection body ...)
|
||||||
"Evaluate BODY... with CONNECTION bound to an open socket to PID 1."
|
"Evaluate BODY... with CONNECTION bound to an open socket to PID 1."
|
||||||
(let ((connection (open-connection)))
|
(let ((connection (open-connection)))
|
||||||
(and connection
|
body ...))
|
||||||
(dynamic-wind
|
|
||||||
(const #t)
|
|
||||||
(lambda ()
|
|
||||||
body ...)
|
|
||||||
(const #t)))))
|
|
||||||
|
|
||||||
(define (report-action-error error)
|
(define (report-action-error error)
|
||||||
"Report ERROR, an sexp received by a shepherd client in reply to COMMAND, a
|
"Report ERROR, an sexp received by a shepherd client in reply to COMMAND, a
|
||||||
|
|
|
@ -211,6 +211,16 @@ the ownership of '~a' may be incorrect!~%")
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(environ env)))))
|
(environ env)))))
|
||||||
|
|
||||||
|
(define-syntax-rule (warn-on-system-error body ...)
|
||||||
|
(catch 'system-error
|
||||||
|
(lambda ()
|
||||||
|
body ...)
|
||||||
|
(lambda (key proc format-string format-args errno . rest)
|
||||||
|
(warning (_ "while talking to shepherd: ~a~%")
|
||||||
|
(apply format #f format-string format-args))
|
||||||
|
(with-monad %store-monad
|
||||||
|
(return #f)))))
|
||||||
|
|
||||||
(define (upgrade-shepherd-services os)
|
(define (upgrade-shepherd-services os)
|
||||||
"Upgrade the Shepherd (PID 1) by unloading obsolete services and loading new
|
"Upgrade the Shepherd (PID 1) by unloading obsolete services and loading new
|
||||||
services specified in OS and not currently running.
|
services specified in OS and not currently running.
|
||||||
|
@ -230,42 +240,44 @@ bring the system down."
|
||||||
(map (compose first shepherd-service-provision)
|
(map (compose first shepherd-service-provision)
|
||||||
new-services))
|
new-services))
|
||||||
|
|
||||||
(let-values (((running stopped) (current-services)))
|
;; Arrange to simply emit a warning if we cannot connect to the shepherd.
|
||||||
(define to-load
|
(warn-on-system-error
|
||||||
;; Only load services that are either new or currently stopped.
|
(let-values (((running stopped) (current-services)))
|
||||||
(remove (lambda (service)
|
(define to-load
|
||||||
(memq (first (shepherd-service-provision service))
|
;; Only load services that are either new or currently stopped.
|
||||||
running))
|
(remove (lambda (service)
|
||||||
new-services))
|
(memq (first (shepherd-service-provision service))
|
||||||
(define to-unload
|
running))
|
||||||
;; Unload services that are (1) no longer required, or (2) are in
|
new-services))
|
||||||
;; TO-LOAD.
|
(define to-unload
|
||||||
(remove essential?
|
;; Unload services that are (1) no longer required, or (2) are in
|
||||||
(append (remove (lambda (service)
|
;; TO-LOAD.
|
||||||
(memq service new-service-names))
|
(remove essential?
|
||||||
(append running stopped))
|
(append (remove (lambda (service)
|
||||||
(filter (lambda (service)
|
(memq service new-service-names))
|
||||||
(memq service stopped))
|
(append running stopped))
|
||||||
(map shepherd-service-canonical-name
|
(filter (lambda (service)
|
||||||
to-load)))))
|
(memq service stopped))
|
||||||
|
(map shepherd-service-canonical-name
|
||||||
|
to-load)))))
|
||||||
|
|
||||||
(for-each (lambda (unload)
|
(for-each (lambda (unload)
|
||||||
(info (_ "unloading service '~a'...~%") unload)
|
(info (_ "unloading service '~a'...~%") unload)
|
||||||
(unload-service unload))
|
(unload-service unload))
|
||||||
to-unload)
|
to-unload)
|
||||||
|
|
||||||
(with-monad %store-monad
|
(with-monad %store-monad
|
||||||
(munless (null? to-load)
|
(munless (null? to-load)
|
||||||
(let ((to-load-names (map shepherd-service-canonical-name to-load))
|
(let ((to-load-names (map shepherd-service-canonical-name to-load))
|
||||||
(to-start (filter shepherd-service-auto-start? to-load)))
|
(to-start (filter shepherd-service-auto-start? to-load)))
|
||||||
(info (_ "loading new services:~{ ~a~}...~%") to-load-names)
|
(info (_ "loading new services:~{ ~a~}...~%") to-load-names)
|
||||||
(mlet %store-monad ((files (mapm %store-monad shepherd-service-file
|
(mlet %store-monad ((files (mapm %store-monad shepherd-service-file
|
||||||
to-load)))
|
to-load)))
|
||||||
(load-services (map derivation->output-path files))
|
(load-services (map derivation->output-path files))
|
||||||
|
|
||||||
(for-each start-service
|
(for-each start-service
|
||||||
(map shepherd-service-canonical-name to-start))
|
(map shepherd-service-canonical-name to-start))
|
||||||
(return #t)))))))
|
(return #t))))))))
|
||||||
|
|
||||||
(define* (switch-to-system os
|
(define* (switch-to-system os
|
||||||
#:optional (profile %system-profile))
|
#:optional (profile %system-profile))
|
||||||
|
|
Loading…
Reference in New Issue