Можно ли написать службу systemd, которая запускается при запуске другой службы?
Кажется, это должен быть очень простой вопрос, но мне не удалось его понять. У меня есть сервис «Алиса»:
[Unit]
Description=Alice
After=network.target
[Service]
Type=simple
Restart=on-failure
RestartSec=5
StartLimitInterval=0
ExecStart=sleep 30d
[Install]
WantedBy=multi-user.target
Я хотел бы написать второй сервис Bob такой, чтобы:
- Боб начинает, когда Алиса успешно стартовала
- Боб запускается, потому что и только потому, что Алиса запустилась успешно (не вызванная запуском системы или другой активностью)
- Боб останавливается, когда Алиса останавливается
Я хотел бы добиться этого, не изменяя Алису. Алису иногда можно запустить в системе (черезsystemctl enable alice.service
), а в других ситуациях запускался только вручную. На практике будет N-много дополнительных сервисов (Carol, Dave, Eve, ..) со своими собственными файлами модулей, которые все должны быть запущены при запуске Алисы, и N может стать довольно большим числом.
Я экспериментировал с различными настройками Unit, такими как PartOf, BoundTo, Requires, After, и ни одна комбинация, которую я пробовал до сих пор, не достигла желаемого результата - запуска Боба путем запуска Алисы. Я также обнаружил, что вызовsystemctl show bob.service
показывает ожидаемые настройки после запускаsystemctl daemon-reload
, но обратные настройки (ConsistsOf, BoundBy, RequiredBy) не отображаются вsystemctl show alice.service
с явным нарушением документации .
Я не вижу ошибок в системном журнале при вызове daemon-reload или при запуске Алисы, что могло бы объяснить, почему Боб не запускается.
Возможно ли сделать то, что я хочу? Если да, то как мне устранить такую проблему? Кстати, я провожу эти эксперименты на RHEL 8.7 и systemd 239.
1 ответ
Возможный ответ.
Похоже, что пока я не могу ничего настроить только для Боба, что привело бы к запуску Боба одновременно с запуском Алисы. Итак, если это правда, то я вообще не могу сделать это без изменения Alice, но похоже, что я, по крайней мере, могу сделать это без изменения alice.service. В моем случае это может быть достаточным решением.
Раздел «Отряд Боба»:
[Unit]
Description=Bob
After=network.target
After=alice.service
PartOf=alice.service
Затем я модифицирую Алису через Drop-In, создавая символическую ссылкуalice.service.requires/bob.service
указывая на bob.service.
Пока что это, кажется, делает именно то, что я хочу - если есть причины избегать этого подхода, я их еще не обнаружил. ПокаPartOf
не заставляет Алису запускать Боба без символической ссылки Requires, это заставляет Боба останавливаться, когда Алиса останавливается (это не происходит без символа Requires).PartOf=alice.service
параметр).
Таким образом, в конечном итоге процедура установки для Боба (программного компонента, над которым я работаю) добавит этот шаг для создания символической ссылки в конце (как и Кэрол и т. д.).
РЕДАКТИРОВАТЬ: Я только что понял, что systemd предоставляет именно эту функциональность, хотя я могу ее использовать, а могу и не использовать. Из bob.service удаляюWantedBy=multi-user.target
из раздела [Установить] и замените его на Алиса:
[Install]
RequiredBy=alice.service
Впоследствии я могу использоватьsystemctl enable bob.service
поскольку это не приведет к запуску Боба при загрузке, а только при запуске Алисы. Он создает описанную выше символическую ссылку в /etc. (Мой установщик в любом случае может сделать это вручную в /usr/lib, а не использовать этот механизм.)