Ich plane, mehrere Instanzen derselben Web-App für Kunden zu hosten, die diese verwenden systemd
. Ich möchte in der Lage sein, jede Kundeninstanz zu verwenden stop
und die gesamte Sammlung von Kundeninstanzen als einen einzigen Dienst zu behandeln, der gemeinsam gestoppt und gestartet werden kann.start
systemd
systemd
scheint die Bausteine bereitzustellen, die ich verwenden muss PartOf
, und Vorlageneinheitsdateien, aber ich habe den übergeordneten Dienst gestoppt, der untergeordnete Kundendienst wird nicht gestoppt. Wie kann ich das mit systemd machen? Folgendes habe ich bisher.
Die übergeordnete Einheitendatei app.service
:
[Unit]
Description=App Web Service
[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal
Eine Einheitsvorlagendatei mit dem Namen [email protected]
, mit der Kundeninstanzen erstellt werden:
[Unit]
Description=%I Instance of App Web Service
[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal
Mein app-poc.sh
Skript (Proof of Concept, das nur in einer Schleife als Protokolldatei gedruckt wird):
#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
echo "The App PoC loop for $@"
sleep 2;
done
Für den Proof of Concept habe ich die systemd-Einheitendateien in ~/.config/systemd/user
.
Ich starte dann das übergeordnete Element und eine Instanz basierend auf der Vorlage (danach systemctl --user daemon-reload
):
systemctl --user start app
systemctl --user start [email protected]
Durch die Verwendung journalctl -f
kann ich sehen, dass beide gestartet wurden und die Kundeninstanz weiterhin ausgeführt wird. Jetzt erwarte ich, dass das Herunterfahren des Elternteils das Kind stoppen wird (weil ich es verwendet habe PartOf
), aber das tut es nicht. Außerdem startet das Starten des Elternteils das Kind auch nicht wie erwartet.
systemctl --user stop app
Vielen Dank!
(Ich verwende Ubuntu 16.04 mit systemd 229).
Requires=
stattdessen verwenden?Antworten:
Sie müssen die Linie verschieben
aus
[Service]
und in den[Unit]
Abschnitt, und fügen Sie die[Unit]
vonapp.service
der Liste der Kunden zu beginnen, zBoder wie sourcejedi in den Kommentaren sagte,
Requires=
dasselbe. Sie können diePartOf
von Hand gestarteten To- Stop-Dienste behalten , die nicht in der obigen Liste aufgeführt sind, zsystemctl --user start [email protected]
.quelle
PartOf
. Vielen Dank. Ich werde die "Wünsche" über einen Symlink bearbeiten, der die einzige Aktion ist, die ich ausführen muss, um einen neuen Kunden mit systemd zu aktivieren. Für meinen Testfall: `ln -s /home/mark/.config/systemd/user/[email protected] / home / mark / .config / systemd / user / app.service.wants / entity @ foo.service`Ich habe gelernt, dass dies das ist, wofür systemd "Target Units" sind. Durch die Verwendung einer Zieleinheit erhalte ich die gewünschten Vorteile, ohne den oben genannten gefälschten
[Service]
Abschnitt erstellen zu müssen . Eine funktionierende Beispieldatei "Zieleinheit" sieht folgendermaßen aus:Dann sollte jede Kundeninstanz
PartOf
in den[Unit]
Abschnitt aufgenommen werden (wie von @meuh hervorgehoben), und sollte auch einen[Install]
Abschnitt haben, damitenable
unddisable
auf dem spezifischen Dienst arbeiten:Dieser einmalige Aktivierungsbefehl wird verwendet, um die Kundeninstanz aufzurufen und beim Starten des Ziels zu starten:
An diesem Punkt kann ich
stop
undstart
aufapp@customer
dem für eine bestimmte Instanz, oder kann ich verwendenstart app
undstop app
gemeinsam alle Anwendungen zu stoppen.quelle
systemctl status $(systemctl list-dependencies --plain otp.target)
systemd
dies die Benutzerfreundlichkeit hier verbessern könnte. Ich habe eine Funktionsanforderung geöffnet, um einen verbesserten Status für Ziele vorzuschlagen.