Зачем ещё один гайд про NUT?

Гайдов по подключению и настройке бесперебойников, то бишь, UPS-ов к компьютеру с linux-ом на борту - тьма тьмущая. И я ни за что не стал бы писать этот текст, если бы не один единственный, но крайне существенный нюанс. Практически все они (по крайней мере, из предложенных гуглом) предлагают такой вариант настройки, при котором компьютер будет выключаться, лишь получив от ups-а сигнал о низком уровне заряда батарей. К сожалению, практика показывает, что с Ippon-ами такое если и работает, то только на новом бесперебойнике с новыми аккумуляторами. Да и то весьма часто, если компьютер и успевает заподозрить что что-то с зарядом батареи не так - на корректное завершение работы времени уже не остаётся.
Логичным выходом будет отключать системник, если он проработал от бесперебойника какое-то фиксированное (гарантированно безопасное) время и питание к этому моменту не восстановилось. Родные "драйвера", идущие с Ippon-ами - это вполне себе умеют. Но вот беда - "драйвер" представляет из себя службу\GUI-морду на Java, и если для рабочего компьютера с иксами и каким-нибудь гномом оно ещё куда ни шло, то для сервера такой вариант - как то совсем не алё :(. К счастью, поскольку речь о linux - у нас тут unix-way, а значит обязательно должна быть программа которая, что называется, мало что умеет, но то что умеет - делает хорошо. И такая программа для управления ups-ами действительно существует. Существует она не одна, но для Ippon-ов из имеющихся вариантов (насколько мне известно) подходит только NUT, он же Network UPS Tools.
И вот тут то подкрадывается основная закавыка. NUT, конечно, замечательный инструмент - тут тебе и сервер, и клиент, и мониторинг, и возможность рулить хоть одним хоть сотней компьютеров, чего он только не умеет... При должном понимании принципов его работы - позволяет настроить сколь угодно сложные реакции на происходящие с бесперебойником события. Однако все эти сложные реакции пользователь должен написать самостоятельно (хоть на сях, хоть на баше, хоть на питонах-перлах - главное чтобы исполнимый файл мог запустить NUT-овский демон и передать ему аргументы), такие дела. Настроить только через конфиги такую простую вещь как "отключиться после N секунд работы на батареях" в NUT невозможно, вероятно поэтому подобная настройка и не предлагается ни в типовых примерах из оригинальной документации, ни в существующих русскоязычных гайдах. Нужный нам функционал даже в родной документации NUT скупо и лишь в общих чертах расписан в разделе Advanced usage (желающие покурить первоисточник могут пройти по ссылке и осознать всё "из первых рук").
Этот гайд я решил разделить на несколько логических частей.

  • Во-первых - чтобы настроить всё правильно, крайне желательно понимать, как вообще работает NUT, где что настраивается, какой процесс что и в какой последовательности вызывает - просто потому что простого копипаста моего варианта настроек (работающего в Debian) может оказаться недостаточно в другом дистрибутиве или даже в другой версии Debian-а. Будет какой-нибудь файлик лежать чуть по другому пути и мозаика не сложится.
  • Во-вторых - зная как это всё функционирует в общих чертах уже можно представить как именно будет работать реальная наша конфигурация.
  • В третьих - раз уж мы понимаем что именно хотим - пора приступать к установке и настройке. Те, кто хотят просто повторить последовательность действий, без понимания их смысла - просто переходят к этому разделу, пропуская всё остальное. В Debian, скорее всего, оно будет работать.

Ну и последнее - в аббревиатуре NUT первая буква она не просто так - это действительно набор сетевых утилит, в первую очередь заточенный на управление большой кучей бесперебойников и питаемых ими компьютеров, объединённых в самых разных конфигурациях типа "1-2 бесперебойника на стойку из десятка серверов". Похоже, эта заточенность и объясняет отсутствие "из коробки" элементарного функционала, типичного для идущего в комплекте с ups-ами софта - у разработчиков голова болит о другом, а то что вместо истребителя при сборке получается паровоз - так в инструкции же написано - детали доработать напильником...

Что из себя представляют и как вообще работают Network UPS Tools.

В родной документации можно прочитать много-много умных букв, а также слов на эту тему, но нам важно знать, что в состав этого "сетевого набора утилит" входят следующие компоненты:

  1. сервер, питается картошкой %)
    Сервер, он же upsd. Как видно из названия - представляет из себя обычного демона (он же служба, он же сервис). Запускается он на том же компе, к которому физически (например по USB) подключён бесперебойник. В дебиане управляется скриптом /etc/init.d/nut-server. Настраивается конфигами: /etc/nut/upsd.conf, /etc/nut/upsd.users, /etc/nut/ups.conf. Но пути к конфигам NUT могут быть другими в другом дистрибутиве!
  2. Драйвер же!
    Драйверы. К ядру операционки они особого отношения не имеют, исполняются в юзерспейсе. Представляют из себя обычные исполнимые бинарники. Их много разных, лежат где-то приблизительно в /lib/nut, могут иметь какие-то свои специфические настройки (смотря для какого устройства и что это устройство умеет). Драйвер(ы) запускает upsd после того как почитает свои конфиги дабы получать через них информацию от ups-ов, после чего эти самые драйверы можно невозбранно увидеть в списке запущенных процессов. Конфиг читают из /etc/nut/ups.conf.
  3. монитор такой монитор
    Клиент, он же монитор, он же upsmon. Несмотря на свою клиентскую сущность - обычно тоже работает как демон (управляется скриптом /etc/init.d/nut-client). А вот этот товарищ запущен может быть решительно где угодно - можно даже на NAS или свой телефон на ведроиде его воткнуть, хотя в последнем смысла не многим больше чем в троллейбусе из буханки белого (или чёрного) хлеба. upsmon на androidИменно upsmon отвечает за то, чтобы тактически грамотно выключить компьютер, когда нет ни питания, ни надежды на его возобновление. Будучи клиентом - информацию о состоянии бесперебойника монитор получает, как нетрудно догадаться, от сервера, т.е. от upsd. Работать upsmon может в двух режимах: master - используется только на том же самом компьютере, к которому ups подключён управляющим проводом (например usb); либо в режиме slave - используется если компьютер питается от упса но не может им напрямую управлять. Отличие master от slave в общем-то только в том что master одновременно с завершением работы своей операционной системы отдаёт бесперебойнику команду отключить питание с нагрузки. Конфигурируется монитор через /etc/nut/upsmon.conf
  4. Типа таймер ))
    Таймер, он же upssched. Эта программка входит в комплект, однако изначально NUT не настроен на то чтобы её использовать, это просто один из возможных вариантов, который upsmon запускает в качестве реакции на те или иные события, т.е. вместо upssched в настройках можно указать, к примеру, самописный скрипт. Однако делать этого имхо не стоит т.к. во-первых самописный скрипт всё равно можно (и придётся!) настроить на запуск из upssched-а, а во вторых - основная фишка upssched-а в том что он умеет работать с таймерами. Получив от upsmon-а ту или иную команду, upssched может запустить отсчёт времени, вместо того чтобы просто сразу же передать её некоему третьему исполнимому файлу. И лишь когда созданный таким образом таймер дотикает до нуля - команда будет передана к примеру в настроенный нами самописный скрипт (обзовём его, скажем, upssched-cmd, хотя это и не принципиально). Есть также возможность прервать работу ещё не дотикавшего таймера по команде от upsmon-а (например, в качестве реакции на событие "вернулось питание"). Созданные upssched-ом таймеры являются отдельными процессами и видны в их списке, причём в upssched предусмотрена защита от "гонки" процессов, которая с небольшой вероятностью может возникнуть если upsmon, реагируя на множество событий, начнёт очень часто вызывать upssched. Конфиг с настройками - /etc/nut/upssched.conf.
  5. Стоит также сказать, что в debian-based-дистрибутивах скрипты инициализации читают файл /etc/nut.conf чтобы определить какие именно демоны вообще запускать. В других дистрибутивах вполне может быть что-то аналогичное - обратите внимание на документацию соответствующих пакетов и на то, что пишет пакетный менеджер при установке.

