Сервис Systemd Unit перезапускается, если другой сервис запускается или перезагружается

16

Я хотел бы знать, есть ли способ с помощью Systemdrestart A.service( After) при B.serviceзапуске или перезагрузке (только перезагрузить конфигурацию), если это возможно, без редактирования, B.serviceкоторое установлено и обновлено системой.

A.serviceдолжен запускаться, даже если B.serviceон не установлен, отключен или остановлен.

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
источник

Ответы:

12

Вы можете использовать PartOfв [Unit]разделе.

Пример: PartOf=B.service

С man-страницы,

PartOf =

Настраивает зависимости, подобные «Требуется =», но ограничивается остановкой и перезапуском юнитов. Когда systemd останавливает или перезапускает перечисленные здесь модули, действие распространяется на этот модуль. Обратите внимание, что это односторонняя зависимость - изменения в этом модуле не влияют на перечисленные модули.

Thushi
источник
Спасибо, я смотрел на Overriding vendor settingsэто, но это выглядит еще более легким и многообещающим, единственное исключение - я не хочу Aостанавливаться, если Bостановлюсь, просто A.restartесли B.start, в любом случае, я скоро проведу какой-нибудь тест и посмотрю, есть ли какой-то способ справиться с этим, тогда дам вам знать
Алекс
@ Алекс: Что делать, если вы используете PartOfи Restart=alwaysвместе?
Thushi
Я смотрю на Restart=документацию, я не уверен, каково поведение со oneshotслужбами, но независимо: When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restartedесли я правильно понимаю, остановка B вручную остановит A
Alex
Что ж, щедрость автоматически назначена на срок действия, @Thushi Я ценю ваши усилия и предложение, но PartOfэто не решение вопроса, все равно наслаждайтесь.
Алекс
@ Алекс: Ну, очки не важны для меня. Есть много других способов заработать очки. Я просто хочу знать, решает ли предоставленное решение вашу проблему. Если нет, мы будем работать над этим дальше. Как насчет использования PartOfс Restart=always? Вы пробовали это?
Thushi
3

Я не имел никакого контроля над stopс PartOf=, и Aне должны останавливаться B, так что я в конечном итоге с помощью Переопределение параметров поставщика , кажется, работает.

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

/cmdРеализация асинхронная и доступ к ресурсу, к которому /script.shтоже нужно обращаться, я не нашел ничего лучшего (пока), чтобы поспать несколько секунд.

Я пытался использовать systemctl [--no-block] try-restartперед использованием /script.shнапрямую, но не получилось.

Alex
источник
Я также ищу решение для этого сценария. Не могли бы вы объяснить это решение немного подробнее? или дайте ссылку на некоторые документы, чтобы прочитать и понять, что вы сделали.
zappy
Здравствуйте, @zappy, найдите руководство man systemd.unit(или найдите его в Интернете, если оно не установлено) и найдите главу «Переопределение настроек поставщика».
Алекс
Спасибо за ваш вклад. Я понимаю, что вы выбираете вышеуказанный метод только потому, что служба B зависит от поставщика, и вы не хотите редактировать этот файл службы. Но в моем случае и сервис A, и B не предоставляются поставщиком. Я чувствую, что переопределение может усложнить систему. У нас есть другие варианты?
Заппи
Вопрос пару лет, вы проверили документацию? Может быть, этот сценарий был рассмотрен с тех пор. В то время я спешил, но, имея время, я искал официальный список рассылки systemd и спрашивал там, в конце концов открывал вопрос
Alex
1

На данный момент systemd не охватывает этот senario. Вы не можете достичь этой функциональности только с помощью служебных файлов. Одна из возможностей состоит в том, чтобы перехватить systemctl с помощью сценария оболочки с тем же именем и в этой проверке, чтобы увидеть, собирается ли B.service быть перезапущен или перезагружен, также выполнить соответствующее действие с A.service и, если необходимо, обновить rc.local, чтобы получить правильное состояние при загрузке, а также. У меня есть эта проблема с docker.service и network.service, но я просто всегда перезапускаю их вместе:

systemctl перезапустить docker.service network.service

Очевидно, что это не будет эффективно, если сама systemd будет манипулировать B.service внутренне (например, через другие служебные файлы).

Kaveh Minooie
источник