Script que manipula o código de retorno do serviço systemd

0

Estou escrevendo um serviço systemd que pode ser iniciado ou interrompido usando comandos systemctl.

No entanto, este programa também pode retornar com vários códigos de retorno e eu gostaria de lidar com esses códigos de retorno.

Por exemplo, se o serviço foi interrompido com systemctl stop <service> , ele não deve fazer nada. Mas se não foi morto por systemctl e retornou por si só eu quero executar um script de post no qual eu poderia obter o código de retorno e fazer ações, dependendo do seu valor.

Modificado após @ NarūnasK responder
Ao ter a versão systemd > = v232, tudo bem com a resposta do @ NarūnasK

No entanto, quando não tem a boa versão do sistema, como pode ser feito?

Eu pensei em fazer algo como

ExecStart=/bin/sh -c '<service> -C /etc/<service_conf_file>; [ $? -eq 1 ] && { <action> }'
    
por Arkaik 13.12.2017 / 12:06

1 resposta

2

ExecStopPost = deve fazer o que quiser.

Additional commands that are executed after the service is stopped. This includes cases where the commands configured in ExecStop= were used, where the service does not have any ExecStop= defined, or where the service exited unexpectedly. This argument takes multiple command lines, following the same scheme as described for ExecStart=. Use of these settings is optional. Specifier and environment variable substitution is supported. Note that – unlike ExecStop= – commands specified with this setting are invoked when a service failed to start up correctly and is shut down again.

It is recommended to use this setting for clean-up operations that shall be executed even when the service failed to start up correctly. Commands configured with this setting need to be able to operate even if the service failed starting up half-way and left incompletely initialized data around. As the service's processes have been terminated already when the commands specified with this setting are executed they should not attempt to communicate with them.

Note that all commands that are configured with this setting are invoked with the result code of the service, as well as the main process' exit code and status, set in the $SERVICE_RESULT, $EXIT_CODE and $EXIT_STATUS environment variables, see systemd.exec(5) for details.

Em seu script, você pode ler as variáveis de ambiente $EXIT_CODE ou $EXIT_STATUS e tomar as medidas adequadas.

EDITAR

Você pode usar a seguinte solução alternativa com systemd < 232 .

sample_script :

#! /bin/bash --

sleep 5

## Non standard exit code
exit 255

exit_handler :

#! /bin/bash --

CODE="${1:-N/A}"

echo CODE: $CODE
echo SERVICE_RESULT: $SERVICE_RESULT
echo EXIT_CODE: $EXIT_CODE
echo EXIT_STATUS: $EXIT_STATUS

sample_script.service :

# systemctl cat sample_script.service 
# /etc/systemd/system/sample_script.service
[Unit]
Description=My service
After=network.target rsyslog.service

[Service]
Type=simple
Restart=never
ExecStart=/bin/bash -c '/tmp/sample_script || /tmp/exit_handler $?'
ExecStopPost=/tmp/exit_handler

[Install]
WantedBy=multi-user.target

Status do sample_script.service :

# systemctl status sample_script.service 
● sample_script.service - My service
   Loaded: loaded (/etc/systemd/system/sample_script.service; enabled)
   Active: inactive (dead) since Thu 2017-12-14 12:29:16 GMT; 7s ago
  Process: 16511 ExecStopPost=/tmp/exit_handler (code=exited, status=0/SUCCESS)
  Process: 16505 ExecStart=/bin/bash -c /tmp/sample_script || /tmp/exit_handler $? (code=exited, status=0/SUCCESS)
 Main PID: 16505 (code=exited, status=0/SUCCESS)

Dec 14 12:29:11 build-local systemd[1]: Started My service.
Dec 14 12:29:16 build-local bash[16505]: CODE: 255
Dec 14 12:29:16 build-local bash[16505]: SERVICE_RESULT:
Dec 14 12:29:16 build-local bash[16505]: EXIT_CODE:
Dec 14 12:29:16 build-local bash[16505]: EXIT_STATUS:
Dec 14 12:29:16 build-local exit_handler[16511]: CODE: N/A
Dec 14 12:29:16 build-local exit_handler[16511]: SERVICE_RESULT:
Dec 14 12:29:16 build-local exit_handler[16511]: EXIT_CODE:
Dec 14 12:29:16 build-local exit_handler[16511]: EXIT_STATUS:

Você pode ver que exit_handler foi chamado duas vezes. No início, de bash , onde tem o código de saída fornecido a ele e, em seguida, como ExecStopPost= script, em que o argumento posicional do código de saída não foi fornecido, portanto, imprimiu N / A.

    
por 13.12.2017 / 13:06