Подведём итог... и чтобы не писать опять много букв про всё то - же самое - сведу-ка я это в виде схемы:
Схема работы компонентов NUT

Как всё будет работать в итоге.

Да всё просто в общем то - скрипты инициализации запускают на одном и том же компьютере и upsd и upsmon, upsd запускает настроенный для имеющегося бесперебойника драйвер и начинает отслеживать его (бесперебойника) состояние. Upsmon подключается к upsd с указанными в настройках upsd именем и паролем пользователя, после чего тоже начинает внимательно наблюдать за состоянием бесперебойника. Как только бесперебойник оказывается в состоянии "питаюсь от батареи" - upsd узнаёт об этом от драйвера, а upsmon узнаёт уже от upsd. Upsmon смотрит свои настройки и видит - для состояния ONBATT он должен вызвать указанную в параметре NOTIFYCMD команду, передав ей через переменную окружения тип события - т.е., опять же, ONBATT. В NOTIFYCMD у нас указан upssched, который немедленно и запускается. Upssched смотрит уже свой собственный конфиг и видит, что получив событие типа ONBATT он должен запустить таймер (длительностью, к примеру, 60 секунд) с именем onbatt - ок, таймер запускается и начинает тикать. А теперь возможны варианты.

  1. Таймер может просто дотикать до нуля - тогда upssched берёт имя таймера, затем он берёт из своих настроек опцию CMDSCRIPT и запускает указанный в этой опции исполнимый файл (у нас будет upssched-cmd) с параметром, идентичным имени таймера. То есть он запустит upssched-cmd с параметром onbatt. Upssched-cmd в нашем случае будет самым обыкновенным bash-скриптом сcase-конструкцией, проверяющий переданный параметр и действующий в зависимости от этого самого параметра. Получив onbatt - скрипт во-первых ругнётся в логи (полезно для отладки), во-вторых отправит бесперебойнику команду shutdown.return (получив эту команду UPS подождёт ранее настроенное время и уберёт питание с нагрузки, а в случае восстановления питания - вернёт питание на нагрузку), в третьих - начнёт завершение работы операционной системы. Для отправки команды бесперебойнику мы воспользуемся командой upscmd - она входит в набор nut и тоже является клиентом для upsd т.е. подключается к нему по сети. Завершать работу операционки можно было бы, к примеру, просто командой halt, однако мы воспользуемся upsmon -c fsd - она во-первых заставляет upsmon передать сигнал fsd (forced shutdown) на upsd, что может быть важно если к upsd подключены upsmon с других, питающихся от того же UPS-а компьютеров, а во-вторых - выполняет собственно завершение работы операционки. По идее, работающий в режиме мастера upsmon при получении fsd должен ещё и обеспечивать передачу на UPS команды shutdown.return, однако "из коробки" оно в Debian на работает. Чтобы заработало - потребуется глубоко вникнуть в устройство скриптов, исполняющихся при завершении работы системы... короче гораздо проще отослать на UPS команду "руками", что и делает наш скрипт.
  2. Питание может вернуться до того как скрипт onbatt дотикает до нуля. Сигнал ONLINE при этом опять пойдёт по цепочке driver-upsd-upsmon-upssched. Последний, увидев в настройках что на ONLINE он должен остановить работу таймера onbatt - прибивает процесс таймера. Естественно таймер уже не дотикает и скрипт upssched-cmd вызван не будет.
  3. Чисто теоретически возможна ситуация, когда таймер ещё не дотикал, но от драйвера поступает сигнал LOWBATT - то есть бесперебойник уже на последнем издыхании. В этом случае upssched решает "резать, не дожидаясь перитонита", т.е. вызывает upssched-cmd с командой onbatt, не дожидаясь когда там дотикает таймер. В итоге компьютер попытается успеть выключиться до того как UPS окончательно сдохнет.

