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.
Связанные понятия
Полезные ресурсы
🔤 Английские термины в этой теме
Слова из этой темы, которые русскоязычные часто произносят неверно. Кнопка 🔊 произносит голосом браузера.
- idempotent /ˌaɪdɛmˈpoʊtənt/ ударение на третий слог разбор: Немые буквы и ударение: cache, queue, suite, height
- actual /ˈæktʃuəl/ «экчуэл», не «актуал» разбор: Ложные друзья: actual, data, accurate, control
- repository /rɪˈpɒzɪtəri/ ударение на «по», четыре слога, а не «репозитОри» разбор: Где встречается: код, доки, тикеты, созвоны
- tutorial /tjuːˈtɔːriəl/ «тьютОриэл» разбор: Читаем документацию, RFC и changelog
- database /ˈdeɪtəbeɪs/ «дЕйтабейс», ударение на первый слог разбор: Английский баз данных и бэкенда