Como iniciar e parar uma unidade systemd com outra?

20

Estou usando o CoreOS para agendar unidades systemd com frota. Eu tenho duas unidades ( firehose.servicee firehose-announce.service. Estou tentando firehose-announce.serviceiniciar e parar firehose.serviceo arquivo. Aqui está o arquivo da unidade para firehose-announce.service:

[Unit]
Description=Firehose etcd announcer
BindsTo=firehose@%i.service
After=firehose@%i.service
Requires=firehose@%i.service

[Service]
EnvironmentFile=/etc/environment
TimeoutStartSec=30s
ExecStartPre=/bin/sh -c 'sleep 1'
ExecStart=/bin/sh -c "port=$(docker inspect -f '{{range $i, $e := .NetworkSettings.Ports }}{{$p := index $e 0}}{{$p.HostPort}}{{end}}' firehose-%i); echo -n \"Adding socket $COREOS_PRIVATE_IPV4:$port/tcp to /firehose/upstream/firehose-%i\"; while netstat -lnt | grep :$port >/dev/null; do etcdctl set /firehose/upstream/firehose-%i $COREOS_PRIVATE_IPV4:$port --ttl 300 >/dev/null; sleep 200; done"
RestartSec=30s
Restart=on-failure

[X-Fleet]
X-ConditionMachineOf=firehose@%i.service

Eu estou tentando usar BindsTocom a noção de que iniciar e parar firehose.servicetambém irá iniciar ou parar firehose-announce.service. Mas isso nunca acontece corretamente. Se firehose.serviceestiver parado, firehose-announce.servicepassa ao estado de falha. Mas quando eu começo firehose.service, o firehose-announce.servicenão inicia.

O que eu estou fazendo errado aqui?

Andy Shinn
fonte
Mesmo problema aqui. Você encontrou uma solução?
nahime

Respostas:

24

Parece que finalmente encontrei a combinação correta para fazer isso funcionar como desejado.

Na minha firehose-announce.serviceunidade, apenas defino a BindsTo. Toda a unidade é:

[Unit]
Description=Firehose etcd announcer
BindsTo=firehose@%i.service

[Service]
EnvironmentFile=/etc/environment
TimeoutStartSec=30s
ExecStartPre=/bin/sh -c 'sleep 1'
ExecStart=/bin/sh -c "port=$(docker inspect -f '{{range $i, $e := .NetworkSettings.Ports }}{{$p := index $e 0}}{{$p.HostPort}}{{end}}' firehose-%i); echo -n \"Adding socket $COREOS_PRIVATE_IPV4:$port/tcp to /firehose/upstream/firehose-%i\"; while netstat -lnt | grep :$port >/dev/null; do etcdctl set /firehose/upstream/firehose-%i $COREOS_PRIVATE_IPV4:$port --ttl 300 >/dev/null; sleep 200; done"
RestartSec=30s
Restart=on-failure

[X-Fleet]
X-ConditionMachineOf=firehose@%i.service

Isso fará com que a firehose-announce.serviceunidade pare quando parar firehose.service. Ótimo. Mas como começamos de novo?

Eu inverto a dependência de estar na minha firehose.serviceunidade da seguinte forma:

[Unit]
Description=Firehose server
Wants=firehose-announce@%i.service
Before=firehose-announce@%i.service

[Service]
ExecStartPre=/usr/bin/docker pull firehose/server
ExecStartPre=-/usr/bin/docker rm -f firehose-%i
ExecStart=/usr/bin/docker run --name firehose-%i -p 7474 --env-file /home/core/firehose.env firehose/server
ExecStop=/usr/bin/docker rm -f firehose-%i
User=core
TimeoutStartSec=5m
TimeoutStopSec=20s
RestartSec=30s
Restart=on-failure

[Install]
WantedBy=multi-user.target

[X-Fleet]
X-Conflicts=firehose@*.service

Isto está dizendo que firehose.servicequer firehose-announce.serviceiniciar quando isso acontecer (mas não falhe se firehose-announce.servicenão puder iniciar). Ele também garante que o processo seja firehose.serviceiniciado antes firehose-announce.service.

Testei isso e as unidades agora parecem parar e começar juntas, conforme desejado.

Andy Shinn
fonte
Ótimo, vou tentar.
Nahime 20/08
11
Aparentemente, quer = significa opcional. Requer = é um requisito. BindsTo significa que se a dependência, ou seja, serviço de mangueira de incêndio parar, o serviço de anúncio de mangueira de incêndio também será considerado parado. Parece uma coisa boa para mim.
Matt
É possível obter esse comportamento sem tocar em firehouse.service?
precisa saber é o seguinte
Eu tentei esta solução, mas estou enfrentando um problema. Eu tenho o serviço A com Requer = B.service e o serviço B com BindsTo = A.service. Quando A sai anormalmente, vejo A e B sendo reiniciados. Mas quando A sai com o código 0 / SUCESS, ambos permanecem no estado parado #
Killer Bug 7/16
ExecStartPre = {} traço 's -não servem de nada sobre o último e só servem propósito em todos, mas o último ExecStartPre
meffect