Теперь несколько слов о восстановлении питания. Что будет если питание вернётся когда upssched уже запустил обратный отсчёт времени, но завершение работы системы ещё не началось - понятно и уже расписано выше. Но обычно важно и чтобы сервер сам загрузился после того как электропитание будет восстановлено - для этого надо залезть в BIOS и найти там в разделе навроде "power management" опцию с названием что-то типа "AC Back Function". Называться и настраиваться оно может в общем то как угодно, особенно в BIOS-ах серверных материнок, главное смысл %). А смысл в том что системник включается сам сразу - как только появляется питание. На том собранном из хлама как-бы-сервере, где я последний раз настраивал работу бесперебойника, опция выглядит так:
опция в биосе
Если питание вернётся после того, как операционная система завершила работу, системник выключился, UPS тоже выключился (т.е. перестал подавать питание на нагрузку) - всё заработает и начнёт загружаться практически сразу. А вот если питание вернётся, к примеру, после того как операционка уже начала завершаться но системник ещё работает, либо после того как системник выключился но UPS ещё не отключался - тут возможны варианты. Совсем не факт что бесперебойник уберёт и потом вернёт питание по истечении настроенного для него времени если питание от сети уже вернулось - а в этом случае системник обратно не включится. Всё прямо зависит от того, как именно бесперебойник реагирует на восстановление питания после получения команды shutdown.return. В моём случае UPS действовал тактически грамотно во всех вариантах - т.е. после получения команды на отключение - он исправно ждал заказанные ему секунды, отключал питание с нагрузки, и только затем если питание от сети присутствовало - возвращал питание обратно. В идеале так и должно быть. Но вам стоит протестировать все возможные варианты, прежде чем оставлять сервер работать без присмотра. Иначе есть вероятность, что вас вытянут на работу утром в воскресенье потому что, например, сайт не работает. Если при тестировании выявились проблемы с загрузкой после восстановления питания, либо если просто очень важно чтобы сервер работал постоянно - возможно стоит настроить BIOS на включение, скажем, каждый день в 7 утра - если конечно в вашем биосе есть такая настройка.

