Suivant: , Précédent: , Monter: Services   [Table des matières][Index]


11.10.2 Exécution de tâches planifiées

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 (voir Services 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

Voir Timers dans 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 (voir 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.

Remarque : For the reasons given above, we recommend using Shepherd timers rather than mcron for your periodic tasks.

L’exemple en dessous définit un système d’exploitation qui lance les commandes updatebd (voir Invoking updatedb dans Finding Files) et guix gc (voir Invoquer guix gc) tous les jours, ainsi que la commande mkid en tant qu’utilisateur non privilégié (voir mkid invocation dans ID Database Utilities). Il utilise des gexps pour introduire des définitions de tâches qui sont passées à mcron (voir G-Expressions).

(use-modules (guix) (gnu) (gnu services mcron))
(use-package-modules base idutils)

(define updatedb-job
  ;; Lance « updatedb » à 3h du matin chaque jour.  Ici nous spécifions
  ;; l'action de la tâche comme une procédure Scheme.
  #~(job '(next-hour '(3))
         (lambda ()
           (system* (string-append #$findutils "/bin/updatedb")
                  "--prunepaths=/tmp /var/tmp /gnu/store"))
         "updatedb"))

(define garbage-collector-job
  ;; Lance le ramasse-miettes tous les jours à minuit cinq.
  ;; L'action de la tâche est une commande shell.
  #~(job "5 0 * * *"            ;Vixie cron syntax
         "guix gc -F 1G"))

(define idutils-job
  ;; Met à jour la base de données d'index en tant que « charlie » à 12h15
  ;; et 19h15.  La commande est lancée depuis le répertoire personnel de l'utilisateur.
  #~(job '(next-minute-from (next-hour '(12 19)) '(15))
         (string-append #$idutils "/bin/mkid src")
         #:user "charlie"))

(operating-system
  ;; …

  ;; %BASE-SERVICES inclus déjà une instance de
  ;; « mcron-service-type », que nous étendons avec un
  ;; travail supplémentaire avec « simple-service ».
  (services (cons (simple-service 'my-cron-jobs
                                   mcron-service-type
                                   (list garbage-collector-job
                                         updatedb-job
                                         idutils-job))
                  %base-services)))

Astuce : Lorsque vous fournissez l’action d’une spécification de tâche avec une procédure, vous devriez donner un nom explicite à la tâche via le troisième argument facultatif comme dans l’exemple updatedb-job ci-dessus. Sinon, la tâche apparaitra comme « Lambda function » dans la sortie de herd schedule mcron, ce qui n’est pas très descriptif !

Astuce : Évitez d’appeler les procédures Guile execl, execle et execlp dans la spécification des tâches sinon mcron ne pourra pas afficher le statut complet de la tâche.

Pour les tâches plus complexes définies dans Scheme où vous devez contrôler le haut niveau, par exemple pour introduire un formulaire use-modules, vous pouvez déplacer votre code vers un programme séparé en utilisant la procédure program-file du module (guix gexp) (voir G-Expressions). L’exemple ci-dessous illustre cette possibilité.

(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")     ; assure que la sortie est en anglais
              (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")))))))

Voir mcron job specifications dans GNU mcron, pour plus d’informations sur les spécifications des tâche de mcron. Ci-dessous est la référence du service mcron.

Sur un système lancé, vous pouvez utiliser l’action schedule du service pour visualiser les travaux mcron qui seront exécutés ensuite :

# herd schedule mcron

Cet exemple ci-dessus montre les cinq tâches qui seront exécutés, mais vous pouvez spécifier le nombre de tâches à afficher :

# herd schedule mcron 10
Variable :mcron-service-type

C’est le type du service mcron, dont la valeur est un objet mcron-configuration.

Ce type de service peut être la cible d’une extension de service qui fournit des spécifications de tâches supplémentaires (voir Composition de services). En d’autres termes, il est possible de définir des services qui fournissent des tâches mcron à lancer.

Type de données :mcron-configuration

Les champs de mcron-configuration disponibles sont :

mcron (par défaut : mcron) (type : simili-fichier)

Le paquet mcron à utiliser.

jobs (par défaut : '()) (type : liste-de-gexps)

C’est la liste des gexps (voir G-Expressions), où chaque gexp correspond à une spécification de tâche de mcron (voir mcron job specifications dans GNU mcron).

log? (par défaut : #t) (type : booléen)

Journalise les messages sur la sortie standard.

log-file (par défaut : "/var/log/mcron.log") (type : chaine)

Log file location.

log-format (par défaut : "~1@*~a ~a: ~a~%") (type : chaine)

Chaine de format (ice-9 format) pour les message de journaux. La valeur par défaut produit des messages de type ‘pid name: message’ (voir Invoking dans GNU mcron). Chaque message est aussi préfixé par un horodatage par le GNU Shepherd.

date-format (type : peut-être-chaine)

(srfi srfi-19) format string for date.


Suivant: Rotation des journaux, Précédent: Services de base, Monter: Services   [Table des matières][Index]