Posso usare systemd per avviare e arrestare un servizio in base alla presenza di un file?


9

La mia configurazione finora è:

foo.path

[Path] 
PathExists=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

foo.service

[Unit]
Description=Matt Test
BindsTo=foo.path

[Service]
ExecStart=/bin/sh /home/mpekar/bin/foo.sh 
PIDFile=/run/foo.pid

Funziona bene all'avvio ma foo.service non verrà ucciso quando /tmp/foo.path viene rimosso. C'è un modo per fare in modo che systemd faccia questo o non è lo strumento adatto per il lavoro?


Risposte:


4

Vorrei provare questo. Crea un servizio aggiuntivo usando PathChanged:

foo-stop.path

[Path] 
PathChanged=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

Quindi creare: foo-stop.service

Fai controllare lo script "ExecStart" per vedere se è /tmp/foo.pathstato eliminato (poiché PathChanged potrebbe attivarsi anche su altre modifiche). Se il percorso è stato rimosso, fare chiamare lo script /bin/systemctl stop foo.


1
Vado avanti e accetterò questo fino a un momento tale che systemd offrirà un'opzione esplicita per fare lo stesso.
martedì

0

Se si è in grado di terminare il processo associato al file PID (/run/foo.pid) quando /tmp/foo.path viene rimosso (ad esempio, entrambi come azioni all'interno dello script di arresto del servizio), sì.

L'ho raggiunto su un Tomcat che esegue <= RHEL-7.7 con un servizio di fork che include un'azione ExecStartPost che annota il contenuto dell'applicazione pidfile (catalina.pid) nel percorso PIDFile del servizio. Un "PathExists" nel corrispondente file .path rintraccia la visualizzazione su questo catalina.pid per agganciare il servizio systemd quando l'utente (nel mio caso, senza privilegi) invoca lo script di avvio. Quando l'utente avvia l'arresto, il pidfile dell'applicazione viene rimosso, il PID (anche senza privilegi) muore con grazia e systemd interrompe il servizio come conseguenza di supervisione del pid systemd.

poc.service:

[nouser@nohost system]# cat poc.service
# . . .
[Unit]
After=network.target
After=%p.path
Wants=%p.path
# . . . 
[Service]
Type=forking
Environment="%p_APPLICATION_PID_FILE=/opt/%p/logs/catalina.pid"
PIDFile=/var/run/%p.pid
ExecStart=/bin/sh -c '/path/to/tomcat/control/script/invoked/with/su/hypen start'
ExecStartPost=/bin/sh -c 'cat ${%p_APPLICATION_PID_FILE} > $(systemctl show %n -p PIDFile|cut -f2- -d"=")'
ExecStop=/bin/sh -c '/path/to/tomcat/control/script/invoked/with/su/hypen stop'
# . . .

poc.path:

[nouser@nohost system]# cat poc.path
# . . .
[Path]
PathExists=/opt/%p/logs/catalina.pid
# . . .

In questo modo mi è servito anche per le applicazioni Spring Boot. Ma poiché sono nati appesi a un processo bash, ho dovuto interrompere immediatamente quel processo genitore per forzare PID 1 a essere il genitore dell'applicazione. In caso contrario, journalctl mostra un messaggio "* .service: supervisione del processo XXXXX che non è nostro figlio. Molto probabilmente non ci accorgeremo quando esce.", E alla fine il servizio systemd non si ferma all'azione di arresto dell'utente.

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.