Написание apply-скрипта¶
В парадигме, используемой фреймворком ram
для написания конфигурационных юнитов
действия сохранения настроек (store) и применения настроек (apply) разделены.
Смысл действия apply
– примененить сохраненную конфигурацию к запущенной системе без перезагрузки.
Чаще всего это означает перезапуск соответствующих сервисов.
Для удобства действия apply
могут быть реализованы с помощью языка сценариев shell.
1) Перезапуск сервисов:¶
В качестве первоначальной реализации сервиса apply
можно использовать скрипт безусловно перезапускающий нужный сервис.
Например, в системе CentOS-6 сервисы sshd
и network
управляются скриптами sysv с помощью утилиты service
.
Соответсвенно, скрипты apply
для этих сервисов могут быть реализованы следующим образом:
#!/bin/sh
service sshd restart
#!/bin/sh
service network restart
В системе CentOS-7 большинство сервисов управляется с помощью systemd.
Тем не менее, systemd поддерживает совместимость и предоставляет команду service
.
2) Перезапуск в зависимости от состояния:¶
Иногда возникают ситуации, когда конфигурация сервиса была изменена, однако на момент изменения конфигурации сервис был выключен. Это могло произойти в результате ручной остановки сервиса для отладки или на постоянной основе для сокращения потребления ресурсов.
В зависимости от реализации sysv-скрипта для такого сервиса выполнение команды restart
может привести
либо к ошибке, либо к невостребованному запуску сервиса.
Для исключения таких ситуаций рекомендуется использовать команду condrestart
соответствующего sysv-скрипта:
#!/bin/sh
service sshd condrestart
В случае, если в sysv-скрипте нужного сервиса поддержка команды condrestart
не реализована,
можно воспользоваться командой status
:
#!/bin/sh
if service sshd status; then
service sshd restart
fi
В случае же, если в sysv-скрипте нужного сервиса не реализована поддержка команды condrestart
и команды status
–
следует проанализировать реализацию сервиса, чтобы определить признаки работы сервиса.
Например, в системе CentOS-6 сервис network
, хоть и имеет поддержку команды status
,
последняя не позволяет понять был ли сервис включен или выключен.
При этом реализация sysv-скрипта создает файл /var/lock/subsys/network
при запуске сервиса и удаляет его при останове.
Т.о. для проверки состояния сервиса network
можно воспользоваться проверкой наличия этого файла:
#!/bin/sh
if [ -f /var/lock/subsys/network ]; then
service network restart
fi
В системе CentOS-7 сервис network
по прежнему реализован в качестве sysv-скрипта и этот код остается функциональным.
Однако большинство демонов теперь управляются через systemd юниты.
Создание файлов в /var/lock/subsys/ для таких демонов не практикуется.
В качестве более переносимого механизма можно ориентироваться на pid-файлы нужных демонов.
Для некоторых systemd юнитов потребуются правки для включения pid-файлов.
3) Перезапуск в зависимости от измениний:¶
Другим аспектом, который следует принять во внимание при написании скриптов apply
–
избыточность перезапуска сервисов в том случае, если конфигурация фактически не была изменена.
Особенно важно учитывать этот аспект для сервисов, работа которых не должна прерываться без необходимости.
Если нужный сервис поддерживает действие reload
(переконфигурация запущенного демона без перезапуска сервиса),
следует воспользоваться этой функциональностью:
#!/bin/sh
if service sshd status; then
service sshd reload
fi
Однако следует убедиться, что переконфигурация запущенного демона корректно работает во всех предусмотренных сценариях.
Если же нужный сервис не поддерживает действия reload
или реализация этого действия не удовлетворяет требованиям,
можно воспользоваться перезапуском сервиса предварительно проверив работает ли сервис с актуальной конфигурацией.
Для примера можно рассмотреть сервис network
и его конфигурационный файл – /etc/sysconfig/network
.
С помощью операций -ot
(older than)/-nt
(newer than) команды test
можно сравнить даты модификации двух файлов.
В случае сервиса network
дата модификации конфигурационного файла сравнивается с датой модификации файла /var/lock/subsys/network
, создаваемого при запуске сервиса:
#!/bin/sh
if [ -f /var/lock/subsys/network \
-a /var/lock/subsys/network -ot /etc/sysconfig/network ]; then
service network restart
fi
Следует принять во внимание, что если один из файлов в сравнении не существует – его время модификации принимается равным 0,
если же оба файла учавствующих в сравнении не существуют – результат сравнения будет не определен
(как -ot
, так и -nt
вернут ошибку).
Важно: проверка необходимости перезапуска сервиса на основе сравнения времени модификации конфигурационных файлов
накладывает дополнительные требования к реализации скриптов store
.
Следует реализовывать эти скрипты таким образом,
чтобы при отсутствии логических измений не происходило обновления конфигурационных файлов.
Стандартные классы для работы с файлами ini
и env
из библиотеки ram.formats
соответствуют этим требованиям.
На самом деле для конфигурации сервиса network
задействовано несколько конфигурационных файлов:
/etc/sysconfig/network
/etc/sysconfig/network-scripts/ifcfg-*
/etc/sysconfig/network-scripts/route-*
Т.о. для корректной проверки необходимости перезапуска сервиса нужно проверить их все:
Помимо файлов необходимо проверить также директорию /etc/sysconfig/network-scripts/
,
т.к. если какие-то из конфигурационных файлов были удалены – это отразится на времени изменения директории.
Следующий скрипт поочередно проверяет все указанные файлы, до тех пор пока не будет найден хотя бы один удовлетворящий условию –
дата модификации конфигурационного файла больше чем дата модификации файла /var/lock/subsys/network
.
Если такой файл будет найден, сервис network
будет перезапущен:
#!/bin/sh
if [ ! -f "/var/lock/subsys/network" ]; then
exit 0
fi
for file in /etc/sysconfig/network \
/etc/sysconfig/network-scripts/ \
$(find /etc/sysconfig/network-scripts/ \
-name 'ifcfg-*' -o -name 'route-*'); do
if [ "/var/lock/subsys/network" -ot "${file}" ]; then
service network restart
break
fi
done
4) Послесловие¶
В этом документе описаны методики написания скриптов apply
при использовании скриптов управления сервисами на основе sysv.
Тем не менее описанные методики будут актуальны и для других систем управления сервисами (upstart, systemd, monit, …).
В общем случае следует стремиться к тому, чтобы перезапуск сервисов учитывал текущее состояние сервиса и фактическое изменений конфигурационных файлов.
Помимо этого, рекомендуется не плодить скрипты apply
управляющие одним и тем же сервисом в разных юнитах,
вместо этого рекомендуется написать скрипт обрабатывающий все аспекты управления нужным сервисом
и задейстовать его в конкретных юнитов с помощью символических ссылок или вложенного вызова apply
.