А вот, собственно, и пошаговая инструкция по настройке. На примере Debian.

Первым делом устанавливаем пакет:

apt-get install nut

Команды, естественно, выполняем с правами суперпользователя, sudo если оно в вашей ситуации нужно - сами делаете :).
Не знаю как другие дистрибутивы, а Debian при установке пакета выдаст приблизительно следующее:

Настраивается пакет nut-client (2.6.4-2.3+deb7u1) …
[info] nut-client disabled, please adjust the configuration to your needs.
[info] Then set MODE to a suitable value in /etc/nut/nut.conf to enable it.
Настраивается пакет nut-server (2.6.4-2.3+deb7u1) …
[info] nut-server disabled, please adjust the configuration to your needs.
[info] Then set MODE to a suitable value in /etc/nut/nut.conf to enable it.

Это означает что пока мы не укажем режим работы NUT в конфиге /etc/nut/nut.conf - скрипты инициализации вообще не будут запускать демоны. Открываем этот конфиг в чём вы там конфиги редактируете. Я обычно редактирую в nano.

nano -w /etc/nut/nut.conf

Опция -w нужна чтобы nano не пытался разбивать длинные строки, что иногда может испортить конфиг.
В самом файле мы видим одну единственную опцию MODE, в комментариях же подробно расписано какие у этой опции могут быть значения. При этом нас вполне устроит режим standalone, его и прописываем.

MODE=standalone

Обратите также внимание что комментарий в конфиге крайне не рекомендует использовать пробелы вокруг символа равенства т.к. скрипты могут это дело неправильно понять.
Теперь нам надо определиться с тем, какой именно драйвер нужно использовать для бесперебойника. Во-первых, можно посмотреть таблицу совместимости на сайте NUT, на момент написания статьи она находилась по адресу http://www.networkupstools.org/stable-hcl.html. Во-вторых, примерно та же информация содержится в файле /usr/share/nut/driver.list (или аналогичном в других дистрибутивах). Так или иначе, различные Ippon-ы работают через драйвер blazer (blazer_ser для серийного порта и blazer_usb для, соответственно, usb). Посмотреть подробности по настройке этого драйвера можно либо командой man blazer, либо по ссылке на странице с сайта NUT - важно ознакомиться с документацией на выбранный драйвер, т.к. команды и настройки у каждого драйвера могут быть свои, уникальные. У меня по какой-то причине blazer_ser работать не захотел, а вот blazer_usb, несмотря на свой экспериментальный статус, работает как часы.

В общем, определяемся с драйвером, после чего лезем в файл /etc/nut/ups.conf. Вписываем в него примерно следующую секцию:

