Вопрос или проблема
Кто-нибудь может помочь мне с этим, не совсем понимаю, что я делаю не так.
У меня есть Raspberry Pi, на котором работает NUT Server, подключенный к моему ИБП по USB.
Я пытаюсь заставить сервер NUT выполнять мои скрипты, когда он переходит на батарейное питание. Мои скрипты в основном являются оболочными скриптами, которые вызывают PowerShell скрипт, использующий Power CLI для выключения моих систем VMware.
Они работают нормально, когда я вызываю их вручную через PowerShell, через оболочный скрипт, и я могу вручную вызывать триггеры, выполняя /usr/bin/upssched-cmd shutdownservers, и это работает хорошо. Но по какой-то причине это не срабатывает, когда я отключаю питание от ИБП. Скрипты электронной почты работают нормально в оболочных скриптах. Не знаю, что происходит.
Ниже приведен оболочный скрипт, который я использую для тестирования, просто чтобы убедиться, что все работает. Этот скрипт обращается к vcenter и выполняет отключение одной ВМ.
#!/bin/sh
#Сначала выполнит PowerShell
pwsh /Scripts/TestScripts/Test_VmwareTest1.ps1
#ждет
#echo 'VMWARE теперь успешно выключена, сплю 60 секунд, чтобы выключить Truenas!!'
#sleep 120
#./Test_TruenasShutdown.sh
sleep 10
/Scripts/EmailAlertMessages/EmailAlert-ShutdownComplete.sh
exit
Когда я отключаю питание от ИБП, срабатывает электронная почта, чтобы сообщить, что ИБП работает на батарейном питании, затем еще одно письмо, чтобы сказать, что он собирается выполнить скрипт отключения. Но скрипт отключения, похоже, никогда не выполняется.
Ниже представлены мои конфигурации NUT.
UPSSCHED-CMD настроен следующим образом:
#!/bin/sh
UPS_USERNAME="admin"
UPS_PASSWORD="pwd"
UPS_LINK="APCUPS01@localhost"
case $1 in
onbatt)
# Включить зуммер
#upscmd -u ${UPS_USERNAME} -p ${UPS_PASSWORD} ${UPS_LINK} beeper.enable
# Отправить уведомление в journalctl и на электронную почту
logger -t upssched-cmd "ИБП на батарейном питании!"
/Scripts/EmailAlertMessages/EmailAlert-OnBattery.sh
;;
online)
# Записать уведомление в journalctl и отправить уведомление по электронной почте
logger -t upssched-cmd "ИБП снова в сети!"
/Scripts/EmailAlertMessages/EmailAlert-BackOnline.sh
;;
shutdownservers)
# Начать отключение всех систем
logger -t upssched-cmd "Скрипт отключения был вызван!"
/Scripts/EmailAlertMessages/EmailAlert-Shutdown.sh
/Scripts/TestScripts/Test_Shutdown.sh
;;
mute_beeper)
# Выключить зуммер через 30 секунд
upscmd -u ${UPS_USERNAME} -p ${UPS_PASSWORD} ${UPS_LINK} beeper.mute
;;
esac
UPSSCHED.CONF
CMDSCRIPT /usr/bin/upssched-cmd
PIPEFN /etc/nut/upssched.pipe
LOCKFN /etc/nut/upssched.lock
# ============================================================================
# Отправка предупреждений
AT ONBATT * EXECUTE onbatt
AT ONLINE * EXECUTE online
# Начать отключение серверов - выполнить Shutdown.sh
AT ONBATT * START-TIMER shutdownservers 5
# Отменить таймер отключения серверов, если батарея снова в сети
AT ONLINE * CANCEL-TIMER shutdownservers online
# Если батарея разряжена, немедленно выполнить команды отключения серверов
AT LOWBATT * EXECUTE shutdownservers
# (Необязательно) Заглушить зуммер через 2 минуты
AT ONBATT * START-TIMER mute_beeper 30
AT ONLINE * CANCEL-TIMER mute_beeper
UPSMON.CONF
RUN_AS_USER root
MONITOR APCUPS01@localhost 1 admin pwd master
MINSUPPLIES 1
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 2
POLLFREQALERT 1
HOSTSYNC 15
DEADTIME 15
NOTIFYMSG ONLINE "ИБП %s на сетевом питании"
NOTIFYMSG ONBATT "ИБП %s на батарее"
NOTIFYMSG LOWBATT "Батарея ИБП %s разряжена"
NOTIFYMSG FSD "ИБП %s: принудительное отключение в процессе"
NOTIFYMSG COMMOK "Связь с ИБП %s установлена"
NOTIFYMSG COMMBAD "Связь с ИБП %s потеряна"
NOTIFYMSG SHUTDOWN "Авто-выход и отключение в процессе"
NOTIFYMSG REPLBATT "Батарея ИБП %s требует замены"
NOTIFYMSG NOCOMM "ИБП %s недоступен"
NOTIFYMSG NOPARENT "Процесс родителя upsmon завершился - отключение невозможно"
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG FSD SYSLOG+WALL
NOTIFYFLAG COMMOK SYSLOG+WALL
NOTIFYFLAG COMMBAD SYSLOG+WALL
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC
NOTIFYFLAG NOCOMM SYSLOG+WALL
NOTIFYFLAG NOPARENT SYSLOG+WALL
RBWARNTIME 43200
NOCOMMWARNTIME 600
FINALDELAY 5
Разрешения на скрипты такие же, как и на верхнем уровне папок, как указано ниже.
drwxr-xr-x 3 root root 4096 Dec 2 19:36 EmailAlertMessages
-rwxr-xr-x 1 root root 146 Dec 2 20:42 RestartNUTServices.sh
drwxr-xr-x 4 root root 4096 Dec 2 19:36 Shutdown
drwxr-xr-x 2 root root 4096 Dec 2 19:36 TestScripts
Разрешения команды PowerShell следующие
-rwxrwxr-x 1 root root 72568 Oct 16 17:50 /opt/microsoft/powershell/7/pwsh
У кого-нибудь есть идея, что я делаю не так?
Ответ или решение
Проблема с выполнением сценариев оболочки на сервере NUT при переходе на питание от батареи может быть вызвана несколькими факторами. Чтобы помочь вам лучше понять и решить эту неполадку, я представлю подробный анализ возможных причин и решений.
1. Проблемы с конфигурацией NUT
Убедитесь, что ваши конфигурационные файлы правильно настроены.
- В файле
upsmon.conf
у вас определены флаги уведомлений, в том числе для событияONBATT
, которые указывают на то, что должно происходить при выходе на питание от батареи. Проверьте, чтоNOTIFYFLAG ONBATT
корректно настроен (вы, похоже, уже это сделали). - Убедитесь, что у вас правильно прописаны пути к скриптам. Вы используете абсолютные пути, что является хорошей практикой.
- Попробуйте добавить логирование для диагностики. Например, добавьте сообщения в лог в начале вашего сценария и в конце его выполнения, чтобы понять, исполняется ли он вообще.
2. Проблемы с правами доступа
Скрипты, которые вызываются NUT, должны иметь достаточные права для выполнения необходимых действий. Убедитесь, что:
- Скрипты имеют права на исполнение:
rwxr-xr-x
(что, похоже, уже установлено у вас). - NUT работает от пользователя, который имеет доступ к VBScript и необходимым ресурсам. Попробуйте временно упростить права, чтобы проверить, решит ли это вашу проблему.
3. Программные ограничения
Подумайте о том, какую среду использует PowerShell при выполнении. Когда скрипт запускается через NUT, он может выполняться в другой среде, где переменные и пути могут отличаться.
- Убедитесь, что
pwsh
доступен и находится в PATH для пользователя, под которым запускается NUT (в данном случае, это, вероятно, root). - Попробуйте протестировать запуск PowerShell в другом контексте, чтобы исключить проблемы с окружением.
4. Ограничения по времени выполнения
Если NUT вызывает shutdownservers
через запланированный таймер, убедитесь, что система не переходит в долгий режим ожидания или другой режим, который препятствует выполнению.
- Возможно, стоит увеличить время ожидания или поработать с более надежным методом управлением задачами. Протестируйте разные временные задержки, чтобы исключить эту возможность.
5. Убедитесь в корректности самих скриптов
Хотя вы упомянули, что скрипты работают корректно при ручном вызове, это следует проверить еще раз.
- Вы можете добавить вывод отладочных сообщений внутри вашего PowerShell скрипта, чтобы точно определить, выполняется ли часть кода.
- Как вариант, измените временный скрипт, который просто записывает дату и время в файл, чтобы проверить выполнение.
6. Журналирование и отладка
Следуйте этим шагам для улучшения диагностики:
- Проверьте журналы NUT в
/var/log/syslog
или используйтеjournalctl
, чтобы понять, что происходит при переходе на новый режим. - Журналируйте вход и выход из всех скриптов, чтобы иметь возможность отследить место их остановки (если это произойдет).
Заключение
Если ни одно из вышеуказанных решений не помогло, попробуйте создать минимально воспроизводимый пример, который состоит только из простых команд, а затем постепенно добавляйте функциональность, чтобы pinpoint’ить точное место отказа. Успех в решении вашей проблемы!