Riavvio del servizio unità di sistema se un altro servizio viene avviato o ricaricato


16

Mi piacerebbe sapere se c'è un modo Systemdper riavviare A.service( After) quando B.servicesi inizia o si ricarica (ricaricare solo la configurazione), se possibile senza modificare B.servicequale è installato e aggiornato dal sistema.

A.servicedovrebbe iniziare anche se B.servicenon è installato, disabilitato o arrestato.

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

Risposte:


12

È possibile utilizzare PartOfnella [Unit]sezione.

Esempio: PartOf=B.service

Dalla pagina man,

ParteDi =

Configura dipendenze simili a Richiede =, ma limitato all'arresto e al riavvio delle unità. Quando systemd arresta o riavvia le unità elencate qui, l'azione viene propagata a questa unità. Si noti che questa è una dipendenza a senso unico: le modifiche a questa unità non influiscono sulle unità elencate.


Grazie, lo stavo esaminando, Overriding vendor settingsma sembra ancora più facile e promettente, l'unica eccezione è che non voglio Afermarmi se Bsmetto, solo A.restartse B.startcomunque farò qualche test presto e vedrò se c'è un modo per gestirlo, quindi ti farò sapere
Alex

@Alex: cosa succede se si utilizza PartOfe Restart=alwaysinsieme?
Thushi,

Sto guardando la Restart=documentazione, non sono sicuro di quale sia il comportamento con i oneshotservizi, ma a prescindere: When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restartedse capisco correttamente l'arresto manuale B fermerebbe A
Alex

Bene, ora la taglia si è auto-assegnata per la scadenza, @Thushi apprezzo il tuo sforzo e il suggerimento, ma PartOfnon è una soluzione per la domanda, goditi comunque.
Alex,

@Alex: Bene, i punti non sono importanti per me. Ci sono molti altri modi in cui posso guadagnare punti. Voglio solo sapere se la soluzione fornita risolve il problema. In caso contrario, ci lavoreremo ulteriormente. Che ne dici di usare PartOfcon Restart=always? Ci hai provato?
Thushi,

3

Ho avuto alcun controllo su stopcon PartOf=, e Anon deve fermarsi con B, così ho finito per usare le impostazioni vendor Override , sembra funzionare.

/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'

/cmdl'implementazione è asincrona e accedi a una risorsa a cui è /script.shnecessario accedere anche io, non ho trovato niente di meglio (per ora) per dormire pochi secondi.

Ho provato a utilizzare systemctl [--no-block] try-restartprima di utilizzare /script.shdirettamente ma non ha funzionato.


Sto anche cercando una soluzione per questo scenario. Potresti spiegare questa soluzione un po 'di più? o dai un link ad alcuni documenti per leggere e capire cosa hai fatto.
zappy

Ciao @zappy, cerca il manuale man systemd.unit(o cercalo online se non è installato) e cerca il capitolo "Sostituzione delle impostazioni del fornitore".
Alex

Grazie per il tuo contributo. Comprendo che si sceglie il metodo sopra solo perché il servizio B è specifico di un fornitore e non si desidera modificare quel file di servizio. Ma nel mio caso entrambi i servizi A e B non sono forniti dal fornitore. Sento che può essere complicato per il sistema. Abbiamo altre opzioni?
zappy

La domanda ha un paio d'anni, hai controllato la documentazione? Forse questo scenario è stato coperto da allora. All'epoca avevo fretta ma, avendo tempo, cercavo la mailing list ufficiale di systemd e chiedevo lì, alla fine avrei aperto un problema
Alex,

1

Al momento systemd non copre questo senario. Non è possibile ottenere questa funzionalità solo tramite i file di servizio. Una possibilità è quella di dirottare systemctl tramite uno script shell con lo stesso nome e in quel controllo per vedere se B.service sta per essere riavviato o riavviato, eseguire anche le azioni appropriate con A.service e, se necessario, aggiornare il rc.local per arrivare allo stato corretto anche all'avvio. Ho questo problema con docker.service e networking.service, ma li riavvio sempre insieme:

systemctl restart docker.service networking.service

Ovviamente, ciò non sarebbe efficace se il sistema stesso manipolasse B.service internamente (ad es. Tramite altri file di servizio).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.