diff --git a/net/nut/Makefile b/net/nut/Makefile index 2a253f8c0..6108e2705 100644 --- a/net/nut/Makefile +++ b/net/nut/Makefile @@ -9,14 +9,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nut PKG_VERSION:=2.7.4 -PKG_RELEASE:=7 +PKG_RELEASE:=8 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://www.networkupstools.org/source/2.7/ PKG_HASH:=980e82918c52d364605c0703a5dcf01f74ad2ef06e3d365949e43b7d406d25a7 PKG_MAINTAINER:=Daniel Dickinson -PKG_LICENSE:=GPL-2.0 -PKG_LICENSE_FILES:=LICENSE-GPL2 +PKG_LICENSE:=GPL-2.0+ GPL-3.0+ GPL-1.0+ Artistic-1.0-Perl +PKG_LICENSE_FILES:=LICENSE-GPL2 LICENSE-GPL3 COPYING PKG_FIXUP:=autoreconf PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) @@ -63,22 +63,32 @@ define Package/nut/install endef define Package/nut-server/install + # Server portion $(INSTALL_DIR) $(1)/etc/nut $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_DIR) $(1)/usr/share/nut - $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/nut-server.init $(1)/etc/init.d/nut-server $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/upsd $(1)/usr/sbin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/upsdrvctl $(1)/usr/sbin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/nut/cmdvartab $(1)/usr/share/nut/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/nut/driver.list $(1)/usr/share/nut/ $(INSTALL_DIR) $(1)/etc/config $(INSTALL_CONF) ./files/nut_server $(1)/etc/config/nut_server - ln -sf /var/etc/nut/nut.conf $(1)/etc/nut/nut.conf - ln -sf /var/etc/nut/ups.conf $(1)/etc/nut/ups.conf ln -sf /var/etc/nut/upsd.users $(1)/etc/nut/upsd.users ln -sf /var/etc/nut/upsd.conf $(1)/etc/nut/upsd.conf + # Driver common portion + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/upsdrvctl $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/nut/driver.list $(1)/usr/share/nut/ + ln -sf /var/etc/nut/ups.conf $(1)/etc/nut/ups.conf + # Mangle libhid.usermap into a format (hotplug shell script) useful for OpenWrt + $(INSTALL_DIR) $(1)/etc/hotplug.d/usb + $(INSTALL_BIN) ./files/30-libhid-ups.head $(1)/etc/hotplug.d/usb/30-libhid-ups + $(CP) $(PKG_INSTALL_DIR)/etc/hotplug/usb/libhid.usermap $(PKG_BUILD_DIR)/30-libhid-ups.middle + $(SED) '/^$$$$/d' \ + -e '/^#/d' \ + -E -e 's:^[^ ][^ ]* *0x0003 *0x0{0,3}([^ ][^ ]*) *0x{0,3}*([^ ][^ ]*).*:\1/\2/* | \\:' \ + $(PKG_BUILD_DIR)/30-libhid-ups.middle + tail -n+2 $(PKG_BUILD_DIR)/30-libhid-ups.middle >>$(1)/etc/hotplug.d/usb/30-libhid-ups + cat ./files/30-libhid-ups.tail >>$(1)/etc/hotplug.d/usb/30-libhid-ups endef define Package/nut-common @@ -87,8 +97,7 @@ define Package/nut-common DEPENDS:= nut \ +NUT_DRIVER_SNMP:libnetsnmp \ +NUT_DRIVER_USB:libusb-compat \ - +NUT_SSL:libopenssl \ - +PACKAGE_libwrap:libwrap + +NUT_SSL:libopenssl endef define Package/nut-common/description @@ -96,6 +105,10 @@ $(call Package/nut/description/Default) This package contains the common files. endef +define Package/nut-common/conffiles +/etc/nut/nut.conf +endef + define Package/nut-common/install $(INSTALL_DIR) $(1)/etc/nut $(INSTALL_DIR) $(1)/usr/lib @@ -107,6 +120,7 @@ define Package/nut-server $(call Package/nut/Default) TITLE+= (server) DEPENDS:=nut +nut-common + USERID:=nut=113:nut=113 endef define Package/nut-server/description @@ -120,13 +134,16 @@ endef define Package/nut-server/conffiles /etc/config/nut_server +/etc/nut/upsd.conf +/etc/nut/upsd.users +/etc/nut/ups.conf endef define Package/nut-upsmon $(call Package/nut/Default) TITLE+= (monitor) DEPENDS:=nut +nut-common - USERID:=nut=113:nut=113 + USERID:=nutmon=114:nutmon=114 endef define Package/nut-upsmon/description @@ -141,6 +158,7 @@ endef define Package/nut-upsmon/conffiles /etc/config/nut_monitor +/etc/nut/upsmon.conf endef define Package/nut-upsmon/install @@ -149,6 +167,7 @@ define Package/nut-upsmon/install $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/nut-monitor.init $(1)/etc/init.d/nut-monitor $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/upsmon $(1)/usr/sbin/ + $(INSTALL_BIN) ./files/nutshutdown $(1)/usr/sbin/nutshutdown $(INSTALL_DIR) $(1)/etc/config $(INSTALL_CONF) ./files/nut_monitor $(1)/etc/config/nut_monitor ln -sf /var/etc/nut/upsmon.conf $(1)/etc/nut/upsmon.conf @@ -182,7 +201,7 @@ define Package/nut-upsc/description $(call Package/nut/description/Default) upsc is provided as a quick way to poll the status of a UPS server. It can be used inside shell scripts and other programs that need UPS data -but don not want to include the full interface. +but do not want to include the full interface. endef define Package/nut-upsc/install @@ -308,12 +327,15 @@ define Package/nut-web-cgi/install $(INSTALL_CONF) ./files/add_nut_httpd_conf $(1)/etc/uci-defaults/add_nut_httpd_conf $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/upsstats.html.sample $(1)/etc/nut/upsstats.html $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/upsstats-single.html.sample $(1)/etc/nut/upsstats-single.html - $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/upsset.conf.sample $(1)/etc/nut/upsset.conf + $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/upsset.conf.sample $(1)/etc/nut/upsset.conf.disable + $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/upsset.conf.sample $(1)/etc/nut/upsset.conf.enable + $(SED) 's/### \?//' $(1)/etc/nut/upsset.conf.enable $(INSTALL_DIR) $(1)/etc/config $(INSTALL_CONF) ./files/nut_cgi $(1)/etc/config/nut_cgi $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/nut-cgi.init $(1)/etc/init.d/nut-cgi ln -sf /var/etc/nut/hosts.conf $(1)/etc/nut/hosts.conf + ln -sf /var/etc/nut/upsset.conf $(1)/etc/nut/upsset.conf endef define Package/nut-avahi-service @@ -342,7 +364,7 @@ define DriverPackage define Package/nut-driver-$(2) $(call Package/nut/Default) TITLE:=$(2) (NUT $(1) driver) - DEPENDS:=nut +nut-common + DEPENDS:=nut +nut-server $(if $(filter $(1),snmp),DEPENDS+= @NUT_DRIVER_SNMP) $(if $(filter $(1),usb),DEPENDS+= @NUT_DRIVER_USB) $(if $(filter $(1),serial),DEPENDS+= @NUT_DRIVER_SERIAL) @@ -502,9 +524,11 @@ CONFIGURE_ARGS += \ --without-avahi \ --$(if $(CONFIG_NUT_DRIVER_SNMP),with,without)-snmp \ --$(if $(CONFIG_NUT_DRIVER_SERIAL),with,without)-serial \ + --without-doc \ --without-neon \ --without-powerman \ --without-wrap \ + --with-hotplug-dir=/etc/hotplug \ --with-cgi \ --without-ipmi \ --without-freeipmi \ diff --git a/net/nut/files/30-libhid-ups.head b/net/nut/files/30-libhid-ups.head new file mode 100755 index 000000000..efcbcf66b --- /dev/null +++ b/net/nut/files/30-libhid-ups.head @@ -0,0 +1,51 @@ +#!/bin/sh + +. /lib/functions.sh + +nut_driver_config() { + local cfg="$1" + local nomatch="$2" + + config_get runas "$cfg" runas "nut" + config_get vendorid "$cfg" vendorid + config_get productid "$cfg" productid + + [ "$ACTION" = "add" ] &&[ -n "$DEVNAME" ] && { + chmod 0660 /dev/"$DEVNAME" + chown ${runas:-root}:$(id -gn "${runas:-root}") /dev/"$DEVNAME" + } + + if [ "$(printf "%04x" 0x"$pvendid")" = "$vendorid" ] && \ + [ "$(printf "%04x" 0x"$pprodid")" = "$productid" ]; then + [ "$ACTION" = "add" ] && { + /etc/init.d/nut-server start "$cfg" + } + [ "$ACTION" = "remove" ] && { + /etc/init.d/nut-server stop "$cfg" + } + found=1 + elif [ "$nomatch" = "1" ]; then + [ "$ACTION" = "add" ] && { + /etc/init.d/nut-server start "$cfg" + } + [ "$ACTION" = "remove" ] && { + /etc/init.d/nut-server stop "$cfg" + } + fi +} + +perform_libhid_action() { + local vendorid productid runas + local pvendid pprodid found + + pvendid=${PRODUCT%/*} + pvendid=${pvendid%/*} + pprodid=${PRODUCT%/*} + pprodid=${pprodid##*/} + + config_load nut_server + config_foreach nut_driver_config driver 0 + [ "$found" != "1" ] && config_foreach nut_driver_config driver 1 +} + +[ -n "$PRODUCT" ] && case "$PRODUCT" in diff --git a/net/nut/files/30-libhid-ups.tail b/net/nut/files/30-libhid-ups.tail new file mode 100644 index 000000000..24c2a9670 --- /dev/null +++ b/net/nut/files/30-libhid-ups.tail @@ -0,0 +1,5 @@ +"") + [ -d /var/run/nut ] && [ ! -f /var/run/nut/disable-hotplug ] && \ + /etc/init.d/nut-server enabled && perform_libhid_action + ;; +esac diff --git a/net/nut/files/nut-cgi.init b/net/nut/files/nut-cgi.init index d63d98ba9..ceb7cce22 100755 --- a/net/nut/files/nut-cgi.init +++ b/net/nut/files/nut-cgi.init @@ -5,9 +5,24 @@ # See /LICENSE for more information. # START=51 +USE_PROCD=1 DEFAULT=/etc/default/nut UPSCGI_C=/var/etc/nut/hosts.conf +UPSCGI_S=/var/etc/nut/upsset.conf + +nut_upscgi_upsset() { + local cfg="$1" + local enable + + config_get_bool enable "$cfg" enable 0 + + [ $enable -eq 1 ] && { + ln -sf /etc/nut/upsset.conf.enable "$UPSCGI_S" + } || { + ln -sf /etc/nut/upsset.conf.disable "$UPSCGI_S" + } +} nut_upscgi_add() { local cfg="$1" @@ -25,20 +40,32 @@ nut_upscgi_add() { system="$system:$port"; fi config_get displayname "$cfg" displayname - echo "MONITOR $system \"$displayname\"" >> $UPSCGI_C + echo "MONITOR $system \"$displayname\"" >> "$UPSCGI_C" } -start() { - rm -f $UPSCGI_C +service_reload() { + mkdir -m 0755 -p "$(dirname "$UPSCGI_C")" + rm -f "$UPSCGI_C" + rm -f "$UPSCGI_S" config_load nut_cgi config_foreach nut_upscgi_add host + config_foreach nut_upscgi_upsset upsset chmod 640 /var/etc/nut/hosts.conf } -stop() { - rm -f $UPSCGI_C +start_service() { + service_reload +} + +stop_service() { + rm -f "$UPSCGI_C" + rm -f "$UPSCGI_S" + ln -sf /etc/nut/upsset.conf.disable "$UPSCGI_S" } +service_triggers() { + procd_add_reload_trigger "nut_cgi" +} diff --git a/net/nut/files/nut-monitor.init b/net/nut/files/nut-monitor.init index af8140781..513d70305 100755 --- a/net/nut/files/nut-monitor.init +++ b/net/nut/files/nut-monitor.init @@ -6,56 +6,57 @@ UPSMON_C=/var/etc/nut/upsmon.conf nut_upsmon_conf() { local cfg="$1" + local RUNAS val optval - echo "# Config file automatically generated from UCI config" > $UPSMON_C + echo "# Config file automatically generated from UCI config" > "$UPSMON_C" - config_get runas "$cfg" runas "nut" - [ -n "$runas" ] && echo "RUN_AS_USER $runas" >> $UPSMON_C + config_get RUNAS "$cfg" runas "nutmon" + [ -n "$RUNAS" ] && echo "RUN_AS_USER $RUNAS" >> "$UPSMON_C" + runas=$RUNAS config_get val "$cfg" minsupplies 1 - echo "MINSUPPLIES $val" >> $UPSMON_C + echo "MINSUPPLIES $val" >> "$UPSMON_C" - config_get val "$cfg" shutdowncmd "/sbin/halt" - echo "SHUTDOWNCMD \"$val\"" >> $UPSMON_C + config_get val "$cfg" shutdowncmd "/usr/sbin/nutshutdown" + echo "SHUTDOWNCMD \"$val\"" >> "$UPSMON_C" config_get val "$cfg" notifycmd - [ -n "$val" ] && echo "NOTIFYCMD \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYCMD \"$val\"" >> "$UPSMON_C" config_get val "$cfg" pollfreq 5 - echo "POLLFREQ $val" >> $UPSMON_C + echo "POLLFREQ $val" >> "$UPSMON_C" config_get val "$cfg" pollfreqalert 5 - echo "POLLFREQALERT $val" >> $UPSMON_C + echo "POLLFREQALERT $val" >> "$UPSMON_C" config_get val "$cfg" hostsync 15 - echo "HOSTSYNC $val" >> $UPSMON_C + echo "HOSTSYNC $val" >> "$UPSMON_C" config_get val "$cfg" deadtime 15 - echo "DEADTIME $val" >> $UPSMON_C + echo "DEADTIME $val" >> "$UPSMON_C" - config_get val "$cfg" powerdownflag /var/run/killpower - echo "POWERDOWNFLAG $val" >> $UPSMON_C + echo "POWERDOWNFLAG /var/run/killpower" >> "$UPSMON_C" config_get val "$cfg" onlinemsg - [ -n "$val" ] && echo "NOTIFYMSG ONLINE \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG ONLINE \"$val\"" >> "$UPSMON_C" config_get val "$cfg" onbattmsg - [ -n "$val" ] && echo "NOTIFYMSG ONBATT \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG ONBATT \"$val\"" >> "$UPSMON_C" config_get val "$cfg" lowbattmsg - [ -n "$val" ] && echo "NOTIFYMSG LOWBATT \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG LOWBATT \"$val\"" >> "$UPSMON_C" config_get val "$cfg" fsdmsg - [ -n "$val" ] && echo "NOTIFYMSG FSD \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG FSD \"$val\"" >> "$UPSMON_C" config_get val "$cfg" commokmsg - [ -n "$val" ] && echo "NOTIFYMSG COMMOK \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG COMMOK \"$val\"" >> "$UPSMON_C" config_get val "$cfg" commbadmsg - [ -n "$val" ] && echo "NOTIFYMSG COMMBAD \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG COMMBAD \"$val\"" >> "$UPSMON_C" config_get val "$cfg" shutdownmsg - [ -n "$val" ] && echo "NOTIFYMSG SHUTDOWN \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG SHUTDOWN \"$val\"" >> "$UPSMON_C" config_get val "$cfg" replbattmsg - [ -n "$val" ] && echo "NOTIFYMSG REPLBATT \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG REPLBATT \"$val\"" >> "$UPSMON_C" config_get val "$cfg" nocommmsg - [ -n "$val" ] && echo "NOTIFYMSG NOCOMM \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG NOCOMM \"$val\"" >> "$UPSMON_C" config_get val "$cfg" noparentmsg - [ -n "$val" ] && echo "NOTIFYMSG NOPARENT \"$val\"" >> $UPSMON_C + [ -n "$val" ] && echo "NOTIFYMSG NOPARENT \"$val\"" >> "$UPSMON_C" notifylist() { local value="$1" @@ -85,34 +86,34 @@ nut_upsmon_conf() { val="" config_list_foreach "$cfg" defaultnotify notifylist default="$optval" - echo "NOTIFYFLAG ONLINE $(setnotify "$cfg" onlinenotify)" >> $UPSMON_C - echo "NOTIFYFLAG ONBATT $(setnotify "$cfg" onbattnotify)" >> $UPSMON_C - echo "NOTIFYFLAG LOWBATT $(setnotify "$cfg" lowbatnotify)" >> $UPSMON_C - echo "NOTIFYFLAG FSD $(setnotify "$cfg" fsdnotify)" >> $UPSMON_C - echo "NOTIFYFLAG COMMOK $(setnotify "$cfg" commoknotify)" >> $UPSMON_C - echo "NOTIFYFLAG COMMBAD $(setnotify "$cfg" commbadnotify)" >> $UPSMON_C - echo "NOTIFYFLAG SHUTDOWN $(setnotify "$cfg" shutdownnotify)" >> $UPSMON_C - echo "NOTIFYFLAG REPLBATT $(setnotify "$cfg" repolbattnotify)" >> $UPSMON_C - echo "NOTIFYFLAG NOCOMM $(setnotify "$cfg" nocommnotify)" >> $UPSMON_C - echo "NOTIFYFLAG NOPARENT $(setnotify "$cfg" noparentnotify)" >> $UPSMON_C + echo "NOTIFYFLAG ONLINE $(setnotify "$cfg" onlinenotify)" >> "$UPSMON_C" + echo "NOTIFYFLAG ONBATT $(setnotify "$cfg" onbattnotify)" >> "$UPSMON_C" + echo "NOTIFYFLAG LOWBATT $(setnotify "$cfg" lowbatnotify)" >> "$UPSMON_C" + echo "NOTIFYFLAG FSD $(setnotify "$cfg" fsdnotify)" >> "$UPSMON_C" + echo "NOTIFYFLAG COMMOK $(setnotify "$cfg" commoknotify)" >> "$UPSMON_C" + echo "NOTIFYFLAG COMMBAD $(setnotify "$cfg" commbadnotify)" >> "$UPSMON_C" + echo "NOTIFYFLAG SHUTDOWN $(setnotify "$cfg" shutdownnotify)" >> "$UPSMON_C" + echo "NOTIFYFLAG REPLBATT $(setnotify "$cfg" repolbattnotify)" >> "$UPSMON_C" + echo "NOTIFYFLAG NOCOMM $(setnotify "$cfg" nocommnotify)" >> "$UPSMON_C" + echo "NOTIFYFLAG NOPARENT $(setnotify "$cfg" noparentnotify)" >> "$UPSMON_C" config_get val "$cfg" rbwarntime 43200 - echo "RBWARNTIME $val" >> $UPSMON_C + echo "RBWARNTIME $val" >> "$UPSMON_C" config_get val "$cfg" nocommwarntime 300 - echo "NOCOMMWARNTIME $val" >> $UPSMON_C + echo "NOCOMMWARNTIME $val" >> "$UPSMON_C" config_get val "$cfg" finaldelay 5 - echo "FINALDELAY $val" >> $UPSMON_C + echo "FINALDELAY $val" >> "$UPSMON_C" config_get val "$cfg" certpath - if [ -n "$val" ]; then echo "CERTPATH $val" >> $UPSMON_C; fi + if [ -n "$val" ]; then echo "CERTPATH $val" >> "$UPSMON_C"; fi config_get_bool val "$cfg" certverify 0 - if [ -n "$val" ]; then echo "CERTVERIFY $val" >> $UPSMON_C; fi + if [ -n "$val" ]; then echo "CERTVERIFY $val" >> "$UPSMON_C"; fi config_get_bool val "$cfg" forcessl 0 - if [ -n "$val" ]; then echo "FORCESSL $val" >> $UPSMON_C; fi + if [ -n "$val" ]; then echo "FORCESSL $val" >> "$UPSMON_C"; fi } nut_upsmon_add() { @@ -126,12 +127,6 @@ nut_upsmon_add() { local password local system - # if UPSMON_C is a symlink we're only doing generated config - [ -L $UPSMON_C ] && { - rm -f $UPSMON_C - nut_upsmon_conf "" - } - config_get upsname "$cfg" upsname config_get hostname "$cfg" hostname localhost config_get port "$cfg" port @@ -142,40 +137,49 @@ nut_upsmon_add() { if [ -n "$port" ]; then system="$system:$port"; fi - echo "MONITOR $system $powervalue $username $password $type" >> $UPSMON_C + echo "MONITOR $system $powervalue $username $password $type" >> "$UPSMON_C" } -start_service() { - mkdir -p "$(dirname "$UPSMON_C")" - chmod 750 "$(dirname "$UPSMON_C")" +build_config() { + local runas + mkdir -m 0750 -p "$(dirname "$UPSMON_C")" config_load nut_monitor - config_foreach nut_upsmon_conf upsmon config_foreach nut_upsmon_add master master config_foreach nut_upsmon_add slave slave - [ -z "$(cat /var/etc/nut/nut.conf)" ] && echo "MODE=netclient" >>/var/etc/nut/nut.conf - - chmod 640 $UPSMON_C - chmod 640 /var/etc/nut/nut.conf - - chown ${runas:-root}:$(id -gn ${runas:-root}) /var/etc/nut - chown ${runas:-root}:$(id -gn ${runas:-root}) /var/etc/nut/nut.conf - chown ${runas:-root}:$(id -gn ${runas:-root}) $UPSMON_C - - [ -d /var/run/nut ] || { - mkdir -m 0750 -p /var/run/nut - chown ${runas:-root}:$(id -gn ${runas:-root}) /var/run/nut + [ -z "$(cat /var/etc/nut/nut.conf)" ] && { + echo "MODE=netclient" >>/var/etc/nut/nut.conf + chmod 640 /var/etc/nut/nut.conf + chgrp $(id -gn ${runas:-root}) /var/etc/nut/nut.conf } - exec $DEBUG /usr/sbin/upsmon $UPSMON_OPTIONS + chmod 640 "$UPSMON_C" + chgrp $(id -gn ${runas:-root}) "$UPSMON_C" } -stop_service() { - exec /usr/sbin/upsmon -c stop +start_service() { + build_config + procd_open_instance + procd_set_param respawn + procd_set_param stderr 0 + procd_set_param stdout 1 + procd_set_param command /usr/sbin/upsmon -D + procd_close_instance } reload_service() { - exec /usr/sbin/upsmon -c reload + if pgrep upsmon >/dev/null 2>/dev/null; then + build_config + upsmon -c reload + else + stop + sleep 1 + start + fi +} + +service_triggers() { + procd_add_reload_trigger nut_monitor } diff --git a/net/nut/files/nut-server.init b/net/nut/files/nut-server.init index e064dd721..73bf30ea1 100755 --- a/net/nut/files/nut-server.init +++ b/net/nut/files/nut-server.init @@ -6,47 +6,70 @@ # START=50 -RUN_D=/var/run -PID_F=$RUN_D/upsd.pid -UPS_C=/var/etc/nut/ups.conf USERS_C=/var/etc/nut/upsd.users UPSD_C=/var/etc/nut/upsd.conf +UPS_C=/var/etc/nut/ups.conf USE_PROCD=1 -listen_address() { - local cfg="$1" +get_write_driver_config() { + local cfg="$1" + local var="$2" + local def="$3" + local flag="$4" + local val - config_get address "$cfg" address "::1" - config_get port "$cfg" port - echo "LISTEN $address $port" >>$UPSD_C + [ -z "$flag" ] && { + config_get val "$cfg" "$var" "$def" + [ -n "$val" ] && [ "$val" != "0" ] && echo "$var = $val" >>"$UPS_C" + } + + [ -n "$flag" ] && { + config_get_bool val "$cfg" "$var" "$def" + [ "$val" = 1 ] && echo "$var" >>"$UPS_C" + } } upsd_statepath() { + local cfg="$1" + local statepath + + config_get statepath "$cfg" statepath "/var/run/nut" + STATEPATH="$statepath" +} + +listen_address() { local cfg="$1" - config_get statepath "$cfg" statepath + + config_get address "$cfg" address "::1" + config_get port "$cfg" port + echo "LISTEN $address $port" >>"$UPSD_C" } upsd_config() { local cfg="$1" - local maxage maxconn certfile + local maxage maxconn certfile runas statepath # Note runas support requires you make sure USB device file is readable by # the runas user - config_get runas "$cfg" runas + config_get runas "$cfg" runas "nut" + RUNAS="$runas" + + config_get statepath "$cfg" statepath "/var/run/nut" + STATEPATH="$statepath" config_get maxage "$cfg" maxage - [ -n "$maxage" ] && echo "MAXAGE $maxage" >>$UPSD_C + [ -n "$maxage" ] && echo "MAXAGE $maxage" >>"$UPSD_C" config_get statepath "$cfg" statepath - [ -n "$statepath" ] && echo "STATEPATH $statepath" >>$UPSD_C + [ -n "$statepath" ] && echo "STATEPATH $statepath" >>"$UPSD_C" config_get maxconn "$cfg" maxconn - [ -n "$maxconn" ] && echo "MAXCONN $maxconn" >>$UPSD_C + [ -n "$maxconn" ] && echo "MAXCONN $maxconn" >>"$UPSD_C" #NOTE: certs only apply to SSL-enabled version config_get certfile "$cfg" certfile - [ -n "$certfile" ] && echo "CERTFILE $certfile" >>$UPSD_C + [ -n "$certfile" ] && echo "CERTFILE $certfile" >>"$UPSD_C" } nut_user_add() { @@ -55,104 +78,180 @@ nut_user_add() { local val config_get val "$cfg" username "$1" - echo "[$val]" >> $USERS_C + echo "[$val]" >> "$USERS_C" config_get val "$cfg" password - echo " password = $val" >> $USERS_C + echo " password = $val" >> "$USERS_C" config_get val "$cfg" actions for a in $val; do - echo " actions = $a" >> $USERS_C + echo " actions = $a" >> "$USERS_C" done instcmd() { local val="$1" - echo " instcmds = $val" >> $USERS_C + echo " instcmds = $val" >> "$USERS_C" } config_list_foreach "$cfg" instcmd instcmd config_get val "$cfg" upsmon if [ -n "$val" ]; then - echo " upsmon $val" >> $USERS_C + echo " upsmon $val" >> "$USERS_C" fi } -start_service() { - local runas statepath - - mkdir -p /var/etc/nut - chmod -R 750 /var/etc/nut - - rm -f $UPSD_C - rm -f $USERS_C - rm -f $UPSD_C +build_server_config() { + mkdir -m 0755 -p "$(dirname "$UPSD_C")" + rm -f "$USERS_C" + rm -f "$UPSD_C" rm -f /var/etc/nut/nut.conf - echo "# Config file automatically generated from UCI config" > $UPS_C - echo "# Config file automatically generated from UCI config" > $USERS_C - echo "# Config file automatically generated from UCI config" > $UPSD_C - - local in_driver have_drivers - config_cb() { - if [ "$1" != "driver" ]; then - in_driver= - else - echo "[$2]" >> $UPS_C - in_driver=true - have_drivers=true - fi - } - option_cb() { - if [ "$in_driver" = "true" ]; then - echo " $1 = $2" >> $UPS_C - fi - } - - config_load nut_server + echo "# Config file automatically generated from UCI config" > "$USERS_C" + echo "# Config file automatically generated from UCI config" > "$UPSD_C" config_foreach nut_user_add user - config_foreach upsd_config upsd config_foreach listen_address listen_address - + config_foreach upsd_config upsd echo "MODE=netserver" >>/var/etc/nut/nut.conf - chmod 0640 $USERS_C - chmod 0640 $UPS_C - chmod 0640 $UPSD_C + chmod 0640 "$USERS_C" + chmod 0640 "$UPSD_C" chmod 0640 /var/etc/nut/nut.conf - [ -d "${statepath:-/var/run/nut}" ] || { - mkdir -m 0750 -p "${statepath:-/var/run/nut}" - chown $runas:$(id -gn $runas) "${statepath:-/var/run/nut}" + + [ -d "${STATEPATH}" ] || { + mkdir -m 0750 -p "${STATEPATH}" } - if [ -n "$runas" ]; then - chown -R $runas:$(id -gn $runas) /var/etc/nut + if [ -n "$RUNAS" ]; then + chown $RUNAS:$(id -gn $RUNAS) "${STATEPATH}" + chgrp $(id -gn $RUNAS) "$USERS_C" + chgrp $(id -gn $RUNAS) "$UPSD_C" fi +} - if [ "$have_drivers" = "true" ]; then - $DEBUG /usr/sbin/upsd ${runas:+-u $runas} $OPTIONS - $DEBUG /usr/sbin/upsdrvctl ${runas:+-u $runas} start - fi +build_driver_config() { + local cfg="$1" + local runas + + echo "[$cfg]" >>"$UPS_C" + + config_get runas "$cfg" runas "nut" + RUNAS="$runas" + + get_write_driver_config "$cfg" driver "usbhid-ups" + get_write_driver_config "$cfg" port "auto" + get_write_driver_config "$cfg" mfr + get_write_driver_config "$cfg" model + get_write_driver_config "$cfg" serial + get_write_driver_config "$cfg" sdtime + get_write_driver_config "$cfg" offdelay 20 + get_write_driver_config "$cfg" ondelay 30 + get_write_driver_config "$cfg" pollfreq 30 + get_write_driver_config "$cfg" vendor + get_write_driver_config "$cfg" product + get_write_driver_config "$cfg" bus + get_write_driver_config "$cfg" interruptonly 0 1 + get_write_driver_config "$cfg" interruptsize 0 + get_write_driver_config "$cfg" maxreport + get_write_driver_config "$cfg" vendorid + get_write_driver_config "$cfg" productid + get_write_driver_config "$cfg" community + get_write_driver_config "$cfg" snmp_version + get_write_driver_config "$cfg" snmp_retries 0 + get_write_driver_config "$cfg" snmp_timeout 0 + get_write_driver_config "$cfg" notransferoids 0 1 + get_write_driver_config "$cfg" other + echo "" >>$UPS_C } +build_config() { + mkdir -m 0755 -p "$(dirname "$UPS_C")" + rm -f "$UPS_C" + echo "# Config file automatically generated from UCI config" > "$UPS_C" + chmod 0640 "$UPS_C" + + config_load nut_server + config_foreach build_driver_config driver + [ -n "$RUNAS" ] && chgrp $(id -gn $RUNAS) "$UPS_C" -nut_driver_stop() { + build_server_config +} + +start_driver_instance() { local cfg="$1" + local requested="$2" + local RUNAS=nut local driver - config_get driver "$cfg" driver + # If wanting a specific instance, only start it + [ "$requested" != "$cfg" ] && [ x"$requested" != x"" ] && return 0 + + mkdir -m 0755 -p "$(dirname "$UPS_C")" + + [ ! -s "$UPS_C" ] && build_config + - [ -r ${statepath:-/var/run/nut}/$driver-$cfg ] && /usr/sbin/upsdrvctl stop $cfg + # Avoid hotplug inadvertenly restarting driver during + # forced shutdown + [ -f /var/run/killpower ] && return 0 + [ -d /var/run/nut ] && [ -f /var/run/nut/disable-hotplug ] && return 0 + + + if [ -n "$RUNAS" ]; then + chown $RUNAS:$(id -gn $RUNAS) "${STATEPATH}" + chown $RUNAS:$(id -gn $RUNAS) "$(dirname "$UPS_C")" + fi + + config_get driver "$cfg" driver "usbhid-ups" + procd_open_instance "$cfg" + procd_set_param respawn + procd_set_param stderr 0 + procd_set_param stdout 1 + procd_set_param command /lib/nut/${driver} -D -a "$cfg" ${RUNAS:+-u $RUNAS} + procd_close_instance +} + +start_server_instance() { + local RUNAS STATEPATH + build_config + + procd_open_instance "upsd" + procd_set_param respawn + procd_set_param stderr 0 + procd_set_param stdout 1 + procd_set_param command /usr/sbin/upsd -D ${RUNAS:+-u $RUNAS} + procd_close_instance } -stop_service() { - [ -r $PID_F ] && /usr/sbin/upsd -c stop - config_load ups +start_service() { + local STATEPATH=/var/run/nut + + # Avoid hotplug inadvertenly restarting driver during + # forced shutdown + [ -f /var/run/killpower ] && return 0 + [ -d /var/run/nut ] && [ -f /var/run/nut/disable-hotplug ] && return 0 + + config_load nut_server config_foreach upsd_statepath upsd - config_foreach nut_driver_stop driver + + [ -d "${STATEPATH}" ] || { + mkdir -m 0750 -p "${STATEPATH}" + } + + build_config + config_foreach start_driver_instance driver "$@" + + [ "$1" != "upsd" ] && [ x"$1" != x"" ] && return 0 + start_server_instance "upsd" } reload_service() { - upsd -c reload + stop + sleep 2 + start +} + +service_triggers() { + procd_add_reload_trigger "nut_server" } diff --git a/net/nut/files/nut_cgi b/net/nut/files/nut_cgi index 9f0bed6fc..dca5de07c 100644 --- a/net/nut/files/nut_cgi +++ b/net/nut/files/nut_cgi @@ -4,3 +4,5 @@ # option port # optional port number # option displayname "Display Name" +config upsset + option enable 0 diff --git a/net/nut/files/nut_monitor b/net/nut/files/nut_monitor index 0b71e95cf..59e0f360d 100644 --- a/net/nut/files/nut_monitor +++ b/net/nut/files/nut_monitor @@ -1,14 +1,13 @@ #config upsmon 'upsmon' -# option runas run-as-user +# option runas nutmon # option minsupplies 1 -# option shutdowncmd /sbin/halt +# option shutdowncmd '/usr/sbin/nutshutdown' # option notifycmd /path/to/cmd # list defaultnotify SYSLOG # option pollfreq 5 # option pollfreqalert 5 # option hostsync 15 # option deadtime 15 -# option powerdownflags /var/run/killpower # option onlinemsg "online message" # option onbattmsg "on battery message" # option lowbattmsg "low battery message" @@ -51,4 +50,3 @@ # option powervalue 1 # option username upsuser # option password upspassword - diff --git a/net/nut/files/nut_server b/net/nut/files/nut_server index bebd169db..464d56303 100644 --- a/net/nut/files/nut_server +++ b/net/nut/files/nut_server @@ -19,5 +19,6 @@ # option maxage 15 # option statepath /var/run/nut # option maxconn 1024 +# option runas nut # NB: certificates only apply to SSL-enabled version # option certfile /usr/local/etc/upsd.pem diff --git a/net/nut/files/nutshutdown b/net/nut/files/nutshutdown new file mode 100755 index 000000000..e4fd962cd --- /dev/null +++ b/net/nut/files/nutshutdown @@ -0,0 +1,41 @@ +#!/bin/sh +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +. /lib/functions.sh + +mount -o remount,ro /overlay /overlay +mount -o remount,ro / / + +stop_instance() { + /etc/init.d/nut-server stop "$1" +} + +shutdown_instance() { + local cfg="$1" + config_get driver "$cfg" driver "usbhid-ups" + /lib/nut/${driver} -a "$cfg" -k +} + +[ -f /var/run/killpower ] && { + [ -f /etc/config/nut_server ] && { + config_load nut_server + + # Can't FSD unless drivers are stopped + config_foreach stop_instance driver + # Driver will wait 'offdelay' before shutting down + config_foreach shutdown_instance driver + # So this can happen + poweroff + # And just in case + sleep 120 + # Uh-oh failed to poweroff UPS + reboot -f + } || { + poweroff + } +} || { + poweroff +}