[ippon-smart-1000]
driver = blazer_usb
port = auto
desc = "Ippon Smart Power Pro 1000"
default.battery.voltage.high = 26.00
default.battery.voltage.low = 20.80
offdelay = 35
ondelay = 1
  • Название устройства в квадратных скобках может быть любым, но именно его придётся использовать в других конфигурационных файлах.
  • Driver - указываем тот, который подходит для вашего устройства. Port - для blazer_usb надо указывать auto, а вот для не-usb драйверов вероятно потребуется указать что-то вроде /dev/ttyS0 - смотря к какому порту подключен бесперебойник.
  • Desc - тут может быть любой текст - это описание устройства.
  • Свойства default.battery.voltage.* - специфичны именно для данного драйвера (специфичные свойства подробно расписаны в man-страницах драйверов и на сайте NUT), значения же - нагуглены для данного конкретного бесперебойника. В Smart Power Pro 1000 используется две 12-вольтовых батареи, т.е. номинальное напряжение батарей будет 24 вольта. Реально же напряжение заряженных батарей будет около 26-27 вольт, почти разряженных - 21-20 вольт. По идее эти параметры можно корректировать экспериментально, наблюдая за напряжением батарей в зависимости от времени автономной работы и того факта что при неких реальных значениях компьютер отключается.
  • Offdelay - ещё один специфичный для blazer_usb параметр, в нём указывается через сколько секунд после получения команды shutdown.return бесперебойник уберёт питание с нагрузки. Я указал 35 секунд, поскольку мой сервер выключается очень быстро, но вам вероятно стоит поставить побольше времени - засеките сколько секунд занимает завершение работы с секундомером и настройку ставьте с запасом. Кстати, сама команда shutdown.return тоже специфична для данного конкретного драйвера - у других драйверов команды могут быть иными.
  • Ondelay - время в минутах, по истечении которого UPS посмотрит есть ли у него питание от сети, и если это питание есть - вернёт питание на нагрузку. Ещё один специфичный для драйвера параметр. В документации на драйвер сказано, что ранние версии прошивок бесперебойников могут проблемно реагировать на значение менее трёх минут, поэтому если будете указывать, как я, 1 минуту - обязательно протестируйте несколько раз включается ли UPS автоматически обратно.

Итак, драйвер мы настроили. Теперь настраиваем основной демон. Лезем в конфиг /etc/nut/upsd.conf. В принципе, достаточно будет раскомментировать следующую опцию:

LISTEN 127.0.0.1 3493

Демон будет слушать 3493 порт на loopback-интерфейсе. Параноики могут явно закрыть извне 3493-й порт в iptables, но по идее из сети добраться до демона при такой настройке никто не сможет.
Теперь надо указать логин и пароль для подключения к демону - открываем /etc/nut/upsd.users. Комментарии не трогаем (желательно - читаем), вписываем в конце файла примерно такую секцию:

[nutuser]
password = nutpass
upsmon master
actions = SET
actions = FSD
instcmds = ALL

В квадратных скобках указан логин, параметром password - пароль. Строчка upsmon master означает, что подключившийся монитор будет работать в режиме мастера. Actions = SET - разрешает монитору менять параметры бесперебойника "на лету". Actions = FSD разрешает включать Forced Shotdown. Instcmds = ALL - разрешает с этого имени пользователя отдавать бесперебойнику любые поддерживаемые драйвером команды.

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

/etc/init.d/nut-server start

Пробуем получить сведения от UPS-а:

upsc ippon-smart-1000@localhost

В ответ должно выдать что-то типа такого:

battery.charge: 100
battery.voltage: 27.80
battery.voltage.high: 26.00
battery.voltage.low: 20.80
battery.voltage.nominal: 24.0
device.type: ups
driver.name: blazer_usb
driver.parameter.offdelay: 35
driver.parameter.ondelay: 1
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.version: 2.6.4
driver.version.internal: 0.08
input.current.nominal: 4.0
input.frequency: 50.1
input.frequency.nominal: 50
input.voltage: 226.2
input.voltage.fault: 226.2
input.voltage.nominal: 220
output.voltage: 223.9
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 60
ups.load: 11
ups.productid: 5161
ups.status: OL
ups.temperature: 25.0
ups.type: offline / line interactive
ups.vendorid: 0665

Если это действительно так - всё ок, драйвер и демон работают. Важно чтобы параметр ups.status имел значение OL т.е. OnLine - если оно отличается - что-то не так либо с драйвером, либо с самим устройством. Если же выдало ошибку, а в логах можно найти сообщения о том, что драйвер не может найти устройство - вероятно на бесперебойник не сработали правила udev. В таком случае вам нужно скопировать файл /lib/udev/rules.d/52-nut-usbups.rules в /etc/udev/rules.d/ - после чего либо подключить\отключить бесперебойник от компьютера (в случае USB), либо перезагрузиться, либо "дёрнуть" udev следующим образом:

udevadm control --reload-rules
udevadm trigger

После чего (если не перезагружались) - перезапустить сервис upsd и заново попробовать получить информацию от бесперебойника:

/etc/init.d/nut-server restart
upsc ippon-smart-1000@localhost

Надеюсь, всё заработало, если нет - рекомендации дать уже сложно, надо вдумчиво курить логи.

