* [bug#38429] [PATCH] Add scron service.
@ 2019-11-29 17:53 Robert Vollmert
2019-11-29 18:07 ` Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 1/5] document scron Robert Vollmert
0 siblings, 2 replies; 12+ messages in thread
From: Robert Vollmert @ 2019-11-29 17:53 UTC (permalink / raw)
To: 38429; +Cc: Robert Vollmert
It's a simple replacement for the mcron service.
If you have a mcron job definition like
(define cron-job
#~(job "*/15 * * * *" #$(program-file ...)))
you can convert it into the valid scron job
(define cron-job
(scron-job (schedule "/15 * * * *")
(program-file ...)))
* gnu/services/scron.scm: New file.
* gnu/local.mk: Add it.
---
gnu/local.mk | 1 +
gnu/services/scron.scm | 39 ++++++++++++++++++++++++---------------
2 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/gnu/local.mk b/gnu/local.mk
index 56ff1d0f7b..ca8b6ecc1b 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -552,6 +552,7 @@ GNU_SYSTEM_MODULES = \
%D%/services/nix.scm \
%D%/services/nfs.scm \
%D%/services/pam-mount.scm \
+ %D%/services/scron.scm \
%D%/services/security-token.scm \
%D%/services/shepherd.scm \
%D%/services/sound.scm \
diff --git a/gnu/services/scron.scm b/gnu/services/scron.scm
index dee0bad81e..0ea7cc9698 100644
--- a/gnu/services/scron.scm
+++ b/gnu/services/scron.scm
@@ -30,6 +30,11 @@
scron-configuration-scron
scron-configuration-jobs
+ scron-job
+ scron-job?
+ scron-job-schedule
+ scron-job-command
+
scron-service-type
scron-service))
@@ -40,7 +45,8 @@
;;
;; (service scron-service-type
;; (scron-configuration
-;; (jobs (list (job "*/15 * * * *" "echo hello!")))))
+;; (jobs (list (scron-job (schedule "*/15 * * * *")
+;; (command "echo hello!"))))))
;;;
;;; Code:
@@ -55,34 +61,37 @@
(define-record-type* <scron-job> scron-job
make-scron-job
scron-job?
- (schedule scron-job-schedule (default ""))
- (command scron-job-command (default "")))
+ (schedule scron-job-schedule (default "* * * * *"))
+ (command scron-job-command (default '())))
(define (crontab jobs)
- (text-file "crontab"
- (string-concatenate
+ (apply mixed-text-file "crontab"
+ (concatenate
(map
(match-lambda
(($ <scron-job> schedule command)
- (string-append schedule " " command "\n")))
+ (list schedule " " command "\n")))
jobs))))
-(define scron-shepherd-service
+(define scron-shepherd-services
(match-lambda
(($ <scron-configuration> scron jobs)
- (shepherd-service
- (provision '(scron))
- (requirement '(user-processes))
- (start #~(make-forkexec-constructor
- (list (string-append #$scron "/bin/crond") "-n" "-f" #$(crontab jobs))
- #:log-file "/var/log/scron.log"))
- (stop #~(make-kill-destructor))))))
+ (list
+ (shepherd-service
+ (provision '(scron))
+ (requirement '(user-processes))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$scron "/bin/crond")
+ "-n" ; don't fork
+ "-f" #$(crontab jobs))
+ #:log-file "/var/log/scron.log"))
+ (stop #~(make-kill-destructor)))))))
(define scron-service-type
(service-type (name 'scron)
(extensions
(list (service-extension shepherd-root-service-type
- (list scron-shepherd-service))))
+ scron-shepherd-services)))
(compose concatenate)
(extend (lambda (config jobs)
(scron-configuration
--
2.24.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH] Add scron service.
2019-11-29 17:53 [bug#38429] [PATCH] Add scron service Robert Vollmert
@ 2019-11-29 18:07 ` Robert Vollmert
2019-12-02 9:01 ` Ludovic Courtès
2019-12-03 12:46 ` [bug#38429] [PATCH 1/5] document scron Robert Vollmert
1 sibling, 1 reply; 12+ messages in thread
From: Robert Vollmert @ 2019-11-29 18:07 UTC (permalink / raw)
To: 38429; +Cc: Robert Vollmert
It's a simple replacement for the mcron service.
If you have a mcron job definition like
(define cron-job
#~(job "*/15 * * * *" #$(program-file ...)))
you can convert it into the valid scron job
(define cron-job
(scron-job (schedule "/15 * * * *")
(program-file ...)))
* gnu/services/scron.scm: New file.
* gnu/local.mk: Add it.
---
Sent an incomplete patch before, this is the full version.
gnu/local.mk | 1 +
gnu/services/scron.scm | 101 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 102 insertions(+)
create mode 100644 gnu/services/scron.scm
diff --git a/gnu/local.mk b/gnu/local.mk
index 56ff1d0f7b..ca8b6ecc1b 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -552,6 +552,7 @@ GNU_SYSTEM_MODULES = \
%D%/services/nix.scm \
%D%/services/nfs.scm \
%D%/services/pam-mount.scm \
+ %D%/services/scron.scm \
%D%/services/security-token.scm \
%D%/services/shepherd.scm \
%D%/services/sound.scm \
diff --git a/gnu/services/scron.scm b/gnu/services/scron.scm
new file mode 100644
index 0000000000..0ea7cc9698
--- /dev/null
+++ b/gnu/services/scron.scm
@@ -0,0 +1,101 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2019 Robert Vollmert <rob@vllmrt.net>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu services scron)
+ #:use-module (gnu services)
+ #:use-module (gnu services shepherd)
+ #:autoload (gnu packages suckless) (scron)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (guix store)
+ #:use-module (ice-9 match)
+ #:use-module (srfi srfi-1)
+ #:export (scron-configuration
+ scron-configuration?
+ scron-configuration-scron
+ scron-configuration-jobs
+
+ scron-job
+ scron-job?
+ scron-job-schedule
+ scron-job-command
+
+ scron-service-type
+ scron-service))
+
+;;; Commentary:
+;;;
+;;; This module implements a service to run instances of scron, a
+;;; periodic job execution daemon. Example of a service:
+;;
+;; (service scron-service-type
+;; (scron-configuration
+;; (jobs (list (scron-job (schedule "*/15 * * * *")
+;; (command "echo hello!"))))))
+;;;
+;;; Code:
+
+(define-record-type* <scron-configuration> scron-configuration
+ make-scron-configuration
+ scron-configuration?
+ (scron scron-configuration-scron ;package
+ (default scron))
+ (jobs scron-configuration-jobs ;list of <scron-job>
+ (default '())))
+
+(define-record-type* <scron-job> scron-job
+ make-scron-job
+ scron-job?
+ (schedule scron-job-schedule (default "* * * * *"))
+ (command scron-job-command (default '())))
+
+(define (crontab jobs)
+ (apply mixed-text-file "crontab"
+ (concatenate
+ (map
+ (match-lambda
+ (($ <scron-job> schedule command)
+ (list schedule " " command "\n")))
+ jobs))))
+
+(define scron-shepherd-services
+ (match-lambda
+ (($ <scron-configuration> scron jobs)
+ (list
+ (shepherd-service
+ (provision '(scron))
+ (requirement '(user-processes))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$scron "/bin/crond")
+ "-n" ; don't fork
+ "-f" #$(crontab jobs))
+ #:log-file "/var/log/scron.log"))
+ (stop #~(make-kill-destructor)))))))
+
+(define scron-service-type
+ (service-type (name 'scron)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ scron-shepherd-services)))
+ (compose concatenate)
+ (extend (lambda (config jobs)
+ (scron-configuration
+ (inherit config)
+ (jobs (append (scron-configuration-jobs config)
+ jobs)))))
+ (default-value (scron-configuration))))
--
2.24.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH] Add scron service.
2019-11-29 18:07 ` Robert Vollmert
@ 2019-12-02 9:01 ` Ludovic Courtès
0 siblings, 0 replies; 12+ messages in thread
From: Ludovic Courtès @ 2019-12-02 9:01 UTC (permalink / raw)
To: Robert Vollmert; +Cc: 38429
Hello!
Robert Vollmert <rob@vllmrt.net> skribis:
> It's a simple replacement for the mcron service.
>
> If you have a mcron job definition like
>
> (define cron-job
> #~(job "*/15 * * * *" #$(program-file ...)))
>
> you can convert it into the valid scron job
>
> (define cron-job
> (scron-job (schedule "/15 * * * *")
> (program-file ...)))
Nice.
> +(define scron-service-type
> + (service-type (name 'scron)
> + (extensions
> + (list (service-extension shepherd-root-service-type
> + scron-shepherd-services)))
> + (compose concatenate)
> + (extend (lambda (config jobs)
> + (scron-configuration
> + (inherit config)
> + (jobs (append (scron-configuration-jobs config)
> + jobs)))))
> + (default-value (scron-configuration))))
Could you add a ‘description’ field with a short blurb (you can use
Texinfo markup)?
Also, could you add it to guix.texi, presumably under “Scheduled Job
Execution”?
Last, it would be great if you could add a test, similar to the mcron
test that’s in (gnu tests base).
Thanks in advance!
Ludo’.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH 1/5] document scron
2019-11-29 17:53 [bug#38429] [PATCH] Add scron service Robert Vollmert
2019-11-29 18:07 ` Robert Vollmert
@ 2019-12-03 12:46 ` Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 2/5] scron-service: remove job defaults Robert Vollmert
` (4 more replies)
1 sibling, 5 replies; 12+ messages in thread
From: Robert Vollmert @ 2019-12-03 12:46 UTC (permalink / raw)
To: 38429; +Cc: Robert Vollmert
* doc/guix.texi: Add documentation for scron-service.
---
The first in a series of supplementary patches on top of the base scron
service patch, to be squashed into that commit.
doc/guix.texi | 100 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 99 insertions(+), 1 deletion(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index e0b831c7e8..1aafa01166 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -283,7 +283,7 @@ System Configuration
Services
* Base Services:: Essential system services.
-* Scheduled Job Execution:: The mcron service.
+* Scheduled Job Execution:: Cron services.
* Log Rotation:: The rottlog service.
* Networking Services:: Network setup, SSH daemon, etc.
* X Window:: Graphical display.
@@ -12890,6 +12890,104 @@ specifications,, mcron, GNU@tie{}mcron}).
@end deftp
+@cindex scron
+@cindex scheduling jobs
+The @code{(gnu services scron)} module provides an interface to
+scron, a simple daemon to run jobs at scheduled times. scron is
+similar to the traditional Unix @command{cron} daemon;
+the main difference is that it is much simpler.
+
+Jobs are executed as root via the shell with working direction @code{/}.
+Use @code{su(1)} or corresponding Guile functions
+(@pxref{Processes,,, guile, GNU Guile Reference Manual}).
+
+The example below defines an operating system that runs the
+@command{updatedb} (@pxref{Invoking updatedb,,, find, Finding Files})
+and the @command{guix gc} commands (@pxref{Invoking guix gc}) daily, as
+well as the @command{mkid} command on behalf of an unprivileged user
+(@pxref{mkid invocation,,, idutils, ID Database Utilities}).
+
+@lisp
+(use-modules (guix) (gnu) (gnu services scron))
+(use-package-modules base idutils)
+
+(define updatedb-job
+ ;; Run 'updatedb' at 3AM every day. Here we write the
+ ;; job's action as a Scheme procedure.
+ (let*
+ ((exp #~(begin
+ (execl (string-append #$findutils "/bin/updatedb")
+ "updatedb"
+ "--prunepaths=/tmp /var/tmp /gnu/store")))
+ (script (program-file "updatedb-job" exp))
+ (scron-job
+ (schedule "0 3 * * *")
+ (command script))))
+
+(define garbage-collector-job
+ ;; Collect garbage 5 minutes after midnight every day.
+ ;; The job's action is a shell command.
+ (scron-job
+ (schedule "5 0 * * *")
+ (command "guix gc -F 1G")))
+
+(define idutils-job
+ ;; Update the index database as user "charlie" at 12:15PM
+ ;; and 19:15PM. This runs from the user's home directory.
+ (let*
+ ((cmd #~(string-append #$idutils "/bin/mkid src"))
+ (cmd-su #~(string-append "su -c '" #$cmd "' charlie")))
+ (scron-job
+ (schedule "15 12,19 * * *")
+ (command cmd-su))))
+
+(operating-system
+ ;; @dots{}
+ (services (cons (service scron-service-type
+ (scron-configuration
+ (jobs (list garbage-collector-job
+ updatedb-job
+ idutils-job))))
+ %base-services)))
+@end lisp
+
+@defvr {Scheme Variable} scron-service-type
+
+This is the type of the @code{scron} service, whose value is an
+@code{scron-configuration} object.
+
+This service type can be the target of a service extension that provides
+it additional job specifications (@pxref{Service Composition}). In
+other words, it is possible to define services that provide additional
+mcron jobs to run.
+@end defvr
+
+@deftp {Data Type} scron-configuration
+Data type representing the configuration of scron.
+
+@table @asis
+@item @code{scron} (default: @var{scron})
+The scron package to use.
+
+@item @code{jobs}
+This is a list of scron jobs.
+@end table
+@end deftp
+
+@deftp {Data Type} scron-job
+Data type representing an scron job.
+
+@table @asis
+@item @code{schedule}
+The job schedule, in Vixie cron syntax. See the @code{scron(1)}
+man page for more information.
+
+@item @code{command}
+The shell command to run, as a value that lowers to a string.
+@end table
+@end deftp
+
+
@node Log Rotation
@subsection Log Rotation
--
2.24.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH 2/5] scron-service: remove job defaults
2019-12-03 12:46 ` [bug#38429] [PATCH 1/5] document scron Robert Vollmert
@ 2019-12-03 12:46 ` Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 3/5] scron: Add description Robert Vollmert
` (3 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: Robert Vollmert @ 2019-12-03 12:46 UTC (permalink / raw)
To: 38429; +Cc: Robert Vollmert
---
gnu/services/scron.scm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gnu/services/scron.scm b/gnu/services/scron.scm
index 0ea7cc9698..990ae8f0e2 100644
--- a/gnu/services/scron.scm
+++ b/gnu/services/scron.scm
@@ -61,8 +61,8 @@
(define-record-type* <scron-job> scron-job
make-scron-job
scron-job?
- (schedule scron-job-schedule (default "* * * * *"))
- (command scron-job-command (default '())))
+ (schedule scron-job-schedule)
+ (command scron-job-command))
(define (crontab jobs)
(apply mixed-text-file "crontab"
--
2.24.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH 3/5] scron: Add description
2019-12-03 12:46 ` [bug#38429] [PATCH 1/5] document scron Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 2/5] scron-service: remove job defaults Robert Vollmert
@ 2019-12-03 12:46 ` Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 4/5] scron: add system test Robert Vollmert
` (2 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: Robert Vollmert @ 2019-12-03 12:46 UTC (permalink / raw)
To: 38429; +Cc: Robert Vollmert
---
gnu/services/scron.scm | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gnu/services/scron.scm b/gnu/services/scron.scm
index 990ae8f0e2..b9b2983e96 100644
--- a/gnu/services/scron.scm
+++ b/gnu/services/scron.scm
@@ -89,6 +89,8 @@
(define scron-service-type
(service-type (name 'scron)
+ (description
+ "Run the scron job scheduling daemon.")
(extensions
(list (service-extension shepherd-root-service-type
scron-shepherd-services)))
--
2.24.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH 4/5] scron: add system test
2019-12-03 12:46 ` [bug#38429] [PATCH 1/5] document scron Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 2/5] scron-service: remove job defaults Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 3/5] scron: Add description Robert Vollmert
@ 2019-12-03 12:46 ` Robert Vollmert
2019-12-03 12:50 ` Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 5/5] gnu/services: Add description to mcron-service-type Robert Vollmert
2019-12-07 23:32 ` [bug#38429] [PATCH 1/5] document scron Ludovic Courtès
4 siblings, 1 reply; 12+ messages in thread
From: Robert Vollmert @ 2019-12-03 12:46 UTC (permalink / raw)
To: 38429; +Cc: Robert Vollmert
---
gnu/tests/base.scm | 86 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm
index a891711844..b80e77be66 100644
--- a/gnu/tests/base.scm
+++ b/gnu/tests/base.scm
@@ -28,6 +28,7 @@
#:use-module (gnu services dbus)
#:use-module (gnu services avahi)
#:use-module (gnu services mcron)
+ #:use-module (gnu services scron)
#:use-module (gnu services shepherd)
#:use-module (gnu services networking)
#:use-module (gnu packages base)
@@ -48,6 +49,7 @@
%test-halt
%test-cleanup
%test-mcron
+ %test-scron
%test-nss-mdns))
(define %simple-os
@@ -720,6 +722,90 @@ non-ASCII names from /tmp.")
(description "Make sure the mcron service works as advertised.")
(value (run-mcron-test name))))
+\f
+;;;
+;;; Scron.
+;;;
+
+(define %scron-os
+ ;; System with an scron service, with one scron job for "root" and one scron
+ ;; job for an unprivileged user.
+ (let ((job1
+ (scron-job
+ (schedule "* * * * *")
+ (command "(id -u; id -g) > witness")))
+ (job2
+ (scron-job
+ (schedule "* * * * *")
+ (command "su -c '(id -u; id -g) > ~/witness' alice")))
+ (job3
+ (scron-job
+ (schedule "* * * * *")
+ (command "touch witness-touch"))))
+ (simple-operating-system
+ (service scron-service-type
+ (scron-configuration (jobs (list job1 job2 job3)))))))
+
+(define (run-scron-test name)
+ (define os
+ (marionette-operating-system
+ %scron-os
+ #:imported-modules '((gnu services herd)
+ (guix combinators))))
+
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (gnu build marionette)
+ (srfi srfi-64)
+ (ice-9 match))
+
+ (define marionette
+ (make-marionette (list #$(virtual-machine os))))
+
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "scron")
+
+ (test-assert "service running"
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'scron))
+ marionette))
+
+ ;; Make sure root's scron job runs, has its cwd set to "/", and
+ ;; runs with the right UID/GID.
+ (test-equal "root's job"
+ '(0 0)
+ (wait-for-file "/witness" marionette))
+
+ ;; Likewise for Alice's job. We cannot know what its GID is since
+ ;; it's chosen by 'groupadd', but it's strictly positive.
+ (test-assert "alice's job"
+ (match (wait-for-file "/home/alice/witness" marionette)
+ ((1000 gid)
+ (>= gid 100))))
+
+ ;; Last, the job that uses a command; allows us to test whether
+ ;; $PATH is sane.
+ (test-equal "root's job with command"
+ ""
+ (wait-for-file "/witness-touch" marionette
+ #:read '(@ (ice-9 rdelim) read-string)))
+
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation name test))
+
+(define %test-scron
+ (system-test
+ (name "scron")
+ (description "Make sure the scron service works as advertised.")
+ (value (run-scron-test name))))
+
\f
;;;
;;; Avahi and NSS-mDNS.
--
2.24.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH 5/5] gnu/services: Add description to mcron-service-type.
2019-12-03 12:46 ` [bug#38429] [PATCH 1/5] document scron Robert Vollmert
` (2 preceding siblings ...)
2019-12-03 12:46 ` [bug#38429] [PATCH 4/5] scron: add system test Robert Vollmert
@ 2019-12-03 12:46 ` Robert Vollmert
2019-12-07 23:32 ` [bug#38429] [PATCH 1/5] document scron Ludovic Courtès
4 siblings, 0 replies; 12+ messages in thread
From: Robert Vollmert @ 2019-12-03 12:46 UTC (permalink / raw)
To: 38429; +Cc: Robert Vollmert
* gnu/services/mcron.go (mcron-service-type): Add description.
---
This one is independent from the scron patches.
gnu/services/mcron.scm | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gnu/services/mcron.scm b/gnu/services/mcron.scm
index 7238665404..1327516b49 100644
--- a/gnu/services/mcron.scm
+++ b/gnu/services/mcron.scm
@@ -130,6 +130,8 @@ files."
(define mcron-service-type
(service-type (name 'mcron)
+ (description
+ "Run the mcron job scheduling daemon.")
(extensions
(list (service-extension shepherd-root-service-type
mcron-shepherd-services)
--
2.24.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH 4/5] scron: add system test
2019-12-03 12:46 ` [bug#38429] [PATCH 4/5] scron: add system test Robert Vollmert
@ 2019-12-03 12:50 ` Robert Vollmert
0 siblings, 0 replies; 12+ messages in thread
From: Robert Vollmert @ 2019-12-03 12:50 UTC (permalink / raw)
To: 38429
I’ve checked that the tests compile, and run the test cron jobs
by hand to ensure they behave as tested, but I wasn’t able to run
the system tests themselves.
> On 3. Dec 2019, at 13:46, Robert Vollmert <rob@vllmrt.net> wrote:
>
> ---
> gnu/tests/base.scm | 86 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 86 insertions(+)
>
> diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm
> index a891711844..b80e77be66 100644
> --- a/gnu/tests/base.scm
> +++ b/gnu/tests/base.scm
> @@ -28,6 +28,7 @@
> #:use-module (gnu services dbus)
> #:use-module (gnu services avahi)
> #:use-module (gnu services mcron)
> + #:use-module (gnu services scron)
> #:use-module (gnu services shepherd)
> #:use-module (gnu services networking)
> #:use-module (gnu packages base)
> @@ -48,6 +49,7 @@
> %test-halt
> %test-cleanup
> %test-mcron
> + %test-scron
> %test-nss-mdns))
>
> (define %simple-os
> @@ -720,6 +722,90 @@ non-ASCII names from /tmp.")
> (description "Make sure the mcron service works as advertised.")
> (value (run-mcron-test name))))
>
> +\f
> +;;;
> +;;; Scron.
> +;;;
> +
> +(define %scron-os
> + ;; System with an scron service, with one scron job for "root" and one scron
> + ;; job for an unprivileged user.
> + (let ((job1
> + (scron-job
> + (schedule "* * * * *")
> + (command "(id -u; id -g) > witness")))
> + (job2
> + (scron-job
> + (schedule "* * * * *")
> + (command "su -c '(id -u; id -g) > ~/witness' alice")))
> + (job3
> + (scron-job
> + (schedule "* * * * *")
> + (command "touch witness-touch"))))
> + (simple-operating-system
> + (service scron-service-type
> + (scron-configuration (jobs (list job1 job2 job3)))))))
> +
> +(define (run-scron-test name)
> + (define os
> + (marionette-operating-system
> + %scron-os
> + #:imported-modules '((gnu services herd)
> + (guix combinators))))
> +
> + (define test
> + (with-imported-modules '((gnu build marionette))
> + #~(begin
> + (use-modules (gnu build marionette)
> + (srfi srfi-64)
> + (ice-9 match))
> +
> + (define marionette
> + (make-marionette (list #$(virtual-machine os))))
> +
> + (mkdir #$output)
> + (chdir #$output)
> +
> + (test-begin "scron")
> +
> + (test-assert "service running"
> + (marionette-eval
> + '(begin
> + (use-modules (gnu services herd))
> + (start-service 'scron))
> + marionette))
> +
> + ;; Make sure root's scron job runs, has its cwd set to "/", and
> + ;; runs with the right UID/GID.
> + (test-equal "root's job"
> + '(0 0)
> + (wait-for-file "/witness" marionette))
> +
> + ;; Likewise for Alice's job. We cannot know what its GID is since
> + ;; it's chosen by 'groupadd', but it's strictly positive.
> + (test-assert "alice's job"
> + (match (wait-for-file "/home/alice/witness" marionette)
> + ((1000 gid)
> + (>= gid 100))))
> +
> + ;; Last, the job that uses a command; allows us to test whether
> + ;; $PATH is sane.
> + (test-equal "root's job with command"
> + ""
> + (wait-for-file "/witness-touch" marionette
> + #:read '(@ (ice-9 rdelim) read-string)))
> +
> + (test-end)
> + (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
> +
> + (gexp->derivation name test))
> +
> +(define %test-scron
> + (system-test
> + (name "scron")
> + (description "Make sure the scron service works as advertised.")
> + (value (run-scron-test name))))
> +
>
> ;;;
> ;;; Avahi and NSS-mDNS.
> --
> 2.24.0
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH 1/5] document scron
2019-12-03 12:46 ` [bug#38429] [PATCH 1/5] document scron Robert Vollmert
` (3 preceding siblings ...)
2019-12-03 12:46 ` [bug#38429] [PATCH 5/5] gnu/services: Add description to mcron-service-type Robert Vollmert
@ 2019-12-07 23:32 ` Ludovic Courtès
2019-12-07 23:43 ` Robert Vollmert
4 siblings, 1 reply; 12+ messages in thread
From: Ludovic Courtès @ 2019-12-07 23:32 UTC (permalink / raw)
To: Robert Vollmert; +Cc: 38429
[-- Attachment #1: Type: text/plain, Size: 661 bytes --]
Hi Robert,
Robert Vollmert <rob@vllmrt.net> skribis:
> The first in a series of supplementary patches on top of the base scron
> service patch, to be squashed into that commit.
Attached is my attempt at squashing it all (except the mcron description
bit) and removing redundancy in the manual (it’s not necessary to copy
the whole mcron example and s/mcron/scron/ IMO).
However, the test fails, and I realize it’s also mostly copy/pasted from
the mcron test. I think the two tests should be factorized, just like
we factorized the SSH daemon tests in (gnu tests ssh).
Could you pick it up from there?
Thanks in advance,
Ludo’.
[-- Attachment #2: 0001-services-Add-scron.patch --]
[-- Type: text/x-patch, Size: 12129 bytes --]
From 7afbcbcd0e00d2db26f139363be81ca26a61095f Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 29 Nov 2019 19:07:22 +0100
Subject: [PATCH] services: Add scron.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It's a simple replacement for the mcron service.
If you have a mcron job definition like
(define cron-job
#~(job "*/15 * * * *" #$(program-file ...)))
you can convert it into the valid scron job
(define cron-job
(scron-job (schedule "/15 * * * *")
(program-file ...)))
* gnu/services/scron.scm: New file.
* gnu/local.mk: Add it.
* gnu/tests/base.scm (%scron-os): New variable.
(run-scron-test): New procedure.
(%test-scron): New variable.
* doc/guix.texi: Add documentation for scron-service.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
---
doc/guix.texi | 77 +++++++++++++++++++++++++++++-
gnu/local.mk | 1 +
gnu/services/scron.scm | 103 +++++++++++++++++++++++++++++++++++++++++
gnu/tests/base.scm | 86 ++++++++++++++++++++++++++++++++++
4 files changed, 266 insertions(+), 1 deletion(-)
create mode 100644 gnu/services/scron.scm
diff --git a/doc/guix.texi b/doc/guix.texi
index 446534c576..0fa8a9bd01 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -282,7 +282,7 @@ System Configuration
Services
* Base Services:: Essential system services.
-* Scheduled Job Execution:: The mcron service.
+* Scheduled Job Execution:: Cron services.
* Log Rotation:: The rottlog service.
* Networking Services:: Network setup, SSH daemon, etc.
* X Window:: Graphical display.
@@ -12899,6 +12899,81 @@ specifications,, mcron, GNU@tie{}mcron}).
@end deftp
+@cindex scron
+@cindex scheduling jobs
+The @code{(gnu services scron)} module provides an interface to
+scron, a simple daemon to run jobs at scheduled times. scron is
+similar to the traditional Unix @command{cron} daemon;
+the main difference is that it is much simpler.
+
+Jobs are executed as root @i{via} the shell with working direction
+@code{/}. Use @code{su} or corresponding Guile functions
+(@pxref{Processes,,, guile, GNU Guile Reference Manual}).
+
+The example below defines an operating system that runs the
+@command{updatedb} command (@pxref{Invoking updatedb,,, find, Finding
+Files}) daily:
+
+@lisp
+(use-modules (guix) (gnu) (gnu services scron))
+(use-package-modules base)
+
+(define updatedb-job
+ ;; Run 'updatedb' at 3AM every day.
+ (let* ((exp #~(begin
+ (execl (string-append #$findutils "/bin/updatedb")
+ "updatedb"
+ "--prunepaths=/tmp /var/tmp /gnu/store")))
+ (script (program-file "updatedb-job" exp)))
+ (scron-job
+ (schedule "0 3 * * *")
+ (command script))))
+
+(operating-system
+ ;; @dots{}
+ (services (cons (service scron-service-type
+ (scron-configuration
+ (jobs (list updatedb-job))))
+ %base-services)))
+@end lisp
+
+@defvr {Scheme Variable} scron-service-type
+
+This is the type of the @code{scron} service, whose value is an
+@code{scron-configuration} object.
+
+This service type can be the target of a service extension that provides
+it additional job specifications (@pxref{Service Composition}). In
+other words, it is possible to define services that provide additional
+mcron jobs to run.
+@end defvr
+
+@deftp {Data Type} scron-configuration
+Data type representing the configuration of scron.
+
+@table @asis
+@item @code{scron} (default: @var{scron})
+The scron package to use.
+
+@item @code{jobs}
+This is a list of scron jobs.
+@end table
+@end deftp
+
+@deftp {Data Type} scron-job
+Data type representing an scron job.
+
+@table @asis
+@item @code{schedule}
+The job schedule, in Vixie cron syntax. See the @code{scron(1)}
+man page for more information.
+
+@item @code{command}
+The shell command to run, as a value that lowers to a string.
+@end table
+@end deftp
+
+
@node Log Rotation
@subsection Log Rotation
diff --git a/gnu/local.mk b/gnu/local.mk
index 80ef0f04d0..4602e464f7 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -554,6 +554,7 @@ GNU_SYSTEM_MODULES = \
%D%/services/nix.scm \
%D%/services/nfs.scm \
%D%/services/pam-mount.scm \
+ %D%/services/scron.scm \
%D%/services/security-token.scm \
%D%/services/shepherd.scm \
%D%/services/sound.scm \
diff --git a/gnu/services/scron.scm b/gnu/services/scron.scm
new file mode 100644
index 0000000000..b9b2983e96
--- /dev/null
+++ b/gnu/services/scron.scm
@@ -0,0 +1,103 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2019 Robert Vollmert <rob@vllmrt.net>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu services scron)
+ #:use-module (gnu services)
+ #:use-module (gnu services shepherd)
+ #:autoload (gnu packages suckless) (scron)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (guix store)
+ #:use-module (ice-9 match)
+ #:use-module (srfi srfi-1)
+ #:export (scron-configuration
+ scron-configuration?
+ scron-configuration-scron
+ scron-configuration-jobs
+
+ scron-job
+ scron-job?
+ scron-job-schedule
+ scron-job-command
+
+ scron-service-type
+ scron-service))
+
+;;; Commentary:
+;;;
+;;; This module implements a service to run instances of scron, a
+;;; periodic job execution daemon. Example of a service:
+;;
+;; (service scron-service-type
+;; (scron-configuration
+;; (jobs (list (scron-job (schedule "*/15 * * * *")
+;; (command "echo hello!"))))))
+;;;
+;;; Code:
+
+(define-record-type* <scron-configuration> scron-configuration
+ make-scron-configuration
+ scron-configuration?
+ (scron scron-configuration-scron ;package
+ (default scron))
+ (jobs scron-configuration-jobs ;list of <scron-job>
+ (default '())))
+
+(define-record-type* <scron-job> scron-job
+ make-scron-job
+ scron-job?
+ (schedule scron-job-schedule)
+ (command scron-job-command))
+
+(define (crontab jobs)
+ (apply mixed-text-file "crontab"
+ (concatenate
+ (map
+ (match-lambda
+ (($ <scron-job> schedule command)
+ (list schedule " " command "\n")))
+ jobs))))
+
+(define scron-shepherd-services
+ (match-lambda
+ (($ <scron-configuration> scron jobs)
+ (list
+ (shepherd-service
+ (provision '(scron))
+ (requirement '(user-processes))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$scron "/bin/crond")
+ "-n" ; don't fork
+ "-f" #$(crontab jobs))
+ #:log-file "/var/log/scron.log"))
+ (stop #~(make-kill-destructor)))))))
+
+(define scron-service-type
+ (service-type (name 'scron)
+ (description
+ "Run the scron job scheduling daemon.")
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ scron-shepherd-services)))
+ (compose concatenate)
+ (extend (lambda (config jobs)
+ (scron-configuration
+ (inherit config)
+ (jobs (append (scron-configuration-jobs config)
+ jobs)))))
+ (default-value (scron-configuration))))
diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm
index a891711844..b80e77be66 100644
--- a/gnu/tests/base.scm
+++ b/gnu/tests/base.scm
@@ -28,6 +28,7 @@
#:use-module (gnu services dbus)
#:use-module (gnu services avahi)
#:use-module (gnu services mcron)
+ #:use-module (gnu services scron)
#:use-module (gnu services shepherd)
#:use-module (gnu services networking)
#:use-module (gnu packages base)
@@ -48,6 +49,7 @@
%test-halt
%test-cleanup
%test-mcron
+ %test-scron
%test-nss-mdns))
(define %simple-os
@@ -720,6 +722,90 @@ non-ASCII names from /tmp.")
(description "Make sure the mcron service works as advertised.")
(value (run-mcron-test name))))
+\f
+;;;
+;;; Scron.
+;;;
+
+(define %scron-os
+ ;; System with an scron service, with one scron job for "root" and one scron
+ ;; job for an unprivileged user.
+ (let ((job1
+ (scron-job
+ (schedule "* * * * *")
+ (command "(id -u; id -g) > witness")))
+ (job2
+ (scron-job
+ (schedule "* * * * *")
+ (command "su -c '(id -u; id -g) > ~/witness' alice")))
+ (job3
+ (scron-job
+ (schedule "* * * * *")
+ (command "touch witness-touch"))))
+ (simple-operating-system
+ (service scron-service-type
+ (scron-configuration (jobs (list job1 job2 job3)))))))
+
+(define (run-scron-test name)
+ (define os
+ (marionette-operating-system
+ %scron-os
+ #:imported-modules '((gnu services herd)
+ (guix combinators))))
+
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (gnu build marionette)
+ (srfi srfi-64)
+ (ice-9 match))
+
+ (define marionette
+ (make-marionette (list #$(virtual-machine os))))
+
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "scron")
+
+ (test-assert "service running"
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'scron))
+ marionette))
+
+ ;; Make sure root's scron job runs, has its cwd set to "/", and
+ ;; runs with the right UID/GID.
+ (test-equal "root's job"
+ '(0 0)
+ (wait-for-file "/witness" marionette))
+
+ ;; Likewise for Alice's job. We cannot know what its GID is since
+ ;; it's chosen by 'groupadd', but it's strictly positive.
+ (test-assert "alice's job"
+ (match (wait-for-file "/home/alice/witness" marionette)
+ ((1000 gid)
+ (>= gid 100))))
+
+ ;; Last, the job that uses a command; allows us to test whether
+ ;; $PATH is sane.
+ (test-equal "root's job with command"
+ ""
+ (wait-for-file "/witness-touch" marionette
+ #:read '(@ (ice-9 rdelim) read-string)))
+
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation name test))
+
+(define %test-scron
+ (system-test
+ (name "scron")
+ (description "Make sure the scron service works as advertised.")
+ (value (run-scron-test name))))
+
\f
;;;
;;; Avahi and NSS-mDNS.
--
2.24.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#38429] [PATCH 1/5] document scron
2019-12-07 23:32 ` [bug#38429] [PATCH 1/5] document scron Ludovic Courtès
@ 2019-12-07 23:43 ` Robert Vollmert
2019-12-07 23:46 ` bug#38429: " Ludovic Courtès
0 siblings, 1 reply; 12+ messages in thread
From: Robert Vollmert @ 2019-12-07 23:43 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: 38429
I’m sorry, for the moment this about as much effort as I’m willing
to put into this. Feel free to close.
Cheers
Robert
> On 8. Dec 2019, at 00:32, Ludovic Courtès <ludo@gnu.org> wrote:
>
> Hi Robert,
>
> Robert Vollmert <rob@vllmrt.net> skribis:
>
>> The first in a series of supplementary patches on top of the base scron
>> service patch, to be squashed into that commit.
>
> Attached is my attempt at squashing it all (except the mcron description
> bit) and removing redundancy in the manual (it’s not necessary to copy
> the whole mcron example and s/mcron/scron/ IMO).
>
> However, the test fails, and I realize it’s also mostly copy/pasted from
> the mcron test. I think the two tests should be factorized, just like
> we factorized the SSH daemon tests in (gnu tests ssh).
>
> Could you pick it up from there?
>
> Thanks in advance,
> Ludo’.
>
> <0001-services-Add-scron.patch>
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#38429: [PATCH 1/5] document scron
2019-12-07 23:43 ` Robert Vollmert
@ 2019-12-07 23:46 ` Ludovic Courtès
0 siblings, 0 replies; 12+ messages in thread
From: Ludovic Courtès @ 2019-12-07 23:46 UTC (permalink / raw)
To: Robert Vollmert; +Cc: 38429-done
Hi,
Robert Vollmert <rob@vllmrt.net> skribis:
> I’m sorry, for the moment this about as much effort as I’m willing
> to put into this. Feel free to close.
Done!
It’s a sad outcome though, given that the two of us had already spent
quite some time on it. Oh well, maybe someone will pick it up later.
Ludo’.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2019-12-08 3:24 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-11-29 17:53 [bug#38429] [PATCH] Add scron service Robert Vollmert
2019-11-29 18:07 ` Robert Vollmert
2019-12-02 9:01 ` Ludovic Courtès
2019-12-03 12:46 ` [bug#38429] [PATCH 1/5] document scron Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 2/5] scron-service: remove job defaults Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 3/5] scron: Add description Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 4/5] scron: add system test Robert Vollmert
2019-12-03 12:50 ` Robert Vollmert
2019-12-03 12:46 ` [bug#38429] [PATCH 5/5] gnu/services: Add description to mcron-service-type Robert Vollmert
2019-12-07 23:32 ` [bug#38429] [PATCH 1/5] document scron Ludovic Courtès
2019-12-07 23:43 ` Robert Vollmert
2019-12-07 23:46 ` bug#38429: " Ludovic Courtès
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).