GNU/Linux >> Tutoriels Linux >  >> Linux

Bonne façon d'utiliser OnFailure dans systemd

Afin d'effectuer un nettoyage si le service échoue, vous pouvez utiliser ExecStopPost= , qui est exécuté que le service réussisse ou non.

Dans le code que vous exécutez à ExecStopPost= , vous pouvez utiliser l'un des $SERVICE_RESULT , $EXIT_CODE ou $EXIT_STATUS pour déterminer la condition de défaillance et agir en conséquence. Consultez la documentation sur ces variables d'environnement pour vérifier celle qui vous convient.

Ensuite, vous pouvez utiliser Restart=on-failure afin que systemd essaie de redémarrer votre unité en cas d'échec.

En mettant tout cela ensemble, voici à quoi cela ressemblerait. En supposant que run_program sortira avec le statut 2 chaque fois que les fichiers sont corrompus (j'espère que vous pourrez adapter cela à d'autres scénarios d'échec à partir de la documentation ci-dessus), cela devrait fonctionner :

[Service]
ExecStart=/bin/run_program
ExecStopPost=/bin/sh -c 'if [ "$$EXIT_STATUS" = 2 ]; then rm /file/to/delete; fi'
Restart=on-failure

(REMARQUE :Le double signe dollar $$ est d'échapper à systemd, donc le shell voit $EXIT_STATUS et accède à cette variable. L'utilisation d'un seul signe dollar fonctionnerait également, mais systemd effectuerait ce remplacement à la place et le shell verrait [ "2" = 2 ] , qui fonctionne sans doute aussi... Quoi qu'il en soit, vous pouvez contourner la plupart de cela en mettant toute cette logique dans un script shell et en l'appelant par son chemin complet dans ExecStopPost= , ce serait probablement mieux et vous pourriez aussi facilement ajouter plus de commandes au script, comme enregistrer l'action entreprise pour récupérer de la condition d'erreur.)

J'espère que cela vous donnera suffisamment d'indications pour comprendre comment configurer cela correctement compte tenu de votre situation particulière !


REMARQUE  :Vous souhaitez probablement utiliser ExecStopPost= au lieu de OnFailure= ici (voir mon autre réponse), mais cela essaie de comprendre pourquoi votre OnFailure= la configuration ne fonctionne pas.

Le problème avec OnFailure= ne pas démarrer l'unité peut être parce qu'elle est dans la mauvaise section, elle doit être dans le [Unit] section et non [Service] .

Vous pouvez essayer ceci à la place :

# software.service
[Unit]
Description=Software
OnFailure=software-fail.service

[Service]
ExecStart=/bin/run_program

Et :

# software-fail.service
[Unit]
Description=Delete corrupt files

[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service

Je peux le faire fonctionner avec cette configuration.

Mais notez que l'utilisation de OnFailure= n'est pas idéal ici, car vous ne pouvez pas vraiment dire pourquoi le programme a échoué, et enchaîner un autre démarrage en ExecStop= en appelant le /bin/systemctl start directement est assez hacky... La solution utilisant ExecStopPost= et regarder le statut de sortie est définitivement supérieur.

Si vous définissez OnFailure= à l'intérieur de [Service] , systemd (au moins la version 234 de Fedora 27) se plaint avec :

software.service:6: Unknown lvalue 'OnFailure' in section 'Service'

Vous ne savez pas si vous voyez cela dans vos journaux ou non... (Peut-être que cela a été ajouté dans un systemd récent ?) Cela devrait être un indice de ce qui se passe là-bas.


Linux
  1. Comment utiliser la commande Systemctl pour gérer les services Systemd

  2. Comment créer un service Systemd sous Linux

  3. Ajouter un nouveau service à Linux systemd

  4. Debian – Bonne façon d'utiliser Onfailure dans Systemd ?

  5. Comment utiliser Systemd pour redémarrer un service en panne ?

Commandes Systemctl pour gérer le service Systemd

Gestion des cgroups avec systemd

Utiliser Systemctl pour gérer les services

Manière correcte d'utiliser Ubuntu systemctl pour contrôler Systemd

Quelle est la bonne façon d'utiliser inotify ?

activation de socket systemd vs xinetd