Tengo un servicio que ejecuta un software que genera algunos archivos de configuración si no existen y los lee si existen. El problema al que me he enfrentado es que estos archivos a veces se corrompen, lo que hace que el software no pueda iniciarse y, por lo tanto, el servicio falle. En este caso, me gustaría eliminar estos archivos y reiniciar el servicio.
Intenté crear un servicio que debería ejecutarse en caso de falla, haciendo esto:
[Service]
ExecStart=/bin/run_program
OnFailure=software-fail.service
dónde está este servicio:
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=systemctl --user start software.service
Sin embargo, el problema es que este servicio no se inicia, incluso cuando ha fallado.
Intenté hacerlo
systemctl --user enable software-fail.service
pero luego se inicia cada vez que se inicia el sistema, como cualquier otro servicio.
Mi solución temporal es usar
ExecStopPost=/bin/rm /file/to/delete
pero esta no es una forma satisfactoria de resolverlo, ya que siempre eliminará el archivo al detener el servicio, sin importar si se debió a una falla o no.
Salida cuando falla:
● software.service - Software
Loaded: loaded (/home/trippelganger/.config/systemd/user/software.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2018-05-04 09:05:26 CEST; 5s ago
Process: 1839 ExecStart=/bin/run_program (code=exited, status=1/FAILURE)
Main PID: 1839 (code=exited, status=1/FAILURE)
May 04 09:05:26 trippelganger systemd[595]: software.service: Main process exited, code=exited, status=1/FAILURE
May 04 09:05:26 trippelganger systemd[595]: software.service: Unit entered failed state.
May 04 09:05:26 trippelganger systemd[595]: software.service: Failed with result 'exit-code'.
La salida de systemctl –user status software-fail.service
es:
● software-fail.service - Delete corrupt files
Loaded: loaded (/home/trippelganger/.config/systemd/user/software-fail.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Respuesta aceptada:
NOTA :Probablemente quiera usar ExecStopPost=
en lugar de OnFailure=
aquí (ver mi otra respuesta), pero esto está tratando de abordar por qué su OnFailure=
la configuración no funciona.
El problema con OnFailure=
no iniciar la unidad puede deberse a que está en la sección incorrecta, debe estar en [Unit]
sección y no [Service]
.
Puedes probar esto en su lugar:
# software.service
[Unit]
Description=Software
OnFailure=software-fail.service
[Service]
ExecStart=/bin/run_program
Y:
# software-fail.service
[Unit]
Description=Delete corrupt files
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service
Puedo hacer que funcione con esta configuración.
Pero tenga en cuenta que usar OnFailure=
no es ideal aquí, ya que realmente no se puede saber por qué falló el programa y encadenar otro inicio en ExecStop=
llamando a /bin/systemctl start
directamente es bastante hacky... La solución usando ExecStopPost=
y mirar el estado de salida es definitivamente superior.
Si define OnFailure=
dentro de [Service]
, systemd (al menos la versión 234 de Fedora 27) se queja con:
software.service:6: Unknown lvalue 'OnFailure' in section 'Service'
No estoy seguro de si está viendo eso en sus registros o no... (¿Quizás esto se agregó en systemd reciente?) Eso debería ser una pista de lo que está sucediendo allí.
Relacionado:¿Diferencia entre '>' y '-gt'?