Рейтинг:3

Почему мой системный таймер срабатывает только один раз, когда юнит является целью?

флаг jp

У меня есть несколько сервисов (генераторы статических сайтов), которые я хочу регулярно запускать с одного и того же системного таймера. я нашел этот вопрос/ответ, который описывает именно то, что я хочу сделать, и описывает установку, посредством которой .цель файл, который Хочет= несколько служб запускаются соответствующим таймером. Звучит здорово, но я обнаружил, что когда я на самом деле настраиваю это, он всегда срабатывает однажды, затем отключается!

Я подготовил минимальный рабочий пример (это не запускает несколько служб, но демонстрирует ту же проблему):

тест-timer.timer:

[Ед. изм]
Description=Таймер тестирования

[Таймер]
OnCalendar=*-*-* *:*:30
Unit=test-timer.target

[Установить]
WantedBy=timers.target

тест-timer.target:

[Ед. изм]
Описание=Целевой блок
Хочет = test-timer.service
После=test-timer.service

[Установить]
WantedBy=timers.target

тест-timer.service:

[Ед. изм]
Описание=Выполнить тест

[Оказание услуг]
ExecStart=/usr/bin/bash -c "date --rfc-3339='seconds' >> /tmp/test-timer-output"

[Установить]
Также=test-timer.target

Включите таймер:

$ sudo cp test-timer.* /etc/systemd/system/
$ sudo systemctl enable --now test-timer.timer
Создал символическую ссылку /etc/systemd/system/timers.target.wants/test-timer.timer — /etc/systemd/system/test-timer.timer.

Затем, когда я смотрю на вывод systemctl список-таймеры --все, до первого запуска я получаю (игнорируя другие таймеры):

СЛЕДУЮЩИЙ СЛЕВА ПОСЛЕДНИЙ ПРОЙДЕННЫЙ БЛОК АКТИВИРУЕТСЯ
Пт 2021-10-08 10:38:30 EDT Осталось 21 с н/д н/д test-timer.timer test-timer.target

После первого запуска, СЛЕДУЮЩИЙ и ОСТАВИЛ были заменены на н/д:

СЛЕДУЮЩИЙ СЛЕВА ПОСЛЕДНИЙ ПРОЙДЕННЫЙ БЛОК АКТИВИРУЕТСЯ
н/д н/д Пт 2021-10-08 10:38:32 EDT 1мин 5с назад test-timer.timer test-timer.target

Я также пытался добавить Постоянный = истина к тест-timer.target и явное включение тест-timer.target, но ни один из них не работает. В любое время я делаю systemctl перезапустить test-timer.timer, он перезапускается, но запускает только один запуск, а затем больше никогда не запускается.

Если я уберу слой косвенности, изменив Единица = линия тест-timer.timer к Unit=test-timer.service, служба радостно запускается каждую минуту, как и ожидалось.

Я пропустил какой-то этап настройки или установки?

Рейтинг:3
флаг jp

Получив некоторую помощь в Твиттере, мне удалось решить эту проблему. Проблема в том, что systemd таймер будет активировать только неактивные службы, а поведение по умолчанию для цель заключается в том, чтобы активироваться и оставаться активным, если что-то не заставит его выйти из строя (это не привязано к сроку службы юнитов, которые он Хочет=). Чтобы заставить целевой юнит стать неактивным, если Любые услуг, которые он активирует, становится неактивным, используйте привязки к = на месте Хочет= в моем примере выше. Итак, для этого минимального примера:

тест-timer.target:

[Ед. изм]
Описание=Целевой блок
BindsTo=test-timer.service
После=test-timer.service

[Установить]
WantedBy=timers.target

тест-timer.service:

[Ед. изм]
Описание=Выполнить тест

[Оказание услуг]
ExecStart=/usr/bin/bash -c "date --rfc-3339='seconds' >> /tmp/test-timer-output"

[Установить]
Также=test-timer.target

Затем вы можете увидеть, что, как только тест-timer.service закончен бег, тест-timer.target также станет неактивный (и, таким образом, таймер сможет активировать его снова):

$ sudo systemctl list-units --all test-timer.target test-timer.service
  ЕДИНИЧНАЯ НАГРУЗКА АКТИВНА ПОД ОПИСАНИЕ
  test-timer.service загружен, неактивен, не работает Запустить тест   
  test-timer.target загружен неактивен мертв Целевой блок

Принимая во внимание, что до изменения цель оставалась активной после смерти службы:

$ sudo systemctl list-units --all test-timer.target test-timer.service
  ЕДИНИЧНАЯ НАГРУЗКА АКТИВНА ПОД ОПИСАНИЕ
  test-timer.service загружен, неактивен, не работает Запустить тест   
  test-timer.target загружен активен активен Целевой блок
флаг za
Дагнаббит, ты нашел решение, прежде чем я смог его опубликовать :-)
karlsebal avatar
флаг in
В особенности, когда у вас есть несколько сервисов, запущенных целью, и все они являются одноразовыми, вы можете использовать StopWhenUnneeded=True. Это приведет к тому, что цель станет неактивной после того, как работа будет выполнена.
флаг ma
Похоже, `StopWhenUnneeded=` работает лучше, чем `BindsTo=`. С последним я получил сообщение об ошибке «xxx.target: привязан к единице yyy.service, но единица не активна» всякий раз, когда цель активирована.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.