systemd oneshot Требование выполнить только один раз

systemd oneshot Требование выполнить только один раз

У меня есть несколько служб systemd, которым требуется сгенерированный EnvironmentFile. У меня есть скрипт оболочки, который генерирует этот файл Environment, но так как мне нужен этот файл environmentдолюбые команды Exec... выполняются, я не могу использовать ExecStartPre=generate_env_file.sh . Поэтому у меня есть другая служба (generate_env_file.service), настроенная на запуск этого скрипта как oneshot:

[Service]
Type=oneshot
ExecStartPre=/usr/bin/touch /path/to/config.ini
ExecStart=/path/to/generate_env_file.sh

и у меня есть несколько других служебных файлов, которые содержат:

[Unit]
Requires=generate_env_file.service
After=generate_env_file.service

Как я могу гарантировать, что две или более зависимых служб (которые требуют generate_env_file.service) не будут работать параллельно и не породят два параллельных выполнения generate_env_file.service?

Я рассматривал возможность использования RemainAfterExit=true или, возможно, StartLimitIntervalSec= и StartLimitBurst=, чтобы гарантировать, что только одна копия будет выполняться в определенный период времени, но я не уверен, что это лучший способ сделать это.

решение1

RemainAfterExit=trueэто путь. В этом случае Systemd запускает службу и считает ее запущенной и работающей. Однако это не покрывает вариант использования выполнения systemctl restart generate_env_file.service. В этом случае systemd повторно выполнит вашу службу. Чтобы решить эту проблему, вы можете создать файл маркера в файловой системе run ExecStartPost=и добавитьConditionPathExists=директива для проверки существования файла.

решение2

ConditionFirstBootТакже может быть интересно:

Принимает логический аргумент. Это условие может использоваться для обусловливания единиц на предмет того, загружается ли система в первый раз. Это примерно означает, что /etc/не было заполнено, когда система начала загружаться (подробнее см. «Семантика первой загрузки» в идентификатор машины(5)). Первая загрузка считается завершенной (это условие будет оценено как ложное) после того, как менеджер завершит фазу запуска.

Это условие может использоваться для заполнения /etc/при первой загрузке после сброса к заводским настройкам или при первой загрузке нового экземпляра системы.

Для надежности блоки с ConditionFirstBoot=yesдолжны упорядочить себя до first-boot-complete.targetи подтянуть эту пассивную цель с Wants=. Это гарантирует, что в случае прерывания первой загрузки эти блоки будут повторно запущены во время следующего запуска системы.

Если systemd.condition-first-boot=опция указана в командной строке ядра (принимая логическое значение), она переопределит результат этой проверки условия, имея приоритет над /etc/machine-id проверками существования.

решение3

Обновление generate_env_file.shдля проверки наличия файла блокировки сразу после запуска. Если файл блокировки существует, немедленно выйдите.

Если файла блокировки не существует, немедленно измените его, затем приступайте к созданию файла конфигурации, а затем удалите файл блокировки.

Другими словами, я не думаю, что systemdсуществует собственный способ обработки ситуации, которую вы описываете, через конфигурацию, поэтому используйте файл блокировки.

И как отмечает @shellter, сайт Unix — более подходящее место для systemdвопросов в будущем.

Связанный контент