背景

目前有一台山特ups,ups只有一个typeb口,但需要同时给多台设备(两台nas一台pve软路由)供电,且家里停电时ups能够通知所有设备自动关机。由于群晖的网络ups协议用的就是nut,所以将群晖作为nutServer,在pve上安装nut进行配置即可。

配置PVE中nut客户端

nut在各类linux系统中都可以用默认的包管理系统进行安装

apt install nut

nut配置

修改/etc/nut/nut.conf,将MODE设置为netclient

MODE=netclient

修改/etc/nut/upsmon.conf中的MONITOR等配置项

MONITOR <system> <powervalue> <username> <password> ("master"|"slave")
#<system>设置为ups@服务器地址或域名,这里是ups@192.168.1.107
#<powervalue>设置为1
#<username>群晖UPS服务器的默认用户名是monuser
#<password>群晖UPS服务器的默认密码是secret
#("master"|"slave"),客户机设置为slave
MONITOR ups@192.168.1.107 1 monuser secret slave

有可能需要设置RUN_AS_USER选项以解决权限问题

RUN_AS_USER root

通过upsc ups@<UPS_IP>测试连接情况

启动nutClient

systemctl start nut-client #启动网络ups客户端服务
systemctl status nut-client #检查服务状态,如有错误再根据提示进行排查
systemctl enable nut-client #设置网络ups客户端服务自启动

编写自动关机脚本

默认情况下nut会在收到LOWBATT时执行关机操作,即在ups低电量时关机,相关的配置在/etc/nut/upsmon.conf

POWERDOWNFLAG /etc/killpower
SHUTDOWNCMD "/sbin/shutdown -h +0"

该配置文件中还有message相关配置

# --------------------------------------------------------------------------
# NOTIFYMSG - change messages sent by upsmon when certain events occur
#
# You can change the default messages to something else if you like.
#
# NOTIFYMSG <notify type> "message"

而我希望软路由会在停电3分钟后自动关机,这就需要使用upssched自定义。在upsmon中设置触发条件通知upssched,并由upssched完成后续工作。

配置upsmon

首先在upsmon.conf中添加NOTIFYCMD /sbin/upssched,即在发生事件时运行upssched服务。

设置触发条件:

NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
  • 触发条件各个选项的含义在upsmon.conf的注释中有详细描述

配置upssched

随后在/etc/nut/upssched.conf中实现所需功能:

CMDSCRIPT /etc/nut/upssched-cmd
PIPEFN /etc/nut/upssched.pipe
LOCKFN /etc/nut/upssched.lock

# 断电使用电池开始180秒后,执行upssched-cmd脚本,带shutdown_self参数
AT ONBATT * START-TIMER shutdown_self 180
# 来电后,停止shutdown_all计时
AT ONLINE * CANCEL-TIMER shutdown_self
# 来电后,执行脚本,带start_all参数
AT ONLINE * EXECUTE start_all
# 低电量,执行脚本,带shutdown_self参数
AT LOWBATT * EXECUTE shutdown_self

CMDSCRIPT指定需要执行的脚本,随后我们设置触发条件以及传入脚本的参数。

  • AT语句需要在前三行之后,且需要保证PIPEFNLOCKFN命令中的文件NUT应有读取写入及操作的权限,若权限不正确则会报错Failed to connect to parent and failed to create parent: No such file or directory

编写脚本

脚本放在上文中CMDSCRIPT指定的位置

#! /bin/sh
case $1 in
        shutdown_self)
                #关闭所有
                /usr/sbin/upsmon -c fsd
                ;;
        shutdown_all)
                pvesh create /nodes/pve/qemu/100/status/stop
                pvesh create /nodes/pve/qemu/101/status/stop
                ;;
        start_all)
                #开启所有
                pvesh create /nodes/pve/qemu/100/status/start
                pvesh create /nodes/pve/qemu/101/status/start
                ;;
        *)
                logger -t upssched-cmd "Unrecognized command: $1"
                ;;
esac
  • nut需要有执行该脚本的权限,否则会报错exec_cmd(your-path your-event) returned 126

最后重启服务,就可以断电测试了。