systemd oneshot Requisito para executar apenas uma vez

systemd oneshot Requisito para executar apenas uma vez

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

ConditionFirstBoottambé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=yesdevem ordenar-se antes first-boot-complete.targete puxar este alvo passivo com Wants=. 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.shpara 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 systemdhaja 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 systemddúvidas futuras.

informação relacionada