Serviço Systemd Unit reiniciar se outro serviço iniciar ou recarregar

16

Gostaria de saber se existe uma maneira Systemdde reiniciar A.service( After) quando B.serviceiniciar ou recarregar (apenas recarregar a configuração), se possível sem editar a B.serviceinstalação e a atualização do sistema.

A.servicedeve iniciar mesmo se B.servicenão estiver instalado, desativado ou parado.

A.service:

[Unit]
After = B.service network-online.target
Wants = B.service

[Service]
Type=oneshot
ExecStart = /script.sh start
ExecStop = /script.sh stop
RemainAfterExit=yes

[Install]
WantedBy = network-online.target

B.service:

[Unit]
After=syslog.target network.target

[Service]
Type=forking
ExecStart=/cmd start
ExecStop=/cmd stop
ExecReload=/cmd reload
PIDFile=/var/run/cmd.pid

[Install]
WantedBy=multi-user.target
Alex
fonte

Respostas:

12

Você pode usar PartOfna [Unit]seção

Exemplo: PartOf=B.service

Na página do manual,

PartOf =

Configura dependências semelhantes a Requer =, mas limitadas à parada e reinicialização de unidades. Quando systemd para ou reinicia as unidades listadas aqui, a ação é propagada para esta unidade. Observe que essa é uma dependência unidirecional - as alterações nesta unidade não afetam as unidades listadas.

Thushi
fonte
Obrigado, eu estava analisando, Overriding vendor settingsmas isso parece ainda mais fácil e promissor, apenas a exceção é que eu não quero Aparar se Bparar, apenas A.restartse B.start, de qualquer maneira, eu fizer algum teste em breve e ver se há alguma maneira de gerenciá-lo, então vai deixar você saber
Alex
@ Alex: E se você usar PartOfe Restart=alwaysjuntos?
Thushi
Eu estou olhando para Restart=a documentação, eu não tenho certeza qual é o comportamento com oneshotserviços, mas independentemente disso: When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restartedse eu entendi corretamente parar manualmente B pararia A
Alex
Bem, agora, a recompensa se auto-atribuiu para vencimento, @Thushi Agradeço seu esforço e a sugestão, mas PartOfnão é uma solução para a pergunta, aproveite de qualquer maneira.
Alex
@ Alex: Bem, os pontos não são importantes para mim. Existem muitas outras maneiras de ganhar pontos. Eu só quero saber se a solução fornecida resolve seu problema. Caso contrário, trabalharemos mais nisso. Que tal usar PartOfcom Restart=always? Você tentou isso?
Thushi
3

Eu não tinha controle sobre stopcom PartOf=, e Anão deve parar com B, então acabei usando configurações de fornecedores Substituindo , parece funcionar.

/etc/systemd/system/B.service.d/override.conf

[Service]
ExecStart=
ExecStart=/bin/sh -c '/cmd start || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'
ExecReload=
ExecReload=/bin/sh -c '/cmd reload || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'

/cmda implementação é assíncrona e acessa um recurso que também /script.shprecisa ser acessado; não encontrei nada melhor (por enquanto) para dormir alguns segundos.

Eu tentei usar systemctl [--no-block] try-restartantes de usar /script.shdiretamente, mas não funcionou.

Alex
fonte
Também estou procurando uma solução para esse cenário. Poderia explicar um pouco mais esta solução? ou dê um link para alguns documentos para ler e entender o que você fez.
zappy
Olá, @zappy, procure o manual man systemd.unit(ou pesquise on-line se não estiver instalado) e procure o capítulo "Substituindo configurações do fornecedor".
Alex #
Obrigdo por sua contribuição. Entendo que você escolheu o método acima apenas porque o serviço B é específico de um fornecedor e não deseja editar esse arquivo de serviço. Mas, no meu caso, os serviços A e B não são fornecidos pelo fornecedor. Sinto que substituir isso pode adicionar complexidade ao sistema. Temos outras opções?
Zappy #
A questão tem alguns anos, você checou a documentação? Talvez esse cenário tenha sido coberto desde então. Na época, eu estava com pressa, mas com o tempo eu iria procurar a correspondência oficial systemd lista e pedir lá, eventualmente, abrir um problema
Alex
1

No momento, o systemd não cobre esse senario. Você não pode conseguir essa funcionalidade apenas com arquivos de serviço. Uma possibilidade é seqüestrar systemctl por meio de um script de shell com o mesmo nome e, nessa verificação, para verificar se o B.service está prestes a ser reiniciado ou recarregado, execute a ação apropriada com o A.service e, se necessário, atualize o rc.local para obter o estado adequado na inicialização também. Eu tenho esse problema com o docker.service e o networking.service, mas eu sempre os reinicio sempre:

systemctl reinicie o docker.service networking.service

Obviamente, isso não seria eficaz se o próprio systemd manipulasse B.service internamente (por exemplo, por meio de outros arquivos de serviço).

kaveh minooie
fonte