guix-commits
[Top][All Lists]
Advanced

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

02/11: services: mcron: Add 'schedule' action.


From: Ludovic Courtès
Subject: 02/11: services: mcron: Add 'schedule' action.
Date: Thu, 12 Jul 2018 18:09:48 -0400 (EDT)

civodul pushed a commit to branch master
in repository guix.

commit 147c5aa5d4e3bd21ee4c4cae70dff8da0bcf94b7
Author: Ludovic Courtès <address@hidden>
Date:   Wed Jul 11 23:40:57 2018 +0200

    services: mcron: Add 'schedule' action.
    
    Inspired by
    <https://lists.gnu.org/archive/html/help-guix/2018-07/msg00035.html>.
    
    * gnu/services/mcron.scm (shepherd-schedule-action): New procedure.
    (mcron-shepherd-services): Add 'actions' field.
    * gnu/tests/base.scm (run-mcron-test)["schedule action"]: New test.
    * doc/guix.texi (Scheduled Job Execution): Mention 'herd schedule'.
---
 doc/guix.texi          | 15 ++++++++++
 gnu/services/herd.scm  |  3 ++
 gnu/services/mcron.scm | 76 +++++++++++++++++++++++++++++++++++++++-----------
 gnu/tests/base.scm     |  7 +++++
 4 files changed, 84 insertions(+), 17 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 34012a3..eaec4c4 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -10850,6 +10850,21 @@ gexps to introduce job definitions that are passed to 
mcron
 for more information on mcron job specifications.  Below is the
 reference of the mcron service.
 
+On a running system, you can use the @code{schedule} action of the service to
+visualize the mcron jobs that will be executed next:
+
address@hidden
+# herd schedule mcron
address@hidden example
+
address@hidden
+The example above lists the next five tasks that will be executed, but you can
+also specify the number of tasks to display:
+
address@hidden
+# herd schedule mcron 10
address@hidden example
+
 @deffn {Scheme Procedure} mcron-service @var{jobs} [#:mcron @var{mcron}]
 Return an mcron service running @var{mcron} that schedules @var{jobs}, a
 list of gexps denoting mcron job specifications.
diff --git a/gnu/services/herd.scm b/gnu/services/herd.scm
index d882c232..8c96b70 100644
--- a/gnu/services/herd.scm
+++ b/gnu/services/herd.scm
@@ -45,6 +45,7 @@
             live-service-requirement
             live-service-running
 
+            with-shepherd-action
             current-services
             unload-services
             unload-service
@@ -168,6 +169,8 @@ 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 ...)))
 
diff --git a/gnu/services/mcron.scm b/gnu/services/mcron.scm
index 5bee02a..5757bf8 100644
--- a/gnu/services/mcron.scm
+++ b/gnu/services/mcron.scm
@@ -60,29 +60,71 @@
 (define (job-file job)
   (scheme-file "mcron-job" job))
 
+(define (shepherd-schedule-action mcron files)
+  "Return a Shepherd action that runs MCRON with '--schedule' for the given
+files."
+  (shepherd-action
+   (name 'schedule)
+   (documentation
+    "Display jobs that are going to be scheduled.")
+   (procedure
+    #~(lambda* (_ #:optional (n "5"))
+        ;; XXX: This is a global side effect.
+        (setenv "GUILE_AUTO_COMPILE" "0")
+
+        ;; Run 'mcron' in a pipe so we can explicitly redirect its output to
+        ;; 'current-output-port', which at this stage is bound to the client
+        ;; connection.
+        (let ((pipe (open-pipe* OPEN_READ
+                                #$(file-append mcron "/bin/mcron")
+                                (string-append "--schedule=" n)
+                                address@hidden)))
+          (let loop ()
+            (match (read-line pipe 'concat)
+              ((? eof-object?)
+               (catch 'system-error
+                 (lambda ()
+                   (zero? (close-pipe pipe)))
+                 (lambda args
+                   ;; There's with race between the SIGCHLD handler, which
+                   ;; could call 'waitpid' before 'close-pipe' above does.  If
+                   ;; we get ECHILD, that means we lost the race, but that's
+                   ;; fine.
+                   (or (= ECHILD (system-error-errno args))
+                       (apply throw args)))))
+              (line
+               (display line)
+               (loop)))))))))
+
 (define mcron-shepherd-services
   (match-lambda
     (($ <mcron-configuration> mcron ())           ;nothing to do!
      '())
     (($ <mcron-configuration> mcron jobs)
-     (list (shepherd-service
-            (provision '(mcron))
-            (requirement '(user-processes))
-            (modules `((srfi srfi-1)
-                       (srfi srfi-26)
-                       ,@%default-modules))
-            (start #~(make-forkexec-constructor
-                      (list (string-append #$mcron "/bin/mcron")
-                            #$@(map job-file jobs))
+     (let ((files (map job-file jobs)))
+       (list (shepherd-service
+              (provision '(mcron))
+              (requirement '(user-processes))
+              (modules `((srfi srfi-1)
+                         (srfi srfi-26)
+                         (ice-9 popen)            ;for the 'schedule' action
+                         (ice-9 rdelim)
+                         (ice-9 match)
+                         ,@%default-modules))
+              (start #~(make-forkexec-constructor
+                        (list (string-append #$mcron "/bin/mcron") 
address@hidden)
+
+                        ;; Disable auto-compilation of the job files and set a
+                        ;; sane value for 'PATH'.
+                        #:environment-variables
+                        (cons* "GUILE_AUTO_COMPILE=0"
+                               "PATH=/run/current-system/profile/bin"
+                               (remove (cut string-prefix? "PATH=" <>)
+                                       (environ)))))
+              (stop #~(make-kill-destructor))
 
-                      ;; Disable auto-compilation of the job files and set a
-                      ;; sane value for 'PATH'.
-                      #:environment-variables
-                      (cons* "GUILE_AUTO_COMPILE=0"
-                             "PATH=/run/current-system/profile/bin"
-                             (remove (cut string-prefix? "PATH=" <>)
-                                     (environ)))))
-            (stop #~(make-kill-destructor)))))))
+              (actions
+               (list (shepherd-schedule-action mcron files)))))))))
 
 (define mcron-service-type
   (service-type (name 'mcron)
diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm
index 0efb4a6..f27064a 100644
--- a/gnu/tests/base.scm
+++ b/gnu/tests/base.scm
@@ -632,6 +632,13 @@ non-ASCII names from /tmp.")
             (wait-for-file "/root/witness-touch" marionette
                            #:read '(@ (ice-9 rdelim) read-string)))
 
+          ;; Make sure the 'schedule' action is accepted.
+          (test-equal "schedule action"
+            '(#t)                                 ;one value, #t
+            (marionette-eval '(with-shepherd-action 'mcron ('schedule) result
+                                result)
+                             marionette))
+
           (test-end)
           (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
 



reply via email to

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