Next: Ротация логов, Previous: Базовые службы, Up: Сервисы [Contents][Index]
It is often useful to have system tasks run periodically. This can be achieved by defining Shepherd timers or by using the historical and somewhat less flexible mcron service.
The Shepherd supports running jobs periodically by defining timers, a
special kind of service. A Shepherd timer can be defined like another
Shepherd service, but with specific start
and stop
methods
(see Сервисы Shepherd):
;; Defining a timer, verbosely. (shepherd-service (provision '(updatedb)) (requirement '(user-processes)) (modules '((shepherd service timer))) (start #~(make-timer-constructor ;; Everyday at 3AM (using Vixie cron syntax). (cron-string->calendar-event "0 3 * * *") (command '(#$(file-append findutils "/bin/updatedb"))) #:wait-for-termination? #t)) (stop #~(make-timer-destructor)) (documentation "Periodically run 'updatedb'.") (actions (list shepherd-trigger-action)))
This is quite some boilerplate so you can instead use this equivalent shorthand notation:
;; Equivalent timer definition, but shorter. (shepherd-timer '(updatedb) "0 3 * * *" #~(#$(file-append findutils "/bin/updatedb")) #:requirement '(user-processes))
This procedure is defined as follows.
%default-timer-documentation] Return a Shepherd service with the given
provision periodically running command, a list-valued gexp,
according to schedule, a string in Vixie cron syntax or a gexp
providing a Shepherd calendar event. documentation is the string that
appears when running herd doc service
.
The example below shows how to define a timer and to add it to your operating system configuration.
(use-modules (gnu)) (use-service-modules shepherd) (use-package-modules base) (define updatedb-timer ;; Run 'updatedb' at 3AM everyday. (shepherd-timer '(updatedb) "0 3 * * *" ;Vixie cron syntax #~(#$(file-append findutils "/bin/updatedb") "--prunepaths=/tmp /var/tmp /gnu/store") #:requirement '(user-processes))) (define garbage-collection-timer ;; Run 'guix gc' everyday at 5AM. (shepherd-timer '(garbage-collection) #~(calendar-event #:hours '(5) #:minutes '(0)) #~("/run/current-system/profile/bin/guix" "gc" "-F" "10G") #:requirement '(guix-daemon))) (operating-system ;; … ;; Extend the Shepherd service with additional timers ;; using 'simple-service'. (services (cons (simple-service 'my-timers shepherd-root-service-type (list garbage-collection-timer updatedb-timer)) %base-services)))
The resulting system contains these two services, which can be inspected
with herd status
. They can also be triggered manually:
herd trigger garbage-collection
See Timers in The GNU Shepherd Manual for more information on Shepherd timers.
Alternatively, the (gnu services mcron)
module provides an interface
to GNU mcron, a daemon to run jobs at scheduled times (see GNU mcron). GNU mcron is similar to the traditional Unix
cron
daemon; the main difference is that it is implemented in
Guile Scheme. It is overall less convenient than Shepherd timers:
individual jobs cannot depend on specific Shepherd services, logging is
coarse-grain (one file for all the jobs), jobs may not be inspected,
updated, or triggered manually.
Примечание: For the reasons given above, we recommend using Shepherd timers rather than mcron for your periodic tasks.
The example below defines an operating system that runs the
updatedb
(see Invoking updatedb in Finding Files) and
the guix gc
commands (see Вызов guix gc
) daily, as well as
the mkid
command on behalf of an unprivileged user (see mkid
invocation in ID Database Utilities). It uses gexps to introduce
job definitions that are passed to mcron (see G-Expressions).
(use-modules (guix) (gnu) (gnu services mcron)) (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. #~(job '(next-hour '(3)) (lambda () (system* (string-append #$findutils "/bin/updatedb") "--prunepaths=/tmp /var/tmp /gnu/store")) "updatedb")) (define garbage-collector-job ;; Collect garbage 5 minutes after midnight every day. ;; The job's action is a shell command. #~(job "5 0 * * *" ;Vixie cron syntax "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. #~(job '(next-minute-from (next-hour '(12 19)) '(15)) (string-append #$idutils "/bin/mkid src") #:user "charlie")) (operating-system ;; … ;; %BASE-SERVICES already includes an instance of ;; 'mcron-service-type', which we extend with additional ;; jobs using 'simple-service'. (services (cons (simple-service 'my-cron-jobs mcron-service-type (list garbage-collector-job updatedb-job idutils-job)) %base-services)))
Tip: When providing the action of a job specification as a procedure, you should provide an explicit name for the job via the optional 3rd argument as done in the
updatedb-job
example above. Otherwise, the job would appear as “Lambda function” in the output ofherd schedule mcron
, which is not nearly descriptive enough!
Tip: Avoid calling the Guile procedures
execl
,execle
orexeclp
inside a job specification, else mcron won’t be able to output the completion status of the job.
For more complex jobs defined in Scheme where you need control over the top
level, for instance to introduce a use-modules
form, you can move
your code to a separate program using the program-file
procedure of
the (guix gexp)
module (see G-Expressions). The example below
illustrates that.
(define %battery-alert-job
;; Beep when the battery percentage falls below %MIN-LEVEL.
#~(job
'(next-minute (range 0 60 1))
#$(program-file
"battery-alert.scm"
(with-imported-modules (source-module-closure
'((guix build utils)))
#~(begin
(use-modules (guix build utils)
(ice-9 popen)
(ice-9 regex)
(ice-9 textual-ports)
(srfi srfi-2))
(define %min-level 20)
(setenv "LC_ALL" "C") ;ensure English output
(and-let* ((input-pipe (open-pipe*
OPEN_READ
#$(file-append acpi "/bin/acpi")))
(output (get-string-all input-pipe))
(m (string-match "Discharging, ([0-9]+)%" output))
(level (string->number (match:substring m 1)))
((< level %min-level)))
(format #t "warning: Battery level is low (~a%)~%" level)
(invoke #$(file-append beep "/bin/beep") "-r5")))))))
See mcron job specifications in GNU mcron, for more information on mcron job specifications. Below is the reference of the mcron service.
On a running system, you can use the schedule
action of the service
to visualize the mcron jobs that will be executed next:
# herd schedule mcron
The example above lists the next five tasks that will be executed, but you can also specify the number of tasks to display:
# herd schedule mcron 10
This is the type of the mcron
service, whose value is an
mcron-configuration
object.
This service type can be the target of a service extension that provides additional job specifications (see Структура сервисов). In other words, it is possible to define services that provide additional mcron jobs to run.
Available mcron-configuration
fields are:
mcron
(default: mcron
) (type: file-like)The mcron package to use.
jobs
(default: '()
) (type: list-of-gexps)This is a list of gexps (see G-Expressions), where each gexp corresponds to an mcron job specification (see mcron job specifications in GNU mcron).
log?
(default: #t
) (type: boolean)Log messages to standard output.
log-file
(default: "/var/log/mcron.log"
) (type: string)Log file location.
log-format
(default: "~1@*~a ~a: ~a~%"
) (type: string)(ice-9 format)
format string for log messages. The default value
produces messages like ‘pid name: message’
(see Invoking in GNU mcron). Each message is
also prefixed by a timestamp by GNU Shepherd.
date-format
(type: maybe-string)(srfi srfi-19)
format string for date.
Next: Ротация логов, Previous: Базовые службы, Up: Сервисы [Contents][Index]