guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[shepherd] 05/05: service: Raise specific error conditions for missing s


From: Ludovic Courtès
Subject: [shepherd] 05/05: service: Raise specific error conditions for missing services.
Date: Mon, 18 Jan 2016 22:10:59 +0000

civodul pushed a commit to branch master
in repository shepherd.

commit 25aa597d20ab5102470765930d51214d868d65e8
Author: Ludovic Courtès <address@hidden>
Date:   Mon Jan 18 23:02:30 2016 +0100

    service: Raise specific error conditions for missing services.
    
    This fixes a regression introduced in 2f204c9 whereby
    "herd status does-not-exist" would spit out a backtrace on a 'match'
    error.
    
    * modules/shepherd/service.scm (&service-error, &missing-service-error):
    New error conditions.
    (launch-service, stop, action, deregister-service): Raise it instead of
    using 'local-output' when the designated service is missing.
    * modules/shepherd.scm (process-command): Guard against
    &missing-service-error and handle it.
    * modules/herd.scm (display-service-status): Handle 'error' sexps.
    * tests/basic.sh: Test exit code of "herd status does-not-exist".
    * tests/status-sexp.sh: Test sexp returned for nonexistent services.
---
 modules/herd.scm             |   11 ++++++++++-
 modules/shepherd.scm         |   28 ++++++++++++++++++++--------
 modules/shepherd/service.scm |   32 ++++++++++++++++++++++++--------
 tests/basic.sh               |    5 +++++
 tests/status-sexp.sh         |   13 +++++++++++++
 5 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/modules/herd.scm b/modules/herd.scm
