Neustart des Systemd Unit-Dienstes, wenn ein anderer Dienst gestartet oder neu geladen wird

16

Ich würde gerne wissen, ob es eine Möglichkeit gibt Systemd, neu zu starten A.service( After), wenn B.serviceSie gestartet oder neu geladen werden (nur Konfiguration neu laden), wenn möglich ohne Bearbeitung, B.servicedie vom System installiert und aktualisiert wird.

A.servicesollte starten, auch wenn B.servicenicht installiert, deaktiviert oder gestoppt.

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
quelle

Antworten:

12

Sie können PartOfim [Unit]Abschnitt verwenden.

Beispiel: PartOf=B.service

Von der Manpage,

PartOf =

Konfiguriert Abhängigkeiten ähnlich wie Requires =, beschränkt sich jedoch auf das Stoppen und Neustarten von Einheiten. Wenn systemd die hier aufgelisteten Einheiten stoppt oder neu startet, wird die Aktion auf diese Einheit übertragen. Beachten Sie, dass dies eine Einwegabhängigkeit ist - Änderungen an diesem Gerät wirken sich nicht auf die aufgeführten Geräte aus.

Thushi
quelle
Vielen Dank, ich habe Overriding vendor settingsnachgeforscht, aber das sieht noch einfacher und vielversprechender aus. Nur, dass ich nicht Aaufhören möchte , wenn ich Baufhöre, nur A.restartwenn B.start, trotzdem werde ich bald einen Test machen und sehen, ob es eine Möglichkeit gibt, es zu handhaben werden Sie wissen lassen
Alex
@Alex: Was ist, wenn du PartOfund Restart=alwayszusammen benutzt?
Thushi
Ich schaue mir die Restart=Dokumentation an, ich bin mir nicht sicher, wie sich die oneshotDienste verhalten , aber unabhängig davon: When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restartedWenn ich richtig verstehe, würde das manuelle Stoppen von B A stoppen
Alex
Naja jetzt hat sich das Kopfgeld automatisch für das Verfallsdatum zugeteilt, @Thushi Ich schätze deine Mühe und den Vorschlag, PartOfist aber keine Lösung für die Frage, trotzdem viel Spaß.
Alex
@Alex: Nun, Punkte sind für mich nicht wichtig. Es gibt so viele andere Möglichkeiten, wie ich Punkte verdienen kann. Ich möchte nur wissen, ob die bereitgestellte Lösung Ihr Problem löst. Wenn nicht, werden wir weiter daran arbeiten. Wie wäre es PartOfmit Restart=always? Hast du das versucht?
Thushi
3

Ich hatte keine Kontrolle über stopmit PartOf=und Amuss nicht aufhören mit B, so dass ich am Ende die Einstellungen des Anbieters überschreiben verwendet habe , scheint zu funktionieren.

/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'

/cmdDie Implementierung ist asynchron und greift auf eine Ressource /script.shzu, auf die auch zugegriffen werden muss. Ich habe (vorerst) nichts Besseres gefunden, als ein paar Sekunden zu schlafen.

Ich habe versucht, systemctl [--no-block] try-restartvor der Verwendung /script.shdirekt zu verwenden, aber nicht funktioniert.

Alex
quelle
Ich suche auch nach einer Lösung für dieses Szenario. Könnten Sie diese Lösung bitte etwas näher erläutern? oder geben Sie einen Link zu einigen Dokumenten, um zu lesen und zu verstehen, was Sie getan haben.
zappy
Hallo @zappy, schaue im Handbuch nach man systemd.unit(oder suche es online, wenn es nicht installiert ist) und suche im Kapitel "Übergeordnete Herstellereinstellungen".
Alex
Danke für deinen Beitrag. Ich verstehe, dass Sie die obige Methode nur wählen, weil Service B herstellerspezifisch ist und Sie diese Servicedatei nicht bearbeiten möchten. In meinem Fall werden Service A und B jedoch nicht vom Anbieter geliefert. Ich bin der Meinung, dass das System dadurch komplexer wird. Haben wir noch andere Möglichkeiten?
zappy
Die Frage ist ein paar Jahre alt, haben Sie die Dokumentation überprüft? Vielleicht wurde dieses Szenario seitdem behandelt. Zu der Zeit hatte ich es eilig, aber wenn ich Zeit hatte, suchte ich nach der offiziellen Mailingliste des Systems und fragte dort, ob ich irgendwann eine Ausgabe öffnen könnte
Alex,
1

Derzeit deckt systemd dieses Szenario nicht ab. Sie können diese Funktionalität nicht allein durch Servicedateien erreichen. Eine Möglichkeit besteht darin, systemctl über ein gleichnamiges Shell-Skript zu hijacken und dabei zu prüfen, ob B.service gerade neu gestartet oder geladen wird, die entsprechende Aktion auch mit A.service durchzuführen und bei Bedarf das zu aktualisieren rc.local, um auch beim Booten in den richtigen Zustand zu gelangen. Ich habe dieses Problem mit docker.service und networking.service, starte sie aber immer zusammen neu:

systemctl docker.service networking.service neu starten

Offensichtlich wäre dies nicht effektiv, wenn das System selbst B.service intern manipulieren würde (z. B. über andere Servicedateien).

kaveh minooie
quelle