Como iniciar e parar uma unidade do sistema com outro?

19

Estou usando o CoreOS para agendar unidades systemd com frota. Eu tenho duas unidades ( firehose.service e firehose-announce.service . Estou tentando obter o firehose-announce.service para iniciar e parar junto com o firehose.service . Aqui está o arquivo de 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

Estou tentando usar BindsTo com a noção de que o início e a parada de firehose.service também iniciarão ou interromperão firehose-announce.service . Mas isso nunca acontece corretamente. Se firehose.service for interrompido, firehose-announce.service irá para o estado com falha. Mas quando eu começo firehose.service , o firehose-announce.service não inicia.

O que estou fazendo de errado aqui?

    
por Andy Shinn 19.08.2014 / 22:27

1 resposta

23

Parece que eu finalmente encontrei a combinação correta para conseguir que isso funcionasse como desejado.

Na minha unidade firehose-announce.service , apenas defino BindsTo . A unidade inteira é:

[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 unidade firehose-announce.service pare quando firehose.service . Ótimo. Mas como podemos começar de novo?

Eu inverto a dependência para estar na minha firehose.service unidade assim:

[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

Isso está dizendo que firehose.service quer que firehose-announce.service inicie quando isso acontecer (mas não falhe se firehose-announce.service não puder ser iniciado). Ele também garante que firehose.service comece antes de firehose-announce.service .

Eu testei isso e as unidades parecem parar e começar juntas conforme desejado.

    
por 20.08.2014 / 16:55