Pretendo hospedar várias instâncias do mesmo aplicativo Web para clientes que estiverem usando systemd
. Eu gostaria de ser capaz de stop
e start
cada instância do cliente usando systemd
, bem como o tratamento de toda a coleção de instâncias do cliente como um único serviço que pode ser parado e iniciado em conjunto.
systemd
parece fornecer os blocos de construção que eu preciso usar PartOf
e os arquivos da unidade de modelo, mas fui eu paro o serviço pai, o serviço ao cliente filho não está parado. Como posso fazer isso funcionar com o systemd? Aqui está o que eu tenho até agora.
O arquivo da unidade pai app.service
:
[Unit]
Description=App Web Service
[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal
Um arquivo de modelo de unidade chamado [email protected]
, usado para criar instâncias do cliente:
[Unit]
Description=%I Instance of App Web Service
[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal
Meu app-poc.sh
script (Prova de conceito que apenas imprime no arquivo de log em um loop):
#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
echo "The App PoC loop for $@"
sleep 2;
done
Para a prova de conceito, eu tenho os arquivos da unidade systemd ~/.config/systemd/user
.
Em seguida, inicio o pai e uma instância com base no modelo (depois systemctl --user daemon-reload
):
systemctl --user start app
systemctl --user start [email protected]
Ao usar journalctl -f
, posso ver que ambos iniciaram e que a instância do cliente continua em execução. Agora eu espero que desligar o pai pare o filho (porque eu usei PartOf
), mas não. Além disso, iniciar o pai também não está iniciando o filho conforme o esperado.
systemctl --user stop app
Obrigado!
(Estou usando o Ubuntu 16.04 com systemd 229).
Requires=
?Respostas:
Você precisa mover a linha
fora
[Service]
e dentro da[Unit]
seção, e adicionar à[Unit]
daapp.service
lista de clientes para começar, por exemplo,ou como sourcejedi disse nos comentários,
Requires=
a mesma coisa. Você pode manter osPartOf
serviços para interromper, iniciados manualmente, que não estão na lista acima, comosystemctl --user start [email protected]
.fonte
PartOf
. Obrigado. Vou lidar com o "Quer" através de um link simbólico, que se torna a única ação que preciso executar para ativar um novo cliente com o systemd. Para o meu caso de teste: `ln -s /home/mark/.config/systemd/user/[email protected] / home / mark / .config / systemd / user / app.service.wants / unity @ foo.service`Aprendi que para isso servem as "Unidades de destino". Ao usar uma unidade de destino, recebo os benefícios que desejo sem precisar criar a
[Service]
seção falsa que tinha acima. Um exemplo prático de arquivo "Unidade de destino" se parece com isso:Em seguida, cada instância do cliente deve incluir
PartOf
na[Unit]
seção (como fora apontado por @meuh), e também deve ter uma[Install]
seção para queenable
edisable
vai trabalhar no serviço específico:Para abrir a instância do cliente e iniciar quando o destino é iniciado, este comando de ativação único é usado:
Agora, neste momento eu posso usar
stop
estart
emapp@customer
que para uma instância específica, ou posso usarstart app
estop app
parar todos os aplicativos juntos.fonte
systemctl status $(systemctl list-dependencies --plain otp.target)
systemd
poderia melhorar a usabilidade aqui. Eu abri um pedido de recurso para sugerir melhoria do estado para alvos.