¿Iniciar el servicio systemd condicionalmente?

14

En mi organización tenemos una serie de AMI básicas fáciles de usar para diferentes servicios, como ECS y Docker. Dado que muchos de nuestros proyectos involucran CloudFormation, estamos usando cfn-bootstrap, que consiste en un par de scripts y un servicio que se ejecuta en el arranque para instalar ciertos paquetes y realizar ciertas tareas de administración de configuración por nosotros.

Al iniciar un sistema, se debe ejecutar un equivalente del siguiente script:

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

Estaba pensando en ejecutar esto como un oneshotservicio systemd que se ejecuta After=network.targety WantedBy=multi-user.target.

El único problema es que me gustaría que mi AMI sea flexible y solo ejecute esto si existe un determinado archivo. En lugar de incrustar el script anterior en los datos del usuario EC2, puedo hacer que los datos del usuario solo definan un archivo de entorno que defina las variables que necesito y solo ejecute mi servicio de una sola vez si ese archivo de entorno existe:

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

¿Hay alguna manera de hacer que systemd solo ejecute un servicio si se cumple una condición determinada?

Naftuli Kay
fuente

Respuestas:

16

systemd proporciona una amplia variedad de condiciones que puede probar . Por ejemplo, puede usar ConditionPathExists=para probar la existencia de un archivo.

[Unit]
ConditionPathExists=/etc/sysconfig/cloudformation
Michael Hampton
fuente
3
Vale la pena señalar que esto no es una whilecondición, sino una if, lo que significa que si la ruta especificada en ConditionPathExistsno existe para el momento en que se inicia el servicio, el resto del servicio simplemente no se ejecutará. Es decir, no espera a que exista el camino.
Mahn
@Mahn utilizando un temporizador systemd, debería ser posible activar repetidamente el servicio en un intervalo para superar esa limitación.
Naftuli Kay
@Mahn Eche un vistazo a freedesktop.org/software/systemd/man/systemd.path.html# . Puede monitorear una ruta y proporcionar activación basada, por ejemplo, cuando una ruta llega a existir.
benf
2

Me topé con esta pregunta buscando formas de iniciar un servicio systemd usando una condición. Hay muchas maneras:

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

Quería iniciar el servicio basado en un nombre de host específico.

ConditionHost= puede usarse para hacer coincidir el nombre de host o la ID de máquina del host. Esto toma una cadena de nombre de host (opcionalmente con globos de estilo de shell) que se prueba contra el nombre de host establecido localmente tal como lo devuelve gethostname (2), o una ID de máquina formateada como cadena (ver id-máquina (5)). La prueba puede negarse anteponiendo un signo de exclamación.

Más sobre eso aquí .

radtek
fuente