Systemd Service bedingt starten?

14

In meiner Organisation gibt es eine Reihe einfach zu verwendender Basis-AMIs für verschiedene Dienste wie ECS und Docker. Da viele unserer Projekte CloudFormation beinhalten, verwenden wir diese cfn-bootstrap, die aus einigen Skripten und einem Dienst besteht, der beim Booten ausgeführt wird, um bestimmte Pakete zu installieren und bestimmte Konfigurationsverwaltungsaufgaben für uns auszuführen.

Beim Start eines Systems muss ein Äquivalent des folgenden Skripts ausgeführt werden:

#!/bin/bash

# capture stderr only
output="$(cfn-init -s $STACK_NAME -r $RESOURCE_NAME --region $REGION >/dev/null)"

# if it failed, signal to CloudFormation that it failed and include a reason
returncode=$?
if [[ $returncode == 0]]; then
    cfn-signal -e $returncode -r "$output"
    exit $returncode
fi

# otherwise, signal success
cfn-signal -s

Ich dachte daran, dies als systemd- oneshotDienst auszuführen , der After=network.targetund ausführt WantedBy=multi-user.target.

Das einzige Problem ist, dass ich möchte, dass mein AMI flexibel ist und dies nur ausführt, wenn eine bestimmte Datei vorhanden ist. Anstatt das obige Skript in die EC2-Benutzerdaten einzubetten, können die Benutzerdaten einfach eine Umgebungsdatei definieren, die die benötigten Variablen definiert, und meinen One-Shot-Dienst nur ausführen, wenn diese Umgebungsdatei vorhanden ist:

#cloud-init
write_files:
    - path: /etc/sysconfig/cloudformation
      # ...
      content: |
          CFN_STACK_NAME="stack-name"
          CFN_RESOURCE="resource-name"
          CFN_REGION="region"

Gibt es eine Möglichkeit, systemd nur dann einen Dienst ausführen zu lassen, wenn eine bestimmte Bedingung erfüllt ist?

Naftuli Kay
quelle

Antworten:

16

systemd bietet eine Vielzahl von Bedingungen, die Sie testen können . Sie können beispielsweise ConditionPathExists=die Existenz einer Datei testen.

[Unit]
ConditionPathExists=/etc/sysconfig/cloudformation
Michael Hampton
quelle
3
Es ist erwähnenswert, dass dies keine whileBedingung ist, sondern eine if, was bedeutet, dass ConditionPathExistsder Rest des Dienstes einfach nicht ausgeführt wird , wenn der in angegebene Pfad zum Zeitpunkt des Starts des Dienstes nicht vorhanden ist. Das heißt, es wartet nicht darauf, dass der Pfad existiert.
Mahn
@Mahn mit einem systemd-Timer sollte es möglich sein, den Dienst wiederholt in einem Intervall auszulösen, um diese Einschränkung zu überwinden.
Naftuli Kay
@Mahn Schauen Sie sich freedesktop.org/software/systemd/man/systemd.path.html# an . Es kann einen Pfad überwachen und eine Aktivierung bereitstellen, beispielsweise basierend darauf, wann ein Pfad entsteht.
Benf
2

Ich bin auf diese Frage gestoßen und habe nach Möglichkeiten gesucht, einen systemd-Dienst unter Verwendung einer Bedingung zu starten. Es gibt viele Wege:

ConditionArchitecture=, ConditionVirtualization=, ConditionHost=, ConditionKernelCommandLine=, ConditionSecurity=, ConditionCapability=, ConditionACPower=, ConditionNeedsUpdate=, ConditionFirstBoot=, ConditionPathExists=, ConditionPathExistsGlob=, ConditionPathIsDirectory=, ConditionPathIsSymbolicLink=, ConditionPathIsMountPoint=, ConditionPathIsReadWrite=, ConditionDirectoryNotEmpty=, ConditionFileNotEmpty=, ConditionFileIsExecutable=

Ich wollte den Dienst basierend auf einem bestimmten Hostnamen starten.

ConditionHost= kann verwendet werden, um mit dem Hostnamen oder der Computer-ID des Hosts abzugleichen. Dies erfordert entweder eine Hostnamenzeichenfolge (optional mit Globs im Shell-Stil), die anhand des von gethostname (2) zurückgegebenen lokal festgelegten Hostnamens getestet wird, oder eine als Zeichenfolge formatierte Maschinen-ID (siehe Maschinen-ID (5)). Der Test kann durch Voranstellen eines Ausrufezeichens annulliert werden.

Mehr dazu hier .

radtek
quelle