У меня есть несколько служб 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
вопросов в будущем.