index 47934a6..1351bde 100644
--- a/modules/herd.scm
+++ b/modules/herd.scm
@@ -97,7 +97,16 @@ of pairs."
        ;; (format #t (l10n "  Conflicts with ~a." (conflicts-with obj)))
        (if respawn?
            (format #t (l10n "  Will be respawned.~%"))
-           (format #t (l10n "  Will not be respawned.~%")))))))
+           (format #t (l10n "  Will not be respawned.~%")))))
+    (('error ('version 0 _ ...) 'service-not-found service)
+     (format (current-error-port)
+             (l10n "Service ~a could not be found.~%")
+             service)
+     (exit 1))
+    (('error . _)
+     (format (current-error-port)
+             (l10n "Something went wrong: ~s~%")
+             service))))
 
 (define (run-command socket-file action service args)
   "Perform ACTION with ARGS on SERVICE, and display the result.  Connect to
diff --git a/modules/shepherd.scm b/modules/shepherd.scm
index cc74743..01097ea 100644
--- a/modules/shepherd.scm
+++ b/modules/shepherd.scm
@@ -24,6 +24,7 @@
   #:use-module (oop goops)      ;; Defining classes and methods.
   #:use-module (srfi srfi-1)    ;; List library.
   #:use-module (srfi srfi-26)
+  #:use-module (srfi srfi-34)
   #:use-module (shepherd config)
   #:use-module (shepherd support)
   #:use-module (shepherd service)
@@ -228,14 +229,25 @@
      ;; line to herd before we actually quit.
      (catch 'quit
        (lambda ()
-         (case the-action
-           ((start) (apply start service-symbol args))
-           ((stop) (apply stop service-symbol args))
-           ((enforce) (apply enforce service-symbol args))
+         (guard (c ((missing-service-error? c)
+                    (case the-action
+                      ((status)
+                       ;; For these actions, we must always return an sexp.
+                       ;; TODO: Extend this to all actions.
+                       (display `(error (version 0) service-not-found
+                                        ,(missing-service-name c))
+                                (%current-client-socket)))
+                      (else
+                       (local-output "Service ~a not found"
+                                     (missing-service-name c))))))
+           (case the-action
+             ((start) (apply start service-symbol args))
+             ((stop) (apply stop service-symbol args))
+             ((enforce) (apply enforce service-symbol args))
 
-           ;; Actions which have the semantics of `action' are
-           ;; handled there.
-           (else (apply action service-symbol the-action args))))
+             ;; Actions which have the semantics of `action' are
+             ;; handled there.
+             (else (apply action service-symbol the-action args)))))
        (lambda (key)
          ;; Most likely we're receiving 'quit' from the 'stop' method of
          ;; DMD-SERVICE.  So, if we're running as 'root', just reboot.
diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm
index 72fe34c..453b48a 100644
--- a/modules/shepherd/service.scm
+++ b/modules/shepherd/service.scm
@@ -22,6 +22,8 @@
   #:use-module (oop goops)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-26)
+  #:use-module (srfi srfi-34)
+  #:use-module (srfi srfi-35)
   #:use-module (ice-9 match)
   #:use-module (ice-9 format)
   #:use-module (shepherd support)
@@ -68,7 +70,13 @@
             make-init.d-service
 
             dmd-service
-            make-actions))
+            make-actions
+
+            &service-error
+            service-error?
+            &missing-service-error
+            missing-service-error?
+            missing-service-name))
 
 ;; Conveniently create an actions object containing the actions for a
 ;; <service> object.  The current structure is a list of actions,
@@ -167,6 +175,15 @@ respawned, shows that it has been respawned more than 
TIMES in SECONDS."
 (define action:proc cadr)
 (define action:doc cddr)
 
+;; Service errors.
+(define-condition-type &service-error &error service-error?)
+
+;; Error raised when looking up a service by name fails.
+(define-condition-type &missing-service-error &service-error
+  missing-service-error?
+  (name missing-service-name))
+
+
 ;; Return the canonical name of the service.
 (define-method (canonical-name (obj <service>))
   (car (provided-by obj)))
@@ -428,7 +445,7 @@ clients."
 (define (launch-service name proc args)
   (match (lookup-services name)
     (()
-     (local-output "No service provides ~a." name))
+     (raise (condition (&missing-service-error (name name)))))
     ((possibilities ...)
      (or (first-running possibilities)
 
@@ -460,8 +477,8 @@ clients."
          (if (and unknown
                   (defines-action? unknown 'stop))
              (apply action unknown 'stop obj args)
-           (local-output "No service currently providing ~a." obj)))
-      (apply stop which args))))
+              (raise (condition (&missing-service-error (name obj))))))
+        (apply stop which args))))
 
 ;; Perform action THE-ACTION by name.
 (define-method (action (obj <symbol>) the-action . args)
@@ -471,7 +488,7 @@ clients."
          (if (and unknown
                   (defines-action? unknown 'action))
              (apply action unknown 'action the-action args)
-           (local-output "No service at all providing ~a." obj)))
+              (raise (condition (&missing-service-error (name obj))))))
       (for-each (lambda (s)
                  (apply (case the-action
                           ((enable) enable)
@@ -917,10 +934,9 @@ requested to be removed."
            ;; Removing only one service.
            (match (lookup-services name)
              (()                        ; unknown service
-              (local-output
-               "Not unloading: '~a' is an uknown service." name))
+              (raise (condition (&missing-service-error (name name)))))
              ((service)             ; only SERVICE provides NAME
-              ;; Are we removing a user service窶ヲ
+              ;; Are we removing a user service…
               (if (eq? (canonical-name service) name)
                   (local-output "Removing service '~a'..." name)
                   ;; or a virtual service?
diff --git a/tests/basic.sh b/tests/basic.sh
index 7e5faa7..e7865a4 100644
--- a/tests/basic.sh
+++ b/tests/basic.sh
@@ -83,6 +83,11 @@ $herd start test-2
 
 $herd status test-2 | grep started
 
+if $herd status does-not-exist
+then false; else true; fi
+
+$herd status does-not-exist 2>&1 | grep "does-not-exist.*not.*found"
+
 # Unload one service, make sure the other it still around.
 $herd unload dmd test
 $herd status | grep "Stopped: (test-2)"
diff --git a/tests/status-sexp.sh b/tests/status-sexp.sh
index d77007f..629e9dc 100644
--- a/tests/status-sexp.sh
+++ b/tests/status-sexp.sh
@@ -91,6 +91,19 @@ dmd_service_sexp="
                     (last-respawns ())))))
 "
 
+# Make sure we get an 'error' sexp when querying a nonexistent service.
+"$GUILE" -c "
+(use-modules (shepherd comm) (ice-9 match))
+
+(match (let ((sock (open-connection \"$socket\")))
+         (write-command (dmd-command 'status 'does-not-exist) sock)
+         (read sock))
+  (('error _ ... 'service-not-found 'does-not-exist)
+   #t)
+  (x
+   (pk 'wrong x)
+   (exit 1)))"
+
 # Unload everything and make sure only 'dmd' is left.
 $herd unload dmd all
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]