Requisites: require и watch
Тема дорожной карты · SaltStack
Requisites — это механизм зависимостей между состояниями: они превращают плоский список состояний в граф, где порядок и реакции заданы явно. Хотя Salt исполняет состояния в порядке их объявления, полагаться на это при росте кодовой базы нельзя — include, формулы и рефакторинг легко ломают неявный порядок. Четыре основных requisites: require («выполняй меня только после успешного X»), watch («как require, плюс отреагируй, если X изменился»), onchanges («выполняй меня, только если X что-то изменил») и onfail («выполняй меня, только если X упал»). Освоив их, вы описываете не просто набор состояний, а поведение системы при изменениях — перезапуски сервисов, миграции, оповещения об ошибках.
Как это работает
Requisite указывает на другое состояние парой «модуль: ID (или name)». Канонический пример — перезапуск сервиса при изменении конфига:
nginx_conf:
file.managed:
- name: /etc/nginx/nginx.conf
- source: salt://nginx/files/nginx.conf
nginx_service:
service.running:
- name: nginx
- require:
- pkg: nginx_pkg
- watch:
- file: nginx_conf
require гарантирует порядок и отменяет зависимое состояние, если зависимость упала. watch делает то же самое, а если наблюдаемое состояние вернуло непустой changes, дополнительно вызывает у модуля функцию mod_watch — у service это перезапуск: конфиг не менялся — nginx работает дальше, изменился — перезапустится. onchanges похож на watch, но без реакции модуля: зависимое состояние просто пропускается, если изменений не было, — удобно для «запусти миграцию, только если обновился код». onfail включает состояние только при падении зависимости — из него строят компенсирующие действия и алерты. У каждого requisite есть зеркальная форма *_in (require_in, watch_in, onchanges_in, onfail_in): зависимость объявляется с другой стороны — «я требуюсь для X». Это удобно в формулах, когда нельзя править чужое состояние, но нужно встроиться в его граф.
Когда применять
require — базовый инструмент: пакет до сервиса, каталог до файла, репозиторий до пакета; ставьте его везде, где порядок важен по смыслу, даже если сейчас он совпадает с порядком в файле. watch — стандарт для пары «конфиг + сервис»; это самый частый requisite в реальных формулах. onchanges выбирайте для дорогих или небезопасных действий, которые должны идти строго за фактическим изменением: миграции БД, сборка, очистка кэша. onfail — для реакции на сбой: откат, уведомление, запасной вариант. Формы *_in применяйте точечно — обычно при расширении чужих формул; в собственном коде прямые формы читаются легче, потому что зависимость видна там, где она действует.
Типичные ошибки
Самая частая ошибка — неверная ссылка: в requisite указывается пара «модуль: ID», и опечатка в любом из двух даёт ошибку «Requisite … not found»; если у состояния задан name, ссылаться можно и на него, но проще держать стабильные ID. Циклические зависимости (A require B, B require A) валят компиляцию всего прогона. watch на состоянии, чей модуль не имеет mod_watch, ведёт себя просто как require — перезапуска «сам собой» не произойдёт. Ещё один тонкий момент: watch реагирует на любой непустой changes, поэтому неидемпотентный cmd.run в зависимостях будет дёргать перезапуск сервиса при каждом прогоне highstate.
Связанные понятия
Полезные ресурсы
Проверить знания (2)
Загрузка вопросов…