Démarrer le service systemd de manière conditionnelle?

14

Dans mon organisation, nous avons un certain nombre d'AMI de base simples à utiliser pour différents services tels que ECS et Docker. Étant donné que beaucoup de nos projets impliquent CloudFormation, nous utilisons cfn-bootstrap, qui se compose de quelques scripts et d'un service qui s'exécute au démarrage pour installer certains packages et effectuer certaines tâches de gestion de la configuration pour nous.

Au démarrage d'un système, un équivalent du script suivant doit être exécuté:

#!/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

Je pensais à exécuter cela comme un oneshotservice systemd qui fonctionne After=network.targetet WantedBy=multi-user.target.

Le seul problème est que j'aimerais que mon AMI soit flexible et ne l'exécute que si un certain fichier existe. Plutôt que d'incorporer le script ci-dessus dans les données utilisateur EC2, je peux demander aux données utilisateur de simplement définir un fichier d'environnement qui définit les variables dont j'ai besoin et d'exécuter mon service one-shot si ce fichier d'environnement existe:

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

Existe-t-il un moyen de faire en sorte que systemd n'exécute un service que si une condition donnée est remplie?

Naftuli Kay
la source

Réponses:

16

systemd fournit une grande variété de conditions que vous pouvez tester . Par exemple, vous pouvez utiliser ConditionPathExists=pour tester l'existence d'un fichier.

[Unit]
ConditionPathExists=/etc/sysconfig/cloudformation
Michael Hampton
la source
3
Il convient de noter que ce n'est pas une whilecondition, mais une if, ce qui signifie que si le chemin spécifié dans ConditionPathExistsn'existe pas au moment où le service démarre, le reste du service ne s'exécutera tout simplement pas. C'est-à-dire qu'il n'attend pas que le chemin existe.
Mahn
@Mahn utilisant un temporisateur systemd, il devrait être possible de déclencher à plusieurs reprises le service sur un intervalle pour surmonter cette limitation.
Naftuli Kay
@Mahn Jetez un œil à freedesktop.org/software/systemd/man/systemd.path.html# . Il peut surveiller un chemin d'accès et fournir une activation en fonction, par exemple, du moment où un chemin d'accès existe.
benf
2

Je suis tombé sur cette question en cherchant des moyens de démarrer un service systemd en utilisant une condition. Il y a plusieurs façons:

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

Je voulais démarrer le service sur la base d'un nom d'hôte spécifique.

ConditionHost= peut être utilisé pour faire correspondre le nom d'hôte ou l'ID d'ordinateur de l'hôte. Cela prend soit une chaîne de nom d'hôte (éventuellement avec des globes de style shell) qui est testée par rapport au nom d'hôte défini localement tel que renvoyé par gethostname (2), ou un ID d'ordinateur formaté en chaîne (voir machine-id (5)). Le test peut être annulé en ajoutant un point d'exclamation.

Plus à ce sujet ici .

radtek
la source