Управление UPSами (NUT)

взято отсюда http://sysadminblog.sagrer.ru/stati-i-gajdy/linux/18-nastrojka-besperebojnika-na-primere-ippon-smart-powerpro-1000-v-linux.html

 

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

apt-get install nut

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

vim /etc/nut/nut.conf

В самом файле мы видим одну единственную опцию 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 уже должен уметь запускать драйвер и отслеживать состояние бесперебойника - запускаем демона:

systemctl start nut-server

Пробуем получить сведения от 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 и заново попробовать получить информацию от бесперебойника:

systemctl restart nut-server
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 - отслеживать изменения в этом логе удобно такой командой:

tail -f /var/log/syslog