Будем считать что, всё работает и продолжим. Настраиваем монитор. Файл там довольно длинный, с кучей комментариев. Поэтому чтобы не выискивать нужные опции - лучше переименуйте /etc/nut/upsmon.conf в, к примеру, /etc/nut/upsmon.conf.old и создайте новый файл /etc/nut/upsmon.conf. В этот пустой файл вставляем что-то типа такого:

MONITOR ippon-smart-1000@localhost 1 nutuser nutpass master
MINSUPPLIES 1
NOTIFYCMD /sbin/upssched
SHUTDOWNCMD "/sbin/shutdown -Ph +0"
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/nut/killpower
NOTIFYMSG ONLINE     "UPS %s on line power"
NOTIFYMSG ONBATT     "UPS %s on battery"
NOTIFYMSG LOWBATT    "UPS %s battery is low"
NOTIFYMSG FSD        "UPS %s: forced shutdown in progress"
NOTIFYMSG COMMOK     "Communications with UPS %s established"
NOTIFYMSG COMMBAD    "Communications with UPS %s lost"
NOTIFYMSG SHUTDOWN   "Auto logout and shutdown proceeding"
NOTIFYMSG REPLBATT   "UPS %s battery needs to be replaced"
NOTIFYMSG NOCOMM     "UPS %s is unavailable"
NOTIFYMSG NOPARENT   "upsmon parent process died - shutdown impossible"
NOTIFYFLAG ONLINE    SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT    SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT   SYSLOG+WALL+EXEC
NOTIFYFLAG FSD       SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK    SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD   SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN  SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT  SYSLOG+WALL+EXEC
NOTIFYFLAG NOCOMM    SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT  SYSLOG+WALL+EXEC
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5
  • Первая строчка заставляет монитор подключаться (с указанными логином и паролем) к серверу upsd на localhost и отслеживать бесперебойник ippon-smart-1000, при этом работать монитор должен в режиме мастера. Единичка означает что системник питается от одной единственной линии бесперебойника, что-то другое тут возможно только когда в системнике больше одного блока питания.
  • MINSUPPLIES 1 - эта опция примерно о том же о чём только что говорилось - тут настраивается минимальное количество действующих источников питания, при котором системник ещё может нормально работать. Бывают особенно извращённые сервера к примеру с 4 блоками питания, для нормальной работы которых нужно запитать минимум 2 из них.
  • NOTIFYCMD - тут мы указываем исполнимый файл, который upsmon будет запускать для тех событий, для которых настроена реакция EXEC. При запуске upsmon передаёт аргументом текст сообщения о событии, а через переменную окружения NOTIFYFLAG - имя типа события. Указать можно что угодно, но мы укажем upssched, ибо нужно будет запускать таймер.
  • SHUTDOWNCMD "/sbin/shutdown -Ph +0" - смысл, полагаю, очевиден - надо объяснить upsmon какой командой ему завершать работу системы.
  • POLLFREQ, POLLFREQALERT, HOSTSYNC, DEADTIME задают таймауты различных проверок upsmon-ом параметров бесперебойника, RBWARNTIME и NOCOMMWARNTIME - таймауты вывода предупреждений о замене батарей и об отсутствии связи с бесперебойником соответственно. Подробности - см. комментарии в оригинальном конфиге.
  • POWERDOWNFLAG - указанный здесь файл upsmon создаёт если, работая в режиме master, он так или иначе получил сигнал FSD и запустил завершение работы системы. В идеале существование этого файла должны проверять скрипты, исполняющиеся при завершении работы, и самостоятельно подавать бесперебойнику команду на отключение питания нагрузки, однако озаботились ли этим разработчики дистрибутива и\или мейнтейнеры пакета(ов) NUT - сказать сложно. Именно поэтому мы "руками" будем отсылать бесперебойнику эту команду через скрипты.
  • Строки NOTIFYMSG задают текст сообщений, которые выдаются в лог и\или на консоли при возникновении соответствующих событий.
  • Строки NOTIFYFLAG задают реакцию upsmon на соответствующие события. Возможно указать следующие виды реакций:
    • SYSLOG - пишется сообщение в, как нетрудно догадаться, /var/log/syslog  :).
    • WALL - сообщение выдаётся на консоли всем залогиненным пользователям.
    • EXEC - вызывается NOTIFYCMD, тип события передаётся через переменную окружения NOTIFYFLAG, аргументом идёт текст сообщения о событии.
    • IGNORE - делать ровно ничего.
  • FINALDELAY - сколько секунд ждать после получения события SHUTDOWN до реального начала завершения работы системы.

