Bisakah saya menggunakan systemd untuk memulai dan menghentikan layanan berdasarkan keberadaan file?

9

Konfigurasi saya sejauh ini adalah:

foo.path

[Path] 
PathExists=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

layanan

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

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

Ini berfungsi dengan baik ketika memulai tetapi layanan foo.ser tidak akan terbunuh ketika /tmp/foo.path dihapus. Apakah ada cara untuk membuat systemd melakukan ini atau itu bukan alat yang tepat untuk pekerjaan itu?

mpr
sumber

Jawaban:

4

Saya akan mencoba ini. Buat layanan tambahan menggunakan PathChanged:

foo-stop.path

[Path] 
PathChanged=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

Kemudian buat: foo-stop.service

Mintalah skrip "ExecStart" untuk melihat apakah /tmp/foo.pathtelah dihapus (karena PathChanged juga dapat menjalankan perubahan lain). Jika jalur telah dihapus, minta panggilan skrip /bin/systemctl stop foo.

Mark Stosberg
sumber
1
Saya akan pergi ke depan dan menerima ini sampai waktu yang systemd menawarkan opsi eksplisit untuk melakukan hal yang sama.
mpr
0

Jika Anda dapat mematikan proses yang terikat ke PIDFile (/run/foo.pid) ketika /tmp/foo.path dihapus (misalnya, keduanya sebagai tindakan di dalam skrip shutdown layanan), maka ya.

Saya mencapainya pada Tomcat yang menjalankan <= RHEL-7.7 dengan layanan forking termasuk tindakan ExecStartPost yang mencatat konten aplikasi pidfile (catalina.pid) ke dalam jalur layanan PIDFile. "PathExists" dalam file .path yang sesuai melacak kemunculan pada catalina.pid ini untuk mengaitkan layanan systemd ketika pengguna (dalam kasus saya, yang tidak terjangkau) meminta skrip startup. Ketika pengguna meluncurkan shutdown, aplikasi pidfile dihapus, PID (juga unprivileged) mati dengan anggun, dan systemd menghentikan layanan sebagai systemd pid mengawasi konsekuensi.

layanan poc:

[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
# . . .

Cara ini juga membantu saya untuk aplikasi Spring Boot. Tetapi ketika mereka lahir tergantung pada proses bash, saya harus segera membunuh proses induk untuk memaksa PID 1 menjadi orangtua aplikasi. Jika tidak, journalctl menampilkan pesan "* .service: Proses pengawasan XXXXX yang bukan anak kami. Kami kemungkinan besar tidak akan melihat ketika keluar.", Dan pada akhirnya layanan systemd tidak berhenti pada tindakan mematikan pengguna.

Pere Moltó
sumber