Ich habe mehrere systemd-Dienste, die eine generierte EnvironmentFile erfordern. Ich habe ein Shell-Skript, das diese Environment-Datei generiert, aber da ich diese Environment-Datei benötigeVoralle Exec...-Befehle werden ausgeführt, ich kann nicht ExecStartPre=generate_env_file.sh verwenden. Daher habe ich einen anderen Dienst (generate_env_file.service) eingerichtet, um dieses Skript als Oneshot auszuführen:
[Service]
Type=oneshot
ExecStartPre=/usr/bin/touch /path/to/config.ini
ExecStart=/path/to/generate_env_file.sh
und ich habe mehrere andere Servicedateien mit:
[Unit]
Requires=generate_env_file.service
After=generate_env_file.service
Wie kann ich garantieren, dass zwei oder mehr abhängige Dienste (die generate_env_file.service erfordern) nicht parallel ausgeführt werden und zwei parallele Ausführungen von generate_env_file.service erzeugen?
Ich habe mir die Verwendung von RemainAfterExit=true oder möglicherweise StartLimitIntervalSec= und StartLimitBurst= angesehen, um sicherzustellen, dass während eines bestimmten Zeitraums immer nur eine Kopie ausgeführt wird, bin mir jedoch nicht sicher, was die beste Vorgehensweise hierfür ist.
Antwort1
RemainAfterExit=true
ist der richtige Weg. In diesem Fall startet Systemd den Dienst und Systemd betrachtet ihn als gestartet und aktiv. Dies deckt jedoch nicht den Anwendungsfall der Ausführung ab systemctl restart generate_env_file.service
. In diesem Fall führt systemd Ihren Dienst erneut aus. Um dies zu lösen, können Sie eine Markierungsdatei im Ausführungsdateisystem erstellen ExecStartPost=
und hinzufügenConditionPathExists=
Direktive zum Überprüfen der Existenz einer Datei.
Antwort2
ConditionFirstBoot
könnte auch interessant sein:
Nimmt ein Boolean-Argument an. Diese Bedingung kann verwendet werden, um Units davon abhängig zu machen, ob das System zum ersten Mal hochfährt. Das bedeutet ungefähr, dass
/etc/
beim Hochfahren des Systems noch nicht belegt war (für Details siehe „Semantik des ersten Hochfahrens“ in Maschinen-ID(5)). Der erste Start gilt als abgeschlossen (diese Bedingung wird als falsch ausgewertet), nachdem der Manager die Startphase abgeschlossen hat.Diese Bedingung kann zum Ausfüllen
/etc/
beim ersten Start nach einer Zurücksetzung auf die Werkseinstellungen oder beim ersten Start einer neuen Systeminstanz verwendet werden.Aus Gründen der Robustheit sollten sich Einheiten mit
ConditionFirstBoot=yes
vor selbst sortierenfirst-boot-complete.target
und dieses passive Ziel mit einbeziehenWants=
. Dadurch wird sichergestellt, dass diese Einheiten im Falle eines abgebrochenen ersten Starts beim nächsten Systemstart erneut ausgeführt werden.Wenn die
systemd.condition-first-boot=
Option in der Kernel-Befehlszeile angegeben wird (und dabei einen Booleschen Wert annimmt), überschreibt sie das Ergebnis dieser Bedingungsprüfung und hat Vorrang vor/etc/machine-id
Existenzprüfungen.
Antwort3
Aktualisieren Sie generate_env_file.sh
, um gleich beim Start zu prüfen, ob eine Sperrdatei vorhanden ist. Wenn die Sperrdatei vorhanden ist, beenden Sie das Programm sofort.
Wenn keine Sperrdatei vorhanden ist, berühren Sie die Sperrdatei sofort, fahren Sie dann mit der Generierung der Konfigurationsdatei fort und entfernen Sie anschließend die Sperrdatei.
Anders ausgedrückt: Ich glaube nicht, systemd
dass es eine native Möglichkeit gibt, die von Ihnen beschriebene Situation über die Konfiguration zu handhaben. Verwenden Sie daher eine Sperrdatei.
Und wie @shellter betont, ist die Unix-Site für systemd
zukünftige Fragen besser geeignet.