Можно ли написать службу 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, а не использовать этот механизм.)

Другие вопросы по тегам