Layanan Systemd Unit restart jika layanan lain mulai atau memuat ulang

16

Saya ingin tahu apakah ada cara Systemduntuk me-restart A.service( After) ketika B.servicememulai atau memuat ulang (hanya memuat konfigurasi), jika mungkin tanpa mengedit B.serviceyang diinstal dan ditingkatkan oleh sistem.

A.serviceharus dimulai meskipun B.servicetidak diinstal, dinonaktifkan, atau dihentikan.

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
Alex
sumber

Jawaban:

12

Anda dapat menggunakan PartOfdi [Unit]bagian ini.

Contoh: PartOf=B.service

Dari halaman manual,

Bagian =

Mengkonfigurasi dependensi mirip dengan Membutuhkan =, tetapi terbatas pada menghentikan dan memulai kembali unit. Ketika systemd berhenti atau me-restart unit yang terdaftar di sini, tindakan disebarkan ke unit ini. Perhatikan bahwa ini adalah ketergantungan satu arah - perubahan pada unit ini tidak mempengaruhi unit yang terdaftar.

Thushi
sumber
Terima kasih, saya sudah melihat ke dalam Overriding vendor settingstetapi ini terlihat lebih mudah dan menjanjikan, hanya pengecualian saya tidak ingin Aberhenti jika Bberhenti, hanya A.restartjika B.start, bagaimanapun saya akan segera melakukan tes dan melihat apakah ada cara untuk mengelolanya, maka akan memberi tahu Anda
Alex
@ Alex: Bagaimana jika Anda menggunakan PartOfdan Restart=alwaysbersama?
Thushi
Saya melihat Restart=dokumentasi, saya tidak yakin apa perilaku dengan oneshotlayanan, tetapi terlepas dari:, When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restartedjika saya mengerti dengan benar, menghentikan B akan menghentikan A
Alex
Nah sekarang, hadiah otomatis yang diberikan sendiri untuk kedaluwarsa, @Thushi Saya menghargai usaha dan saran Anda tetapi PartOfbukan solusi untuk pertanyaan itu, selamat menikmati.
Alex
@ Alex: Yah, Poin tidak penting bagi saya. Ada banyak cara lain saya bisa mendapatkan poin. Saya hanya ingin tahu apakah solusi yang disediakan menyelesaikan masalah Anda. Jika tidak, kami akan mengerjakannya lebih lanjut. Bagaimana kalau menggunakan PartOfdengan Restart=always? Apakah Anda sudah mencobanya?
Thushi
3

Saya tidak punya kendali stopdengan PartOf=, dan Atidak boleh berhenti B, jadi saya akhirnya menggunakan pengaturan vendor Overriding , tampaknya berhasil.

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

/cmdimplementasi asynchronous dan mengakses sumber daya yang /script.shperlu mengakses juga, saya menemukan tidak ada yang lebih baik (untuk saat ini) untuk tidur beberapa detik.

Saya mencoba menggunakan systemctl [--no-block] try-restartsebelum menggunakan /script.shsecara langsung tetapi tidak berhasil.

Alex
sumber
Saya juga mencari solusi untuk skenario ini. Bisakah Anda jelaskan solusi ini sedikit lebih banyak? atau berikan tautan ke beberapa dokumen untuk membaca dan memahami apa yang telah Anda lakukan.
zappy
Hai @zappy, cari manual man systemd.unit(atau cari online jika tidak diinstal) dan cari bab "Mengesampingkan pengaturan vendor".
Alex
Terima kasih atas masukannya. Saya memahami bahwa Anda memilih metode di atas hanya karena layanan B adalah vendor spesifik dan Anda tidak ingin mengedit file layanan itu. Namun dalam kasus saya, layanan A dan B bukanlah vendor yang dikirimkan. Saya merasa overriding dapat menambah kompleksitas ke sistem. Apakah kita punya opsi lain?
zappy
Pertanyaannya adalah beberapa tahun, apakah Anda memeriksa dokumentasinya? Mungkin skenario ini sudah dibahas sejak itu. Pada saat itu saya sedang terburu-buru tetapi mempunyai waktu saya akan mencari mailing list resmi systemd dan bertanya di sana, akhirnya membuka masalah
Alex
1

Saat ini systemd tidak membahas senario ini. Anda tidak dapat mencapai fungsi ini hanya melalui file layanan. Satu kemungkinan adalah untuk membajak systemctl melalui skrip shell dengan nama yang sama dan di cek itu untuk melihat apakah B.service akan kembali / dimulai atau dimuat ulang, lakukan tindakan yang sesuai dengan A.service juga, dan jika perlu perbarui rc.local untuk mendapatkan status yang tepat saat boot juga. Saya memiliki masalah ini dengan docker.service dan networking.service, tapi saya selalu me-restart bersama:

systemctl restart docker.service networking.service

Jelas, ini tidak akan efektif jika systemd itu sendiri memanipulasi layanan B. secara internal (misalnya melalui file layanan lainnya.).

kaveh minooie
sumber