Теперь настроим upssched. Открываем /etc/nut/upssched.conf. Опять же, либо чистим файл, либо ищем там нужные незакомментированные параметры и проставляем там нужные нам значения. Получиться должно примерно что-то такое:

#Скрипт, который будет запускаться по завершению работы таймера или по EXECUTE
CMDSCRIPT /bin/upssched-cmd
# Именованный канал, через который upssched общается с процессами-таймерами.
PIPEFN /var/run/nut/upssched.pipe
# Блокировочный файл - нужен чтобы не было гонок процессов.
LOCKFN /var/run/nut/upssched.lock
#Если переходим на батареи - ждём 60 секунд и посылаем команду onbatt, которая вырубит сервер.
AT ONBATT * START-TIMER onbatt 60
#Если вернулось питание - отменить таймер для команды onbatt
AT ONLINE * CANCEL-TIMER onbatt
#Если батарейка села нафиг - сразу послать onbatt чтобы вырубить сервер.
AT LOWBATT * EXECUTE onbatt

Суть настроек уже объяснена в комментариях, хочу только заметить, что по-умолчанию в конфиге предлагаются другие значения PIPEFN и LOCKFN, и если их не менять - придётся (по крайней мере на Debian) идти на дополнительные ухищрения чтобы процессы, работающие от имени пользователя nut могли писать\читать\создавать эти файлы. А вот к каталогу /var/run/nut/ доступ у этих процессов обычно есть. В любом случае стоит убедиться что пользователь, от имени которого в вашем дистрибутиве работают демоны NUT имеет возможность создавать файлы, указанные в этих настройках.
Строки начинающиеся на AT - добавляют реакции на типы событий - для ONBATT (на батарейке) мы запускаем таймер на 60 секунд, для ONLINE - прерываем таймер, для LOWBATT - сразу выключаем компьютер.

Осталось только написать или отредактировать (если он уже существует) скрипт /bin/upssched-cmd. Убедитесь что файлу проставлены права на исполнение и что пользователь nut сможет запустить файл! Рекомендую просто заменить его содержимое на следующий текст:

#! /bin/sh
#
# This script should be called by upssched via the CMDSCRIPT directive.
#
# Here is a quick example to show how to handle a bunch of possible
# timer names with the help of the case structure.
#
# This script may be replaced with another program without harm.
#
# The first argument passed to your CMDSCRIPT is the name of the timer
# from your AT lines.

case "$1" in
        onbatt)
                logger -t upssched-cmd "60 seconds on battary - halt system and poweroff UPS after 35 sec"
                upscmd -unutuser -pnutpass ippon-smart-1000@localhost shutdown.return
                sudo upsmon -c fsd
                ;;
        upsgone)
                logger -t upssched-cmd "The UPS has been gone for awhile"
                ;;
        *)
                logger -t upssched-cmd "Unrecognized command: $1"
                ;;
esac

Важный момент. Процесс upssched скорее всего будет работать от имени пользователя nut. И, опять же, скорее всего этот пользователь не имеет права завершать работу операционной системы. Я обошёл это добавлением sudo к вызову команды upsmon -c fsd и добавлением в /etc/sudoers следующих строчек:

#allow shutdown for nut
nut ALL=NOPASSWD: /sbin/shutdown, /sbin/upsmon -c fsd

Но есть и другие варианты, например добавлением пользователя nut в соответствующую группу - зависит от вашего дистрибутива.

Вот и всё, можно (если ещё не) запускать сервисы NUT (либо просто перезагрузиться) и приступать к тестированию работоспособности всей этой конструкции.
В процессе тестирования сообщения от NUT будут падать в /var/log/syslog - отслеживать изменения в этом логе удобно такой командой:

watch -n 0,5 tail -n 50 /var/log/syslog

Вот вроде и всё, спасибо что прочитали.

Если вы заметили ошибки\неточности - не стесняйтесь отписаться о них в комментариях.


 


 

Комментарии  

0 #10 Sagrer 29.07.2018 17:03
Цитирую Роман:
Есть подозрение, что рубится исполнение sudo, т.к. выполняется она не интерактивно. Но совершенно не имею представления, куда копать и как продиагностировать проблему.


Я бы курил куда-нибудь в сторону
Цитата:
watch tail -n 30 /var/log/auth.log
На первый взгляд всё должно работать судя по тому что описываете.
Цитировать | Сообщить модератору
0 #9 Роман 18.07.2018 17:54
Цитирую Sagrer:
2Роман

