Redémarrage du service de l'unité Systemd si un autre service démarre ou se recharge

16

Je voudrais savoir s'il existe un moyen Systemdde redémarrer A.service( After) lors du B.servicedémarrage ou du rechargement (reload config uniquement), si possible sans modification B.servicequi est installée et mise à niveau par le système.

A.servicedevrait démarrer même s'il B.servicen'est pas installé, désactivé ou arrêté.

A.service:

[Unit]
After = B.service network-online.target
Wants = B.service

[Service]
Type=oneshot
ExecStart = /script.sh start
ExecStop = /script.sh stop
RemainAfterExit=yes

[Install]
WantedBy = network-online.target

B.service:

[Unit]
After=syslog.target network.target

[Service]
Type=forking
ExecStart=/cmd start
ExecStop=/cmd stop
ExecReload=/cmd reload
PIDFile=/var/run/cmd.pid

[Install]
WantedBy=multi-user.target
Alex
la source

Réponses:

12

Vous pouvez utiliser PartOfdans la [Unit]section.

Exemple: PartOf=B.service

Depuis la page de manuel,

PartOf =

Configure les dépendances similaires à Requiert =, mais limitées à l'arrêt et au redémarrage des unités. Lorsque systemd arrête ou redémarre les unités répertoriées ici, l'action est propagée à cette unité. Notez qu'il s'agit d'une dépendance à sens unique - les modifications apportées à cette unité n'affectent pas les unités répertoriées.

Thushi
la source
Merci, je cherchais Overriding vendor settingsmais cela semble encore plus facile et prometteur, seule excpetion est que je ne veux Apas m'arrêter si Barrêter, juste A.restartsi B.start, de toute façon je ferai bientôt un test et voir s'il y a un moyen de le gérer, alors vous le fera savoir
Alex
@Alex: Et si vous utilisez PartOfet Restart=alwaysensemble?
Thushi
Je regarde la Restart=documentation, je ne sais pas quel est le comportement avec les oneshotservices, mais peu importe: When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restartedsi je comprends bien, arrêter manuellement B arrêterait A
Alex
Eh bien maintenant, la prime s'est auto-assignée pour l'expiration, @Thushi J'apprécie vos efforts et la suggestion mais ce PartOfn'est pas une solution à la question, profitez-en quand même.
Alex
@Alex: Eh bien, les points ne sont pas importants pour moi. Il y a tellement d'autres façons de gagner des points. Je veux juste savoir si la solution fournie résout votre problème. Sinon, nous y travaillerons plus avant. Que diriez-vous d'utiliser PartOfavec Restart=always? Avez-vous essayé cela?
Thushi
3

J'ai eu aucun contrôle sur stopavec PartOf=, et Ail ne faut pas arrêter avec B, donc je me suis retrouvé à l' aide de modifier les réglages des fournisseurs , semble fonctionner.

/etc/systemd/system/B.service.d/override.conf

[Service]
ExecStart=
ExecStart=/bin/sh -c '/cmd start || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'
ExecReload=
ExecReload=/bin/sh -c '/cmd reload || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'

/cmdl'implémentation est asynchrone et accède à une ressource à laquelle il /script.shfaut aussi accéder, je n'ai rien trouvé de mieux (pour l'instant) pour dormir quelques secondes.

J'ai essayé d'utiliser systemctl [--no-block] try-restartavant d'utiliser /script.shdirectement mais n'a pas fonctionné.

Alex
la source
Je recherche également une solution pour ce scénario. Pourriez-vous expliquer un peu plus cette solution? ou donnez un lien vers certains documents pour lire et comprendre ce que vous avez fait.
zappy
Bonjour @zappy, recherchez le manuel man systemd.unit(ou recherchez-le en ligne s'il n'est pas installé) et recherchez le chapitre "Remplacement des paramètres du fournisseur".
Alex
Merci pour votre participation. Je comprends que vous choisissez la méthode ci-dessus uniquement parce que le service B est spécifique au fournisseur et que vous ne souhaitez pas modifier ce fichier de service. Mais dans mon cas, les services A et B ne sont pas fournis par le fournisseur. Je pense que l'emporter peut ajouter de la complexité au système. Avons-nous d'autres options?
zappy
La question a quelques années, avez-vous vérifié la documentation? Peut-être que ce scénario a été couvert depuis. À l'époque, j'étais pressé, mais ayant le temps, je cherchais la liste de diffusion officielle de systemd et j'y demandais, puis j'ouvrais un problème
Alex
1

Pour le moment, systemd ne couvre pas ce senario. Vous ne pouvez pas atteindre cette fonctionnalité uniquement à l'aide des fichiers de service. Une possibilité consiste à détourner systemctl via un script shell du même nom et à vérifier si B.service est sur le point d'être redémarré / rechargé, effectuez également l'action appropriée avec A.service et, si nécessaire, mettez à jour le rc.local pour obtenir également l'état approprié au démarrage. J'ai ce problème avec docker.service et networking.service, mais je les redémarre toujours ensemble:

systemctl restart docker.service networking.service

De toute évidence, cela ne serait pas efficace si systemd lui-même manipulait B.service en interne (par exemple via d'autres fichiers de service.).

kaveh minooie
la source