Next: , Previous: , Up: Сервисы   [Contents][Index]


11.10.2 Запланированное исполнения задач

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.

11.10.2.1 Shepherd Timers

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.

Procedure: shepherd-timer provision schedule command [#:requirement '()]  [#:documentation

%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.

11.10.2.2 Mcron

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 of herd schedule mcron, which is not nearly descriptive enough!

Tip: Avoid calling the Guile procedures execl, execle or execlp 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
Variable: mcron-service-type

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.

Data Type: mcron-configuration

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]