Абзац про то, что для пользователя, от имени которого запускается скрипт возможно придётся править /etc/sudoers вы точно прочитали?


1. Имя пользователя я поставил через опцию RUN_AS_USER, так что это наверняка пользователь nut. У демона upsmon тоже есть опция -u для этого. Кстати, то что пользователь nut - это просто желание мейнтейнеров пакета того или иного дистра. И чтобы не гадать, лучше указывать пользователя явно. Это указано и в документации.
2. Проверил через whoami в скрипте upssched-cmd, что действительно он запускается от нужного пользователя (nut)
3. Есс-но отредактировал sudoers. И проверил, запустив upssched-cmd onbatt в терминале от nut, сделав nut возможность логина, что всё работает.

Есть подозрение, что рубится исполнение sudo, т.к. выполняется она не интерактивно. Но совершенно не имею представления, куда копать и как продиагностировать проблему.
Цитировать | Сообщить модератору
-1 #8 Sagrer 18.07.2018 15:21
2Роман

Абзац про то, что для пользователя, от имени которого запускается скрипт возможно придётся править /etc/sudoers вы точно прочитали? Потому что непонятно от чьего имени вы вообще запускаете скрипт если потом пишете что "Если же сделать пользователя nut... то скрипт срабатывает на ура.".
Цитировать | Сообщить модератору
0 #7 MelaniT 17.07.2018 22:17
APC Back-UPS CS умеет рассказывать, насколько он загружен. Ippon Smart Power pro тоже, Back Power pro — не знаю. Также не знаю, есть ли возможность это посмотреть в поставляющемся с Ippon ПО или с ПО от APC, но под Windows.
Цитировать | Сообщить модератору
0 #6 Роман 16.07.2018 16:57
А что можете подсказать в случае, если команда на завершение upsmon -c fsd (или shutdown -h now и пр.) в скрипте upssched-cmd не срабатывает при запуске через NUT? Именно только это команда. Логирование и др. команды в нём запускаются. Т.е. скрипт запускается и штатно отрабатывает.

Если же сделать пользователя nut с возможностью логирования и запустить тот же скрипт с параметром onbatt, то скрипт срабатывает на ура.

Система CentOS 7.

Спасибо. И за статью тоже большое спасибо.
Цитировать | Сообщить модератору
0 #5 Андрон 20.12.2017 02:30
Монументально! В закладки!
Цитировать | Сообщить модератору
0 #4 oleg 26.09.2017 23:33
Отличная статья, спасибо! :-)
Цитировать | Сообщить модератору
0 #3 Николай 10.07.2016 04:03
Отличный гайд. Давно собирался посидеть и неспеша разобраться во всех нюансах. Без подробного понимания параметров не могу заставить себя включить ИБП по принципу лишь бы работало - тогда уж лучше совсем без софта.
Родная "управлялка" под Windows мало того еще и кушает процессор просто так! Под Linux WinPower работает, но не сильно лучше.
Цитировать | Сообщить модератору
0 #2 Sagrer 18.05.2016 13:53
2Илья

А пробовали добавлять в /etc/sudoers строку
nut ALL=NOPASSWD: /sbin/shutdown, /sbin/upsmon -c fsd
? По идее nut ALL=(ALL) ALL несекьюрно, да и права рута nut-у давать не алё, особенно если сервер голой жо в интернет выставлен... Я вообще включал возможность логиниться nut-ом и из под него проверял юзабельность команд.

Что касается chmod -R g+w /etc/nut/ - не очень понятно что оно даст, killpower по крайней мере на момент написания статьи скрипты дебиана не проверяли при завершении работы всё равно...

Ну а вообще рад, что статья помогла ).
Цитировать | Сообщить модератору
+2 #1 Илья 26.01.2016 10:12
Огромное СПАСИБО автору за подробную статью. Перечитал не меньше, чем уважаемый Владимир, но самая толковая оказалась эта. Единственное что - мне пришлось добавить:
1. В файлах /etc/group и /etc/passwd группе nut и пользователю nut присвоил права группы и пользователя root соответственно
2. Выполнил команду chmod -R g+w /etc/nut/
3. В файле /etc/sudoers добавил строку %nut ALL=(ALL) ALL
Без этого не завел...
Система - Debian 8.2.0 amd64; UPS - ION V-2000
Цитировать | Сообщить модератору

Добавить комментарий


Защитный код
Обновить