summaryrefslogtreecommitdiff
path: root/guix/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'guix/scripts')
-rw-r--r--guix/scripts/archive.scm1
-rw-r--r--guix/scripts/build.scm1
-rw-r--r--guix/scripts/environment.scm10
-rw-r--r--guix/scripts/graph.scm2
-rw-r--r--guix/scripts/lint.scm1
-rw-r--r--guix/scripts/size.scm2
-rwxr-xr-xguix/scripts/substitute.scm1
-rw-r--r--guix/scripts/system.scm142
8 files changed, 105 insertions, 55 deletions
diff --git a/guix/scripts/archive.scm b/guix/scripts/archive.scm
index 3fb210ee91..e06c38aaab 100644
--- a/guix/scripts/archive.scm
+++ b/guix/scripts/archive.scm
@@ -19,6 +19,7 @@
(define-module (guix scripts archive)
#:use-module (guix config)
#:use-module (guix utils)
+ #:use-module (guix combinators)
#:use-module ((guix build utils) #:select (mkdir-p))
#:use-module ((guix serialization) #:select (restore-file))
#:use-module (guix store)
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index 9a6b427fc5..320ec39be2 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -24,6 +24,7 @@
#:use-module (guix derivations)
#:use-module (guix packages)
#:use-module (guix grafts)
+ #:use-module (guix combinators)
;; Use the procedure that destructures "NAME-VERSION" forms.
#:use-module ((guix utils) #:hide (package-name->name+version))
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index d4c09ef54c..9ba487d1eb 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -25,7 +25,6 @@
#:use-module (guix packages)
#:use-module (guix profiles)
#:use-module (guix search-paths)
- #:use-module (guix utils)
#:use-module (guix build utils)
#:use-module (guix monads)
#:use-module ((guix gexp) #:select (lower-inputs))
@@ -499,12 +498,13 @@ Otherwise, return the derivation for the Bash package."
;; The '--' token is used to separate the command to run from the rest of
;; the operands.
- (let-values (((args command) (split args "--")))
+ (let-values (((args command) (break (cut string=? "--" <>) args)))
(let ((opts (parse-command-line args %options (list %default-options)
#:argument-handler handle-argument)))
- (if (null? command)
- opts
- (alist-cons 'exec command opts)))))
+ (match command
+ (() opts)
+ (("--") opts)
+ (("--" command ...) (alist-cons 'exec command opts))))))
(define (assert-container-features)
"Check if containers can be created and exit with an informative error
diff --git a/guix/scripts/graph.scm b/guix/scripts/graph.scm
index b0d7c08582..ba63780e2b 100644
--- a/guix/scripts/graph.scm
+++ b/guix/scripts/graph.scm
@@ -21,7 +21,7 @@
#:use-module (guix graph)
#:use-module (guix grafts)
#:use-module (guix scripts)
- #:use-module (guix utils)
+ #:use-module (guix combinators)
#:use-module (guix packages)
#:use-module (guix monads)
#:use-module (guix store)
diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm
index c581586ac3..06001d3eae 100644
--- a/guix/scripts/lint.scm
+++ b/guix/scripts/lint.scm
@@ -31,6 +31,7 @@
#:use-module (guix records)
#:use-module (guix ui)
#:use-module (guix utils)
+ #:use-module (guix combinators)
#:use-module (guix scripts)
#:use-module (guix gnu-maintenance)
#:use-module (guix monads)
diff --git a/guix/scripts/size.scm b/guix/scripts/size.scm
index 8f0cb7decd..be1e8ca087 100644
--- a/guix/scripts/size.scm
+++ b/guix/scripts/size.scm
@@ -21,7 +21,7 @@
#:use-module (guix scripts)
#:use-module (guix store)
#:use-module (guix monads)
- #:use-module (guix utils)
+ #:use-module (guix combinators)
#:use-module (guix grafts)
#:use-module (guix packages)
#:use-module (guix derivations)
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm
index 1cfab81dbd..d46d610347 100755
--- a/guix/scripts/substitute.scm
+++ b/guix/scripts/substitute.scm
@@ -21,6 +21,7 @@
#:use-module (guix ui)
#:use-module ((guix store) #:hide (close-connection))
#:use-module (guix utils)
+ #:use-module (guix combinators)
#:use-module (guix config)
#:use-module (guix records)
#:use-module (guix serialization)
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index e5d754a6fa..dd1e534c9b 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -236,6 +236,72 @@ BODY..., and restore them."
(with-monad %store-monad
(return #f)))))
+(define-syntax-rule (with-shepherd-error-handling body ...)
+ (warn-on-system-error
+ (guard (c ((shepherd-error? c)
+ (report-shepherd-error c)))
+ body ...)))
+
+(define (report-shepherd-error error)
+ "Report ERROR, a '&shepherd-error' error condition object."
+ (cond ((service-not-found-error? error)
+ (report-error (_ "service '~a' could not be found~%")
+ (service-not-found-error-service error)))
+ ((action-not-found-error? error)
+ (report-error (_ "service '~a' does not have an action '~a'~%")
+ (action-not-found-error-service error)
+ (action-not-found-error-action error)))
+ ((action-exception-error? error)
+ (report-error (_ "exception caught while executing '~a' \
+on service '~a':~%")
+ (action-exception-error-action error)
+ (action-exception-error-service error))
+ (print-exception (current-error-port) #f
+ (action-exception-error-key error)
+ (action-exception-error-arguments error)))
+ ((unknown-shepherd-error? error)
+ (report-error (_ "something went wrong: ~s~%")
+ (unknown-shepherd-error-sexp error)))
+ ((shepherd-error? error)
+ (report-error (_ "shepherd error~%")))
+ ((not error) ;not an error
+ #t)))
+
+(define (call-with-service-upgrade-info new-services mproc)
+ "Call MPROC, a monadic procedure in %STORE-MONAD, passing it the list of
+names of services to load (upgrade), and the list of names of services to
+unload."
+ (define (essential? service)
+ (memq service '(root shepherd)))
+
+ (define new-service-names
+ (map (compose first shepherd-service-provision)
+ new-services))
+
+ (let-values (((running stopped) (current-services)))
+ (if (and running stopped)
+ (let* ((to-load
+ ;; Only load services that are either new or currently stopped.
+ (remove (lambda (service)
+ (memq (first (shepherd-service-provision service))
+ running))
+ new-services))
+ (to-unload
+ ;; Unload services that are (1) no longer required, or (2) are
+ ;; in TO-LOAD.
+ (remove essential?
+ (append (remove (lambda (service)
+ (memq service new-service-names))
+ (append running stopped))
+ (filter (lambda (service)
+ (memq service stopped))
+ (map shepherd-service-canonical-name
+ to-load))))))
+ (mproc to-load to-unload))
+ (with-monad %store-monad
+ (warning (_ "failed to obtain list of shepherd services~%"))
+ (return #f)))))
+
(define (upgrade-shepherd-services os)
"Upgrade the Shepherd (PID 1) by unloading obsolete services and loading new
services specified in OS and not currently running.
@@ -243,59 +309,35 @@ services specified in OS and not currently running.
This is currently very conservative in that it does not stop or unload any
running service. Unloading or stopping the wrong service ('udev', say) could
bring the system down."
- (define (essential? service)
- (memq service '(root shepherd)))
-
(define new-services
(service-parameters
(fold-services (operating-system-services os)
#:target-type shepherd-root-service-type)))
- (define new-service-names
- (map (compose first shepherd-service-provision)
- new-services))
-
- ;; Arrange to simply emit a warning if we cannot connect to the shepherd.
- (warn-on-system-error
- (let-values (((running stopped) (current-services)))
- (define to-load
- ;; Only load services that are either new or currently stopped.
- (remove (lambda (service)
- (memq (first (shepherd-service-provision service))
- running))
- new-services))
- (define to-unload
- ;; Unload services that are (1) no longer required, or (2) are in
- ;; TO-LOAD.
- (remove essential?
- (append (remove (lambda (service)
- (memq service new-service-names))
- (append running stopped))
- (filter (lambda (service)
- (memq service stopped))
- (map shepherd-service-canonical-name
- to-load)))))
-
- (for-each (lambda (unload)
- (info (_ "unloading service '~a'...~%") unload)
- (unload-service unload))
- to-unload)
-
- (with-monad %store-monad
- (munless (null? to-load)
- (let ((to-load-names (map shepherd-service-canonical-name to-load))
- (to-start (filter shepherd-service-auto-start? to-load)))
- (info (_ "loading new services:~{ ~a~}...~%") to-load-names)
- (mlet %store-monad ((files (mapm %store-monad shepherd-service-file
- to-load)))
- ;; Here we assume that FILES are exactly those that were computed
- ;; as part of the derivation that built OS, which is normally the
- ;; case.
- (load-services (map derivation->output-path files))
-
- (for-each start-service
- (map shepherd-service-canonical-name to-start))
- (return #t))))))))
+ ;; Arrange to simply emit a warning if the service upgrade fails.
+ (with-shepherd-error-handling
+ (call-with-service-upgrade-info new-services
+ (lambda (to-load to-unload)
+ (for-each (lambda (unload)
+ (info (_ "unloading service '~a'...~%") unload)
+ (unload-service unload))
+ to-unload)
+
+ (with-monad %store-monad
+ (munless (null? to-load)
+ (let ((to-load-names (map shepherd-service-canonical-name to-load))
+ (to-start (filter shepherd-service-auto-start? to-load)))
+ (info (_ "loading new services:~{ ~a~}...~%") to-load-names)
+ (mlet %store-monad ((files (mapm %store-monad shepherd-service-file
+ to-load)))
+ ;; Here we assume that FILES are exactly those that were computed
+ ;; as part of the derivation that built OS, which is normally the
+ ;; case.
+ (load-services (map derivation->output-path files))
+
+ (for-each start-service
+ (map shepherd-service-canonical-name to-start))
+ (return #t)))))))))
(define* (switch-to-system os
#:optional (profile %system-profile))
@@ -839,4 +881,8 @@ argument list and OPTS is the option alist."
(parameterize ((%graft? (assoc-ref opts 'graft?)))
(process-command command args opts)))))
+;;; Local Variables:
+;;; eval: (put 'call-with-service-upgrade-info 'scheme-indent-function 1)
+;;; End:
+
;;; system.scm ends here