systemd oneshot Requisito para ejecutarse solo una vez

systemd oneshot Requisito para ejecutarse solo una vez

Tengo varios servicios systemd que requieren un EnvironmentFile generado. Tengo un script de shell que genera este archivo de entorno, pero como necesito ese archivo de entornoantesSe ejecuta cualquier comando Exec..., no puedo usar ExecStartPre=generate_env_file.sh. Por lo tanto, tengo otro servicio (generate_env_file.service) configurado para ejecutar ese script como un oneshot:

[Service]
Type=oneshot
ExecStartPre=/usr/bin/touch /path/to/config.ini
ExecStart=/path/to/generate_env_file.sh

y tengo muchos otros archivos de servicio que tienen:

[Unit]
Requires=generate_env_file.service
After=generate_env_file.service

¿Cómo puedo garantizar que dos o más servicios dependientes (que requieren generate_env_file.service) no se ejecuten en paralelo y generen dos ejecuciones paralelas de generate_env_file.service?

He analizado el uso de RemainAfterExit=true o posiblemente StartLimitIntervalSec= y StartLimitBurst= para garantizar que solo se ejecute una copia a la vez durante un período, pero no estoy seguro de cuál es la mejor manera de hacerlo.

Respuesta1

RemainAfterExit=truees el camino a seguir. En este caso Systemd inicia el servicio y Systemd lo considera iniciado y activo. Sin embargo, esto no cubre el caso de uso de ejecutar systemctl restart generate_env_file.service. En este caso, systemd volverá a ejecutar su servicio. Para resolver esto, puede crear un archivo de marcador en el sistema de archivos de ejecución ExecStartPost=y agregarConditionPathExists=Directiva para comprobar la existencia del archivo.

Respuesta2

ConditionFirstBootTambién puede ser interesante:

Toma un argumento booleano. Esta condición se puede utilizar para condicionar las unidades según si el sistema se está iniciando por primera vez. Esto significa aproximadamente que /etc/no estaba completo cuando el sistema comenzó a iniciarse (para obtener más detalles, consulte "Semántica del primer inicio" en ID de máquina (5)). El primer inicio se considera finalizado (esta condición se evaluará como falsa) después de que el administrador haya finalizado la fase de inicio.

Esta condición se puede utilizar para completarse /etc/en el primer inicio después del restablecimiento de fábrica o cuando se inicia una nueva instancia del sistema por primera vez.

Para mayor solidez, las unidades con ConditionFirstBoot=yesdeben ordenarse antes first-boot-complete.targety atraer a este objetivo pasivo con Wants=. Esto garantiza que, en caso de que se cancele el primer inicio, estas unidades se volverán a ejecutar durante el siguiente inicio del sistema.

Si la systemd.condition-first-boot=opción se especifica en la línea de comando del kernel (tomando un valor booleano), anulará el resultado de esta verificación de condición, teniendo prioridad sobre /etc/machine-id las verificaciones de existencia.

Respuesta3

Actualice generate_env_file.shpara verificar si existe un archivo de bloqueo tan pronto como se inicie. Si el archivo de bloqueo existe, salga inmediatamente.

Si no existe ningún archivo de bloqueo, toque el archivo de bloqueo inmediatamente, luego continúe con la tarea de generar el archivo de configuración y luego elimine el archivo de bloqueo.

Dicho de otra manera, no creo que systemdhaya una forma nativa de manejar la situación que estás describiendo a través de la configuración, así que usa un archivo de bloqueo.

Y como señala @shellter, el sitio Unix es un sitio más apropiado para systemdpreguntas en el futuro.

información relacionada