Tenho vários serviços systemd que requerem um EnvironmentFile gerado. Eu tenho um script de shell que gera esse arquivo de ambiente, mas como preciso desse arquivo de ambienteantesqualquer comando Exec... é executado, não consigo usar ExecStartPre=generate_env_file.sh . Portanto, tenho outro serviço (generate_env_file.service) configurado para executar esse script como um oneshot:
[Service]
Type=oneshot
ExecStartPre=/usr/bin/touch /path/to/config.ini
ExecStart=/path/to/generate_env_file.sh
e tenho vários outros arquivos de serviço que possuem:
[Unit]
Requires=generate_env_file.service
After=generate_env_file.service
Como posso garantir que dois ou mais serviços dependentes (que requerem generate_env_file.service) não serão executados em paralelo e gerarão duas execuções paralelas de generate_env_file.service?
Eu olhei para usar RemainAfterExit=true ou possivelmente StartLimitIntervalSec= e StartLimitBurst= para garantir que apenas uma cópia será executada por vez durante algum período, mas não tenho certeza da melhor maneira de fazer isso.
Responder1
RemainAfterExit=true
é o caminho a seguir. Neste caso, o Systemd inicia o serviço e o Systemd o considera como iniciado e ativo. No entanto, isso não cobre o caso de uso de execução systemctl restart generate_env_file.service
. Neste caso, o systemd executará novamente o seu serviço. Para resolver isso, você poderia criar um arquivo de marcador no sistema de arquivos de execução ExecStartPost=
e adicionarConditionPathExists=
diretiva para verificar a existência do arquivo.
Responder2
ConditionFirstBoot
também pode ser interessante:
Aceita um argumento booleano. Esta condição pode ser usada para condicionar as unidades ao fato de o sistema estar inicializando pela primeira vez. Isso significa aproximadamente que
/etc/
não foi preenchido quando o sistema iniciou a inicialização (para obter detalhes, consulte "Semântica da primeira inicialização" em ID da máquina (5)). A primeira inicialização é considerada concluída (esta condição será avaliada como falsa) após o gerenciador terminar a fase de inicialização.Esta condição pode ser usada para preencher
/etc/
na primeira inicialização após a redefinição de fábrica ou quando uma nova instância do sistema é inicializada pela primeira vez.Para maior robustez, as unidades com
ConditionFirstBoot=yes
devem ordenar-se antesfirst-boot-complete.target
e puxar este alvo passivo comWants=
. Isto garante que, no caso de uma primeira inicialização abortada, essas unidades serão executadas novamente durante a próxima inicialização do sistema.Se a
systemd.condition-first-boot=
opção for especificada na linha de comando do kernel (assumindo um booleano), ela substituirá o resultado desta verificação de condição, tendo precedência sobre/etc/machine-id
as verificações de existência.
Responder3
Atualize generate_env_file.sh
para verificar se existe um arquivo de bloqueio assim que for iniciado. Se o arquivo de bloqueio existir, saia imediatamente.
Se não existir nenhum arquivo de bloqueio, toque no arquivo de bloqueio imediatamente, prossiga para gerar o arquivo de configuração e remova o arquivo de bloqueio.
Dito de outra forma, não acho que systemd
haja uma maneira nativa de lidar com a situação que você está descrevendo por meio da configuração, então use um arquivo de bloqueio.
E como aponta @shellter, o site Unix é um site mais apropriado para systemd
dúvidas futuras.