Table of Contents
The primary goal of the Network UPS Tools (NUT) project is to provide support for Power Devices, such as Uninterruptible Power Supplies, Power Distribution Units and Solar Controllers.
This document intends to report high-level changes delivered by NUT project releases, as well as practical nuances for packagers and end-users who would be upgrading their NUT deployments.
It DOES NOT intend to detail the change log: it is very large and complicated to render properly, so is better served by another document artifact.
If you wish to discover how everything came together, have a look at the Project History.
If you’re upgrading from an earlier version, see the UPGRADING.adoc file.
Please note that web and source document links, product and service names listed in historic entries of past releases may no longer be relevant.
For a complete and more detailed list of changes, please refer to the ChangeLog file (generated for release archives), or to the Git version control history for "live" codebase.
https://github.com/networkupstools/nut/milestone/10
Fix fallout of development in NUT v2.8.0 and/or v2.8.1:
INSTCMD
processing of commands without parameters nor
TRACKING
identifier. [#2155]
upsmon
recognition of CAL
state could linger after the calibration
activity was completed by the hardware, which led to mis-processing of
shutdown triggers. Also, notification was added to report "finished
calibration". [issue #2168, PR #2169]
upsmon
recognition of OFF
state as a trigger for FSD (forced shut
down) criticality considered also the input line state, which may be
an independently evolving circumstance. [issue #2278, PR #2279]
upsmon
support for POLLFAIL_LOG_THROTTLE_MAX
did not neuter the
applied setting when live-reloading configuration, so commenting it
away in upsmon.conf
did not have the effect of resetting the logging
frequency to default. It also did not reset the counters to certainly
follow the new configuration for existing faults. [issue #2207, PR #2209]
upsmon
support for POLLFAIL_LOG_THROTTLE_MAX
had an off-by-one error
(e.g. reporting "Data stale" or "Driver not connected" every 30 sec with
POLLFAIL_LOG_THROTTLE_MAX 5
and POLLFREQ 5
settings). [#2207]
user=root
in their configuration) failed to apply group ownership and permissions
to their Unix socket file for interaction with the local data server.
[#2185, #2096]
scripts/python/app/NUT-Monitor
referenced py3qt3
instead of the correct py3qt5
. It also tries to check both py2gtk2
and py3qt5
implementations verbosely, even if one is not installed.
[#2199, #2201]
DesktopFileName
in scripts/python/app/NUT-Monitor-py3qt5
,
this binds the application with the desktop file and allow the Open
Desktop compatible implementation to display the proper icon and
application name. [#2205]
apc_modbus
strictly required USB support even if
building NUT without it. [#2262]
CFLAGS
and CXXFLAGS
should again be honoured. [PR #2306]
configure
script option --with-debuginfo
. Note that default autoconf
behavior usually embeds moderate optimizations and debug information on
its own. [PR #2310]
usbhid-ups
subdriver belkin-hid
which in practice
relied on the broken older behavior; more details in its entry below.
[PR #2371]
nut-usbinfo.pl, nut-scanner and libnutscan:
libnutscan
was bumped from 2.2.0 to 2.5.0
during evolution of this NUT release.
alt_driver_names
in nutscan_device_t
structure
for ability to suggest a comment with other possibly compatible driver
names in configuration snippets generated by nut-scanner
; practical
support implemented for USB connected drivers.
comment_tag
and a method to nutscan_add_commented_option_to_device()
, instead of
hacks in prepared config data which broke some use-cases. [#2221]
-U
for USB scan can now be specified several times
to increase the detail level about hardware link to the device (this was
previously always suggested, but may be not reliable if USB enumeration
gets changed over time). [#2221]
$datadir
e.g. /usr/local/share/nut
and need to be pasted into your /boot/loader.conf.local
). [#2159]
nutdevN
device section names
when called separately to scan different media buses (one at a time).
Now the "bus" name would be embedded (e.g. non-colliding nutdev-usb1
and nutdev-snmp1
). [#2247]
.dev
and .seq
files) located in your sysconfig directory, and prepare configuration
sections with the simulation driver (currently dummy-ups
). [#2246]
dummy-ups
as driver when scanning NUT "bus"
with Old or Avahi method. [#2236, #2245]
ALLOW_NOT_ALL_LISTENERS
setting was added to control this behavior. [#723]
NUT CI improvements:
ccache
namespace concept, where possible. [#2256]
--without-usb
. [#2263]
libgd
discovery (for CGI etc. builds). [#2287]
aspell
TeX module detection more reliable. [#2206]
main driver core codebase:
nutdrv_qx
built for serial-only support), and built
in fact without USB support but used for USB devices, with some more
information to make troubleshooting easier. [issue #2259, PR #2260]
-D
CLI option and/or
the NUT_DEBUG_LEVEL
environment variable now check those earlier in
their life-time, so that initialization routine can be debugged. [#2259]
usb_config_index
usb_hid_rep_index
, usb_hid_desc_index
, usb_hid_ep_in
and
usb_hid_ep_out
hardware connection settings via ups.conf
options.
This is treated as experimental, not all code paths may be actually
using such values from struct usb_communication_subdriver_t
rather
than hard-coded defaults. Discovery of correct values is up to the
user at the moment (using lsusb
, internet search, luck…) [#2149]
nut-driver-enumerator (NDE) service/script:
--daemon-after
variant which parses the configuration once before
daemonization and this has a chance to fail while not forked off, as
well as to allow only completing the service unit initialization when
everything is actually ready to work (so further dependencies can start
at the proper time). [#682]
ups.conf
. [PR #2297, issues #2282 and #2258]
snmp-ups driver:
usbhid-ups driver:
arduino-hid
subdriver was enhanced from "initial bare bones" experimental
set of mapped data points to support some 20 more mappings to make it more
useful as an UPS driver, not just a controller developer sandbox. [#2188]
cps-hid
subdriver now supports devices branded as Cyber Energy and built
by cooperation with Cyber Power Systems. [#2312]
belkin-hid
subdriver now supports Liebert PSI5 devices which have a
different numeric reading scale than earlier handled models. [issue #2271,
PR #2272, PR #2369] Generally the wrong-scale processing was addressed,
including a regression in NUT v2.8.0 which led to zero values
in voltage data points which NUT v2.7.4 reported well [#2371]
onlinedischarge
configuration flag name was too ambiguous and got
deprecated (will be supported but no longer promoted by documentation),
introducing onlinedischarge_onbattery
as the meaningful alias. [#2213]
OL+DISCHRG
state should now be throttled
(see the driver manual page for more details) [#2214, #2215]:
battery.charge
is available, make the message when entering the
state and then only if the charge differs from that when we posted
the earlier message (e.g. really discharging) and is under
onlinedischarge_log_throttle_hovercharge
value (defaults to 100%);
onlinedischarge_log_throttle_sec
, by default 30 sec if battery.charge
is not reported by the device (should be frequent by default, in case
the UPS-reported state combination does reflect a bad power condition).
nutdrv_qx driver:
battery_voltage_reports_one_pack
configuration flag
introduced in NUT v2.8.1. [originally by PR #1279; fixed by PR #2324,
issue #2325]
tools/gitlog2changelog.py.in
script was revised, in particular to
convert section titles (with contributor names coming from Git metadata)
into plain ASCII character set, for dblatex
versions which do not allow
diacritics and other kinds of non-trivial characters in sections. This can
cause successful builds of ChangeLog.pdf
file on more platforms, but at
expense of a semi-cosmetic difference in those names. [PR #2360, PR #2366]
https://github.com/networkupstools/nut/milestone/8
*.adoc
pattern
to facilitate automatic rendering in GitHub and IDE GUIs, and adding recipe
support for GitHub issue/PR links. This NEWS
file is now proper asciidoc
rendered into release-notes.pdf
(and HTML versions). [issue #1953, PR #2048]
Internally, the documents would use a new way to define cross-linking to
other pages and their chapters, to facilitate different renderers (including
GitHub UI), and file names created for "chunked HTML" documentation format
will no longer have the "chapter number, section number" format which is
not easy to maintain over time with independent builds of documentation
in NUT and the actual and historic snapshots for nut-website for example.
Chapter/Section names will be adapted to produce "chunked HTML" file names
instead. Documentation links rendered in GitHub UI should point to the HTML
pages served by a current iteration of the NUT website. [PR #226, PR #669]
configure --enable-spellcheck
toggle should add spelling checks
to make check
(by default, if tools are available) to facilitate quicker
acceptance of contributions. [#2067]
Published a new maintainer GPG key to sign tags and release artifacts, and possibly git commits as well, as part of solution for issue #1410. You can pull it from common OpenPGP servers with the following command:
:; gpg --recv-key DE0184DA7043DCF7 gpg: key DE0184DA7043DCF7: public key "Jim Klimov (Doing FOSS since last millennium) <jimklimov@gmail.com>" imported gpg: Total number processed: 1 gpg: imported: 1
as part of https://github.com/networkupstools/nut/issues/1410 solution.
Bug fixes for fallout possible due to "fightwarn" effort and other evolution in NUT v2.8.0 release:
upsdebugx()
and similar methods were converted to macros in #685
to avoid useless data manipulations and requests for logged information,
whose results would be ignored instantly because the debug level is
too low. As issue #1455 and PR #1495 found, in two cases the called
commands did "meaningfully" modify data — so without debug logs the
program misbehaved. A known regression for upscode2
driver; might
be or not be a problem with upsd
server in NUT v2.8.0 release,
fixed for NUT v2.8.1.
cyberpower-mib
(for snmp-ups
driver) sources was
arranged in NUT v2.8.0 release in a way that precluded the driver
logic from looking at all of its entries. Also a fix for instant
command definitions had in fact broken them due to other development.
Regressions fixed for NUT v2.8.1 [#1432, #2029]
dummy-ups
driver for NUT
v2.8.0 release misfired on some platforms. Regression fixed for NUT
v2.8.1 [#1420]
configure
script for custom builds [#1467]
upsdrvctl
can pass debugging level through to the launched
driver(s), they would by default stay in the foreground. This can
complicate (or simplify, when intentional) the management of service
instances. Now there are explicit upsdrvctl
options for choosing
this (-F
/-B
), although default behavior is retained. Note that
explicit foregrounding mode also keeps upsdrvctl
tool from exiting
and would not wait for one driver to complete initialization before
starting another in case of mass-management loop to start all drivers
(without specifying the single device) [#1759, #1806, #1875]
apcsmart
and apcsmart-old
handled invalid data too zealously
and aborted instead of skipping over it, like they did before [#2015]
riello_ser
and riello_usb
misfired [#2137]
libupsclient
parser of device
and host names to crash upon bad inputs (e.g. poorly resolved environment
variables in scripts). Now it should fail more gracefully [#2052]
configure --enable-inplace-runtime
option should set default values
for --sysconfdir
, --with-user
and --with-group
options to match an
existing NUT deployment — for users who are trying if a custom build
of recent codebase solves their practical issues. For "quick tests", a
shortcut operation ./ci_build.sh inplace
was added [#1714]
NUT_DEBUG_PID
envvar (presence) support was added to add current
process ID to tags with debug-level identifiers. This may be useful
when many NUT daemons write to the same console or log file. [#2118]
nutdrv_qx updates:
battery_voltage_reports_one_pack
driver option was added for devices
which "natively" report a battery.voltage
for a single battery pack or
cell, not for the whole assembly [#1279]
voltronic_qs_protocol
should now accept both "V" (as before)
and newly "H" dialects, which otherwise seem interchangeable [#1623]
armac
subdriver was enhanced to support devices with a different
response pattern than previously expected per initial contribution.
It was tested to work with Vultech V2000 and Armac PF1 series. [#1978]
nutdrv_qx and blazer updates:
usbhid-ups updates:
subdriver
configuration option, to select the
USB HID subdriver for the device manually where automatic match
does not suffice (e.g. new devices for which no vendorid
/productid
pair was built into any driver, or for different-capability devices
with same interface chips, notably "phoenixtec/liebert" and "mge") [#1369]
powerfactor
without a namespace (bug
in 2.8.0 release), fixed to outlet.powerfactor
usbhid-ups
driver should now reconnect if libusb
returned a
memory allocation error [#1422] (seen as "Can’t retrieve Report 0a:
Resource temporarily unavailable"), which can cause practical problems
in the field — the driver otherwise interpreted the situation as
ups.status
being OL OFF
and cut the power supply.
UPS.Battery.ManufacturerDate
to map
to battery.mfr.date
(not battery.date
which is the maintenance
replacement date) [#1644]
onlinedischarge_calibration
option for UPSes that report
OL+DISCHRG
when they are in calibration mode [#2104]
riello_usb updates:
upsid
to match the
specific device (not all firmware/hardware models support this) [#2075]
apcupsd-ups:
apc_modbus driver was introduced, to cover the feature gap between existing NUT drivers for APC hardware and the actual USB-connected devices (or their firmwares) released since roughly 2010, which deprecated standard USB HID support in favor of Modbus-based protocol which is used across the board (also with their network management cards). The new driver can monitor APC UPS devices over TCP and Serial connections, as well as USB with a patched libmodbus (check https://github.com/EchterAgo/libmodbus/commits/rtu_usb for now, PR pending). [#139, #2063]
dummy-ups:
repeater_disable_strict_start
option to disable the driver
exiting upon encountering any kind of error at startup (as repeater).
This option should allow for collective upsdrvctl
startup despite
individual target UPS to be repeated or upsd
not having come up yet.
[#2132]
NUT for Windows:
scripts/Windows/build-mingw-nut.sh
[#1489]
ci_build.sh
script and
Makefile
checks as used across the board for local developer builds,
Linux/illumos/FreeBSD/OpenBSD/… on dedicated NUT CI farm on Fosshost,
and MacOS on CircleCI [#1552]
snmp-ups updates:
ups.status
) between
Eaton UPSs, and rename mibs from pw
to eaton_pw_nm2
, and from
pxgx_ups
to eaton_pxg_ups
[#1715]
baytech-mib.c
subdriver: fixed baytech_outlet_status_info[]
set
of valid outlet status values [#1871]
cyberpower-mib.c
subdriver: support devices which report the shorter
Vendor OID as their sysOID, e.g. "CyberPower PowerPanel Personal" [#1997]
and support more data points including hardware status alarms [#1982]
bestfortress
driver shutdown handling was fixed to use a non-trivial
default timeout [#1820]
optiups
driver only gave accurate voltage information with 120VAC
models and assumed a 12V battery when calculating capacity. There is
a protocol command that gives a (fixed) voltage which correlates with
the voltage selection DIP switches on the back of the UPS, taking into
account whether it is a 120 or 240VAC model. Likewise, now the battery
capacity fix is applied globally, based on whether or not the battery
voltage is greater than 20V. [#2089]
GPIO drivers [#1855]:
generic_gpio_libgpiod
driver using libgpiod
backend was added
(defaults to be required on Linux, optional on other platforms)
make install
of PyNUT module and NUT-Monitor desktop
application [#1462, #1504]
riello_usb
and richcomm_usb
[#1763] and updated man pages
of all USB drivers using these options to include the same description
[#1766]
allow_duplicates
flag for common USB matching options which
may help monitor several related no-name devices (although without knowing
reliably which one is which… better than nothing) [#1756]
nut-scanner
program should now suggest same configuration fields as
those used by common USB matching options in (most of the) drivers, e.g.
adding "device" to the generated configuration section [#1790]
SIGTERM
quickly are now retried with
SIGKILL
[#1424]
driver.state
to help readers determine
whether it is initializing, reconnecting, or running regular loops [#1767]
LD_LIBRARY_PATH
as a preferred possible override
to built-in paths (note that most operating systems advise against setting
this variable unless troubleshooting, although other systems rely on it)
[#805]
upsdebugx()
should now be less
limited in the sizes of messages that they can print, such as path names
that may be quite long. Note that the OS methods manipulating the strings,
and receivers such as logging systems, may still impose limits of their own.
nut-scanner
usage and debug printouts now include the loadable library
search paths, to help troubleshooting especially in multi-platform builds;
pre-filtering of the built-in paths was introduced (to walk only existing
and unique directory names) [#317]
lt_dlopen()
implementation on the current
platform would find library files better [#805]
libltdl
in configure
script updated with fallback code to
find it on systems that deliver the library to /usr/local/lib
(e.g. on
FreeBSD) [#1577]
configure --with-nut-scanner
toggle was added, specifically
so that build environments requesting --with-all
but lack libltdl
would
abort and require either to install the dependency or explicitly forfeit
the tool (some distro packages missed it quietly in the past) [#1560]
nut-scanner
program should now by default warn about serial numbers
which do not make much sense (are duplicate, empty, all same character, etc)
[#1810]
usb_resetter
script
has been contributed to scripts/usb_resetter
(the script itself is tracked
externally on GitHub), along with a configuration example for Linux+systemd
[#1887]
Some fixes for builds on older OSes with less functional default system
shell interpreters - now autogen.sh
supports a CONFIG_SHELL
envvar
to inject its value into generated configure
script [#1736]
grep
with -E
support on Solaris as detailed
in https://github.com/networkupstools/nut/issues/1736 comments)
configure
script, reference init-script and packaging templates updated
to eradicate @PIDPATH@/nut
ambiguity in favor of @ALTPIDPATH@
for the
unprivileged processes vs. @PIDPATH@
for those running as root [#1719]
configure
script enhanced: --with-unmapped-data-points
option allows
to build SNMP and USB-HID subdrivers with entries discovered by the scripts
which generated them from data walks, but developers did not rename yet
to NUT mappings conforming to docs/nut-names.txt standards [#1699]
PyNUT.py version bumped to 1.5.0 with some improvements:
ListClients()
method fixed (was broken in many ways), and is now
CI-tested [#549]
DeviceLogin()
method added (mostly as aid to CI-test ListClients()
in a practically relevant manner, so far)
nutclient C++ library:
listDeviceClients()
and deviceGetClients(dev)
to Client
classes, and Device::getClients()
to match PyNUT capabilities [#549]
libnutclientstub
which is an
implementation of a NUT TCP client in C++ with in-memory data store.
upsclient C library:
NUT_QUIET_INIT_SSL
environment variable to hide
the infamous "Init SSL without certificate database" warning [#1662]
upsd.conf
listing of LISTEN
addresses was previously inverted
(the last listed address was applied first), which was counter-intuitive
and fixed for this release [#2012]
upsd
configured to listen on IPv6 addresses should handle only
IPv6 (and not IPv4-mappings) to avoid surprises and insecurity; it
will now warn if a host name resolves to several addresses (and will only
listen on the first hit, as before in such cases) [#2012]
LISTEN *
directives became specified, to try
handling both IPv4 and IPv6 "any" address (subject to upsd
CLI options
to only choose one, and to OS abilities). When both address families are
enabled, the upsd
data server will first try to open an IPv6 socket
asking for disabled IPv4-mapped IPv6 address support (if the OS honors
that), and then an IPv4 socket (which may fail if the IPv6 socket already
covers it anyway); in other words, you can end up with one or two separate
listening sockets. [#2012]
upsmon client changes include:
upsmon
behavior [#1761, #1680…], including new
ability to configure default POWERDOWNFLAG location — packagers are
encouraged to pick optimal location for their distributions (which
remains mounted at least read-only late in shutdown) and a new optional
POLLFAIL_LOG_THROTTLE_MAX setting [#529, #506]
upsmon
should now recognize OFF
and BYPASS
flags in ups.status
and report that these states begin or end. The OFF
state usually means
than an administrative action happened to power off the load, but the UPS
device is still alive and communicating (USB, SNMP, etc.); corresponding
MONITOR
'ed amount of power sources are considered not being "fed" for
the power value calculation purposes. The BYPASS
state is now treated
similarly to ONBATT
: currently this UPS "feeds" its load, but if later
communications fail, it is considered dead. This may have unintended
consequences for devices (or NUT drivers) that do not report these modes
correctly (e.g. an APC calibration routine seems to start with a few
seconds of "OFF" state), so the reported status is only considered as a
loss of feed if it persists for more than OFFDURATION
seconds. [#2044,
#2104]
SHUTDOWNEXIT no
configuration toggle for systems which
require a long time to stop their workload such as virtual machines.
Since the disconnection of a "secondary" client is treated by the
"primary" system as permission to proceed with its own shutdown and
power-off for the UPS, the original (now merely default) behavior to
call SHUTDOWNCMD
and immediately exit could be counter-productive.
An optional delay can also be introduced. [#2133]
upsmon
.
Extended Linux systemd support with optional notifications about daemon state (READY, RELOADING, STOPPING) and watchdog keep-alive messages [#1590]
NUT_QUIET_INIT_UPSNOTIFY=true
environment variable in init-scripts on platforms where such frameworks
are not expected. [#2136]
nut-server.service
as upsd.service
, and nut-monitor.service
as
upsmon.service
(so simple systemctl reload upsd
can work) [#1777]
BROADCAST (num)
keyword,
and a NOBROADCAST
as a shortcut for BROADCAST 0
. This allows clients
to toggle whether they want to receive send_to_all()
updates from a
driver, or only answers to requests they send [#1914]
make sockdebug
for easier developer access to the tool;
also if configure --with-dev
is in effect, it would now be installed to
the configured libexec
location. A man page was also added. [#1936]
Numerous daemons (upsd
, upsmon
, drivers, upsdrvctl
, upssched
)
which accepted -D
option for debug setting previously, now can also
honour a NUT_DEBUG_LEVEL=NUM
environment variable if no -D
arguments
were provided. Unlike those arguments, the environment variable does
not enforce that daemons run in foreground mode by default [#1915]
upssched
with enabled
debug does not stop reporting on stderr
! [#1965]
upssched
was discovered and fixed, where it ran a tight loop
stressing the CPU; it was presumably introduced between NUT v2.7.4 and
v2.8.0 releases [#1964, #1965]
# Set verbosity level 6: :; upsrw -s driver.debug=6 UPS # Set verbosity level 0 to disable the noise (even if debug_min is set): :; upsrw -s driver.debug=0 UPS1@localhost # Un-set the protocol override, honour CLI or config-file settings again: :; upsrw -s driver.debug=-1 remoteUPS@1.2.3.4
+
and a driver.killpower
instant command (for safety, must be unlocked by
driver.flag.allow_killpower
protocol setting or allow_killpower
configuration flag), which is now the first choice for driver -k
operations [#1917, #1923]
ups.conf
reloading in NUT drivers,
with a driver.reload-with-error
instant command (more commands and
signal handling may be available depending on platform), with a goal
of changing inconsequential settings like debug_min
for a running
driver. This can also benefit the drivers on systems managed by real-time
nut-driver-enumerator
and for simpler changes the drivers get only
reloaded and not redefined and restarted. Reload signals should also
be reasonably supported with upsdrvctl
tool. Relevant CLI options
for -c CMD
handing were added to drivers and upsdrvctl
, although
their availability may vary between operating systems [#1903, #1914, #1924]
SIGURG
(or SIGWINCH
on systems that lack
the former) on POSIX platforms to dump their current state information
and move on. Such report goes to stdout
of the driver process (may
be disconnected when background mode is used) — this can help with
troubleshooting [#1907]
main.c
code were enhanced to produce a libdummy_mockdrv.la
helper library during build (not intended to be installed nor distributed),
in order to facilitate creation of test programs which behave like a driver
[#1855]
size_t
, ssize_t
, uint16_t
,
time_t
etc.) in third-party client code that earlier sufficed to only
include NUT headers. Sort of regression by NUT 2.8.0 (note those consumers
still have to re-declare some numeric variable types used) [#1638, #1615]
COPYING
file was updated with licenses and attribution for certain
source code files and blocks coming from the Internet originally [#1758]
tools/gitlog2changelog.py.in
script was revised, in particular to
generate the ChangeLog
file more consistently with different versions
of Python interpreter, and without breaking the long file paths in the
resulting mark-up text [#1945, #1955]
Earlier discussions (mailing list threads, GitHub issues, etc.) could refer to this change set (too long in the making) as NUT 2.7.5.
DISABLE_WEAK_SSL=true
in upsd.conf to disable older/weaker
SSL/TLS protocols and ciphers: when NUT is built against relatively recent
versions of OpenSSL or NSS it will be restricted to TLSv1.2 or better.
For least-surprise, currently defaults to false
and complains in log
[PR #1043]
ALLOW_NO_DEVICE=true
(as an upsd.conf flag or environment
variable passed from caller of the program), to allow starting the data
server initially without any device configurations and reloading it later
to apply config changes on the fly [PR #766]
debug_min=NUM
setting (ups.conf, upsd.conf, upsmon.conf)
to specify the minimum debug verbosity for daemons. This allows "in-vivo"
troubleshooting of service daemons without editing init scripts or service
unit definitions.
synchronous
setting, which is the
new default now: auto
. Initially after driver start-up this mode
acts as the older default off
, but would fall back to on
in case
the driver fails to send reports to upsd
by overflowing the socket
buffer in async mode — so the next connections of this driver uptime
would be synchronized (potentially slower, but safer — blocking on
writes to the data server). This adaptation would primarily impact
and benefit devices with many (hundreds of) data points, such as
ePDUs and daisy chains. [issue #1309, PR #1315]
-F
/-B
), although default
behavior is retained. This change is used for simplified service unit
definitions.
Improvements for device discovery or driver "lock-picking", including general support for:
-s
option), to monitor a device which is not
detailed or mentioned in ups.conf
NUT_ALTPIDPATH
and NUT_STATEPATH
environment variables to override
the paths built into the driver binary [PR #473 and #507]
-d
option), to poll a device for one or
few (update_count ) loops, report discovered values (dump the data
tree in upsc-like format), and exit. This complements the nut-scanner
for finding and identifying devices.
support for new devices:
nutdrv_qx: several subdrivers added or improved, including:
snr
subdriver
in their ups.conf
settings because of USB chip using the same
values of VendorID/ProductID as fabula_subdriver, fuji_subdriver,
and krauler_subdriver.
add devices to HCL/DDL:
NUT-Monitor
name is retained for wrapper
script which calls one of these, such that the current system can execute
[PRs #1310, #1354]
usbhid-ups:
onlinedischarge
option for UPSes that report OL+DISCHRG
when wall power is lost [PR #811]
battery.mfr.date
for APC HID UPS [PR #1318]
snmp-ups:
input.phase.shift
variable
ondelay
(ups.delay.start
) and offdelay
(ups.delay.shutdown
) as timeticks support [PR #276]
nut-scanner: various improvements, including:
nobt
config parameter to skip battery check
on initialization/startup [PR #1256]
netxml-ups:
systemd support improvements:
PROTVER
as alias to NETVER
to report the protocol version in use.
Note that NUT codebase itself does not use this value and handles commands
and reported errors individually [issue #1347]
mode
as a driver argument, and separates the
notion of dummy-once
(new default for *.dev
files that do not change)
vs. dummy-loop
(legacy default for *.seq
and others) [issue #1385]
new protocol variables:
input.phase.shift
outlet.N.name
outlet.N.type
battery.voltage.cell.max
, battery.voltage.cell.min
battery.temperature.cell.max
, battery.temperature.cell.min
battery.status
battery.capacity.nominal
battery.date.maintenance
(and clarified purpose of battery.date
)
battery.packs.external
(and clarified purpose of battery.packs
)
experimental.*
namespace introduced [PR #1046] to facilitate
introduction of NUT drivers and their data points for which we do
not yet have concepts, or which the original driver contributors
did not map well per suitable NUT standards: this allows to balance
having those drivers available in the project vs. least surprise
for when the explicitly experimental names are changed to something
stable and standardized.
Proposed to track Date and Time values (still as "opaque strings") preferably in representations compatible to ISO-8601/RFC-3339 [PR #1076] (standards update; changes to actual codebase to be applied in the future)
Master/Slave terminology was deprecated in favor of Primary/Secondary
modes of upsmon
client:
upsd.users
and
upsmon.conf
) are supported as backwards-compatible settings,
but the obsoleted values are no longer documented.
upsmon
now
first trying to elevate privileges with PRIMARY <ups>
request,
and falling back to MASTER <ups>
just in case it talks to an
older build of an upsd
server.
net_master()
(as handler for MASTER
net command) in header and
C code for the sake of existing linked binaries, and returns the
OK MASTER-GRANTED
line to the older client that invoked it.
net_primary()
(as handler for PRIMARY
net command)
calls the exact same application logic, but returns OK PRIMARY-GRANTED
line to the client.
Build fixes:
pkg-config
to detect dependencies at configure time, as
well as fail-safe detection of presence of pkg-config (and its macros)
to survive and build without it too
upsdebugx()
were refactored as macros so there
is slightly less overhead when logging is disabled [PRs #685 and #1100]
--with-dev
and so may impact upsclient
and nutclient
(C++) consumers.
At the very least, binaries for those consumers should be rebuilt to remain
stable with NUT 2.8.0 and not mismatch int-type sizes and other arguments.
NUT command and variable naming scheme:
support for new devices:
snmp-ups:
Eaton:
macosx-ups:
nutdrv_qx:
nut-scanner:
solis:
usbhid-ups:
systemdsystemunitdir
nutdrv_qx:
tripplite_usb:
Eaton:
support for new devices:
support for new devices:
There was no public NUT 2.7.0 release.
macosx-ups: new OS X Power Sources meta-driver
support for new devices:
Space
to ~
(Reported by Sebastian Pohle, Alioth bug #313636, CVE-2012-2944)
A separate patch, which applies to any faulty version, is also available:
http://trac.networkupstools.org/projects/nut/changeset/3633
For more information, refer to the Common Vulnerabilities and Exposures:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-2944
support for new devices:
support for new devices:
NUT now provides a tool, called nut-scanner, to discover supported devices, both local and remote. nut-scanner will help to ease the configuration step, and power infrastructure discovery. This development, sponsored by Eaton, supports the following methods:
support for new devices:
support for new devices:
Per original semantic versioning, there were no public NUT 2.5.x releases.
--with-doc
option help of configure
script, and
docs/configure.txt for more information.
support for new devices:
support for new devices:
support for new devices:
Per original semantic versioning, there were no public NUT 2.3.x releases.
preliminary support for Power Distribution Units (PDUs): NUT can now support PDUs, either natively (ie using NUT snmp-ups driver), or through a binding to the Powerman daemon. The list of supported PDUs is already quite long, including:
support for new devices:
support for new devices:
Per original semantic versioning, there were no public NUT 2.1.x releases.
support for new devices:
This release is a backport of the development version. Many changes have already been backported previously. Thus it is more a synchronization release, though it includes many bugfixes and support for new models.
support for new devices:
The fentonups driver now recognizes several more Megatec protocol units:
MONITOR ups-1@host-1 ... MONITOR ups-1@host-2 ... MONITOR ups-2@host-2 ... MONITOR ups-3@host-3 ...
More ancient history is not covered in detail here.
You can see docs/history.txt for more details.
This file lists changes that affect users who installed older versions of this software. When upgrading from an older version, be sure to check this file to see if you need to make changes to your system.
For packaging (OS distribution or in-house) it is recommended to
primarily ./configure --with-all
and then excise --without-something
explicitly for items not supported on your platform, so you do not miss
out on new NUT features as they come with new releases. Some may require
that you update your build environment with new third-party dependencies,
so a broken build of a new NUT release would let you know how to act.
This is a good time to point out that for stricter packaging systems, it may
be beneficial to add --enable-option-checking=fatal
to the ./configure
command line, in order to quickly pick up any other removed option flags.
language standard revision via
CFLAGS
and CXXFLAGS
should again be honoured. There was a mishap
with the m4
scripting for autoconf
which could have caused use of
C11/C
11 if compiler supported it, regardless of a request. [PR #2306]
$datadir
e.g. /usr/local/share/nut
and need to be pasted into your /boot/loader.conf.local
). [#2159]
bus
, busport
and device
values when generating device configurations by default. They may
appear as comments, or enabled by specifying the -U
command-line
option several times. [#2221]
tools/gitlog2changelog.py.in
script was revised, in particular to
convert section titles (with contributor names) into plain ASCII character
set, for dblatex
versions which do not allow diacritics and other kinds
of non-trivial characters in sections. A number of other projects seem to
use the NUT version of the script, and are encouraged to look at related
changes in configure.ac
and Makefile.am
recipes. [PR #2360, PR #2366]
*.adoc
pattern. Newly, a release-notes.pdf
and HTML
equivalents are generated. Packages which deliver documentation may need
to update the lists of files to ship. [#1953] Developers may be impacted
by new configure --enable-spellcheck
toggle (should add spelling checks
to make check
by default, if tools are available) to facilitate quicker
acceptance of contributions. Packaging systems may now want to explicitly
disable it, if it blocks package building (pull requests to update the
docs/nut.dict
are a better and welcome solution). [#2067]
Several improvements regarding simultaneous support of USB devices that were previously deemed "identical" and so NUT driver instances did not start for all of them:
ups.conf
options for that [#1763], and man pages were
updated to reflect that [#1766];
nut-scanner
tool should suggest these options in its generated
device configuration [#1790]: hopefully these would now suffice for
sufficiently unique combinations;
nut-scanner
tool should also suggest sanity-check violations
as comments in its generated device configuration [#1810], e.g. bogus
or duplicate serial number values;
allow_duplicates
flag (caveat emptor!) which may help monitor several related no-name
devices on systems that do not discern "bus" and "device" values
(although without knowing reliably which one is which… sometimes it
is better than nothing) [#1756].
int
type). Now such
entities are named TYPE_FD
, TYPE_FD_SER
or TYPE_FD_SOCK
with some
helper macros to name and determine "invalid" values (closed file, etc.)
Some of these changes happened in NUT header files, and at this time it
was not investigated whether the set of files delivered for third-party
code integration (e.g. C/C++ projects binding with libnutclient
or
`libupsclient) is consistent or requires additional definitions/files.
If something gets broken by this, it is a bug to address in future [#1556]
Further revision of public headers delivered by NUT was done, particularly
to address lack of common data types (size_t
, ssize_t
, uint16_t
,
time_t
etc.) in third-party client code that earlier sufficed to only
include NUT headers. Sort of regression by NUT 2.8.0 (note those consumers
still have to re-declare some numeric variable types used) [#1638]
make install
of PyNUT module and NUT-Monitor desktop
application — such activity was earlier done by packages directly; now
the packaging recipes may use NUT source-code facilities and package just
symlinks as relevant for each distro separately [#1462, #1504]
upsd.conf
listing of LISTEN
addresses was previously inverted
(the last listed address was applied first), which was counter-intuitive
and fixed for this release. If user configurations somehow relied on this
order (e.g. to prioritize IPv6 vs IPv4 listeners), configuration changes
may be needed. [#2012]
upsd
configured to listen on IPv6 addresses should handle only
IPv6 (and not IPv4-mappings like it might have done before) to avoid
surprises and insecurity — if user configurations somehow relied on
this dual support, configuration changes may be needed to specify both
desired IP addresses. Note that the daemon logs will now warn if a
host name resolves to several addresses (and will only listen on the
first hit, as it did before in such cases). [#2012]
LISTEN *
directives became specified, to try
handling both IPv4 and IPv6 "any" address (subject to upsd
CLI options
to only choose one, and to OS abilities). This use-case may be practically
implemented as a single IPv6 socket on systems with enabled and required
IPv4-mapped IPv6 address support, or as two separate listening sockets -
logged messages to this effect (e.g. inability to listen on IPv4 after
opening IPv6) are expected on some platforms. End-users may also want to
reconfigure their upsd.conf
files to remove some now-redundant LISTEN
lines. [#2012]
make sockdebug
for easier developer access to the tool;
also if configure --with-dev
is in effect, it would now be installed to
the configured libexec
location. A man page was also added. [#1936]
--with-gpio
configure script option) -
this may impact packaging decisions on some (currently Linux released 2018+)
distributions going forward [#1855]
configure --with-nut-scanner
toggle was added, specifically
so that build environments requesting --with-all
but lacking libltdl
would abort and require the packager either to install the dependency
or explicitly forfeit building the tool (some distro packages missed it
quietly in the past) [#1560]
upsdebugx_report_search_paths()
method in NUT common code was added,
and exposed in libnutscan.so
builds in particular - API version for the
public library was bumped [#317]
Some environment variable support was added to NUT programs, primarily aimed at wrappers such as init scripts and service unit definitions, allowing to tweak what (and whether) they write into debug traces, and so "make noise" or "bring invaluable insights" to logs or terminal:
NUT_DEBUG_LEVEL=NUM
envvar allows to temporarily boost debugging
of many daemons (upsd
, upsmon
, drivers, upsdrvctl
, upssched
)
without changes to configuration files or scripted command lines. [#1915]
NUT_DEBUG_PID
envvar (presence) support was added to add current
process ID to tags with debug-level identifiers. This may be useful
when many NUT daemons write to the same console or log file, such as
in containers/plugins for Home Assistant, storage appliances, etc. [#2118]
NUT_QUIET_INIT_SSL
envvar (presence or "true" value) prevents
libupsclient
consumers (notoriously upsc
) from reporting whether
they have initialized SSL support. [#1662]
NUT_QUIET_INIT_UPSNOTIFY
envvar (presence or "true" value)
prevents daemons which can notify service management frameworks (such
as systemd) about passing their lifecycle milestones, to not report
loudly if they could not do so (e.g. running on a system without a
framework, or misconfigured so they could not report and the OS would
restart the false-positively "unresponsive" service). [#2136]
configure
script, reference init-script and packaging templates updated
to eradicate @PIDPATH@/nut
ambiguity in favor of @ALTPIDPATH@
for the
unprivileged processes vs. @PIDPATH@
for those running as root [#1719]
configure
script can now be retained and installed by using the
--enable-keep_nut_report_feature
option; packagers are welcome to make
use of this, to better keep track of their deliveries [#1826, #1708]
Renamed generated nut-common.tmpfiles(.in) ⇒ nut-common-tmpfiles.conf(.in) to install a /usr/lib/systemd-tmpfiles/*.conf pattern [#1755]
WatchdogSec=
values are currently NOT pre-set into systemd
unit file templates provided by NUT, this is an exercise for end-users
based on sizing of their deployments and performance of monitoring station
[#1590, #1777]
mibs
)
were renamed: pw
is now eaton_pw_nm2
, and pxgx_ups
is eaton_pxg_ups
[#1715]
tools/gitlog2changelog.py.in
script was revised, in particular to
generate the ChangeLog
file more consistently with different versions
of Python interpreter, and without breaking the long file paths in the
resulting mark-up text. Due to this, a copy of this file distributed with
NUT release archives is expected to considerably differ on first glance
from its earlier released versions (not just adding lines for the new
release, but changing lines in the older releases too) [#1945, #1955]
nut-driver@instances
and the nut-driver-enumerator
to manage their population), as well as
updated Python 2 and Python 3 support (again, maybe dictating different
package groups) as detailed below.
--with-dev
and so may impact upsclient
and nutclient
(C++) consumers.
At the very least, binaries for those consumers should be rebuilt to remain
stable with NUT 2.8.0 and not mismatch int-type sizes and other arguments.
nutdrv_qx
framework
for USB and Serial connected devices, not as updates/clones of older e.g.
blazer
family and bestups
. Sources, man pages and start-up messages
of such older drivers were marked with "OBSOLETION WARNING".
do_convert_deci
flag. See
docs/man/netxml-ups.txt for details.
pkg-config
by
default (if present), rather than net-snmp-config(-32|-64)
script(s) as
the only option available previously. The scripts tend to specify a lot
of options (sometimes platform-specific) in suggested CFLAGS
and LIBS
compared to the packaged pkg-config
information which also works and is
more portable. If this change bites your distribution, please bring it up
in https://github.com/networkupstools/nut/issues or better yet, post a PR.
Also note that ./configure --with-netsnmp-config(=yes)
should set up the
preference of the detected script over pkg-config
information, if both
are available, and --with-netsnmp-config=/path/name
would as well.
dummy-ups can now specify mode
as a driver argument, and separates the
notion of dummy-once
(new default for \*.dev
files that do not change)
vs. dummy-loop
(legacy default for *.seq
and others) [issue #1385]
*.dev
files to work as a looping sequence with a TIMER
keywords to change
values slowly; now such files should get processed to the end once.
Specify mode=dummy-loop
driver option or rename the data file used
in the port
option for legacy behavior.
Use/Test-cases which modified such files content externally should
not be impacted.
Python: scripts have been updated to work with Python 3 as well as 2.
NUT-Monitor
script
and nut-monitor.desktop
) are still delivered, but now cover a wrapper
script which detects the environment capabilities and launches the best
suitable UI implementation (if both are available).
[D#]
prefix to log entries with level > 0
so if any scripts or other tools relied on parsing those messages
making some assumptions, they should be updated
TRACKING
ID to be used with
an INSTCMD
or SET VAR
requests; for details see docs/net-protocol.txt
and docs/sock-protocol.txt
--with-augeas-lenses-dir
configure option.
killall -SIGUSR1 upslog
to any OB/OL script actions. This will force
upslog to write a log entry to catch short power transients.
upsd
forks, to work around issues in the
NSS library.
ACCESS is no longer supported in upsd.conf. Use ACCEPT and REJECT.
Old way:
ACCESS grant all adminbox ACCESS grant all webserver ACCESS deny all all
New way:
ACCEPT adminbox ACCEPT webserver REJECT all
Note that ACCEPT and REJECT can take multiple arguments, so this will also work:
ACCEPT adminbox webserver REJECT all
This page is an attempt to document how everything came together.
The Network UPS Tools team would like to warmly thank Russell Kroll.
Russell initially started this project, maintaining and improving it for over 8 years (1996 — mid 2005).
APC’s Powerchute was running on kadets.d20.co.edu (a BSD/OS box) with
SCO binary emulation. Early test versions ran in cron, pulled status
from the log files and wrote them to a .plan file. You could see the
results by fingering pwrchute@kadets.d20.co.edu
while it lasted:
Last login Sat May 11 21:33 (MDT) on ttyp0 from intrepid.rmi.net Plan: Welcome to the UPS monitor service at kadets.d20.co.edu. The Smart-UPS attached to kadets generated a report at 14:24:01 on 05/17/96. During the measured period, the following data points were taken: Voltage ranged from 115.0 VAC to 116.3 VAC. The UPS generated 116.3 VAC at 60.00 Hz. The battery level was at 27.60 volts. The load placed on the UPS was 024.9 percent. UPS temperature was measured at 045.0 degrees Celsius. Measurements are taken every 10 minutes by the upsd daemon. This report is generated by a script written by Russell Kroll<rkroll@kadets>. Modified for compatibility with the BSD/OS cron daemon by Neil Schroeder
This same status data could also be seen with a web browser, since we had rigged up a CGI wrapper script which called finger.
Initial tests with a freestanding non-daemon program provided a few basic status registers from the UPS. The 940-0024C cable was not yet understood, so this happened over the [attachment:apcevilhack.jpg evil two-wire serial hack].
Communicating with SMART-UPS 700 S/N WS9643050926 [10/17/96] Input voltage range: 117.6 VAC - 118.9 VAC Load is 010.9% of capacity, battery is charged to 100.0% of capacity
Note that today’s apcsmart driver still displays the serial number when it starts, since it is derived from this original code.
The first split daemon/client code was written. upsd spoke directly to the UPS (APC Smart models only) and communicated with upsc by sending binary structures in UDP datagrams.
The first CGI interface existed, but it was all implemented with shell scripts. The main script would call upsc to retrieve status values. Then it would cat a template file through sed to plug them into the page.
upsstats actually has since returned to using templates, despite having a period in the middle when it used hardcoded HTML.
The images were also created with shell scripts. Each script would call upsc to get the right value (utility, upsload, battcap). It then took the value, plugged it into a command file with sed, and passed that into fly, a program which used an interpreted language to create images. fly actually uses gd, just like upsimage does today.
This code later evolved into Smart UPS Tools 0.10.
Version 0.10 was released on March 10, 1998. It used the same design as the pre-release prototype. This made expansion difficult as the binary structure used for network communications would break any time a new variable was added. Due to byte-ordering and struct alignment issues, the code usually couldn’t talk over the network to a system with a different architecture. It was also hopelessly bound to one type of UPS hardware.
Five more releases followed with this design followed. The last was 0.34, released October 27, 1998.
Following a long period of inactivity and two months of prerelease testing versions, 0.40.0 was released on June 5, 1999. It featured a complete redesign and rewrite of all of the code. The layering was now in three pieces, with the single driver (smartups) separate from the server (upsd).
Clients remained separate as before and still used UDP to talk to the server, but they now used a text-based protocol instead of the brittle binary structs. A typical request like "REQ UTILITY" would be answered with "ANS UTILITY 120.0".
The ups-trust425-625 driver appeared shortly after the release of 0.40.0, marking the first expansion beyond APC hardware.
Over the months that followed, the backupspro driver would be forked from the smartups driver to handle the APC Back-UPS Pro line. Then the backups driver was written to handle the APC Back-UPS contact-closure models. These drivers would later be renamed and recombined, with smartups and backupspro becoming apcsmart, and backups became genericups.
The drivers stored status data in an array. At first, they passed this data to upsd by saving it to a file. upsd would reread this file every few seconds to keep a copy for itself. This was later expanded to allow shared memory mode, where only a stub would remain on the disk. The drivers and server then passed data through the shared memory space.
upsd picked up the ability to monitor multiple drivers on the system, and the "upsname@hostname" scheme was born. Access controls were added, and then the network code was expanded to allow TCP communications, which at this point were on port 3305.
Several visitors to the web page and subscribers to the mailing lists provided suggestions to rename the project. The old name no longer accurately described it, and it was perilously close to APC’s "Smart-UPS" trademark. Rather than risk problems in the future, the name was changed. Kern Sibbald provided the winner: Network UPS Tools, which captures the essence of the project and makes for great short tarball filenames: nut-x.y.z.tar.gz.
The new name was first applied to 0.42.0, released October 31, 1999.
This is also when the web pages moved from the old
http://www.exploits.org/~rkroll/smartupstools/
URL to the replacement
at http://www.exploits.org/nut/
to coincide with the name change.
More drivers were written and the hardware support continued to grow. upsmon picked up the concepts of what is now known as "primary" and "secondary", and could now handle environments where multiple systems get power from a single UPS.
Manager mode was added to allow changing the value of read/write variables in certain UPS models.
Up to this point, all of the drivers compiled into freestanding programs, each providing their own implementation of main(). This meant they all had to check the incoming arguments and act uniformly. Unfortunately, not all of the programs behaved the same way, and it was hard to document and use consistently. It also meant that startup scripts had to be edited depending on what kind of hardware was attached.
Starting in 0.45.0, released June 11, 2001, there was a new common core for
all drivers called main.c
. It provided the main function and called back to
the upsdrv_*
functions provided by the hardware-specific part of the drivers.
This allowed driver authors to focus on the UPS hardware without worrying about
the housekeeping stuff that needs to happen.
This new design provided an obvious way to configure drivers from one file, and
so ups.conf
was born. This eventually spawned upsdrvctl, and now all drivers
based on this common core could be started or stopped with one command. Startup
scripts now could contain "upsdrvctl start", and it didn’t matter what kind of
hardware or how many UPSes you had on one system.
Interestingly, at the end of this month, Arnaud Quette entered the UPS world, as a subcontractor of the now defunct MGE UPS SYSTEMS. This marked the start of a future successful collaboration.
During the 0.45.x series, both the old standalone drivers and the ones which had been converted to the common core were released together. Before the release of 0.50.0 on May 24, 2002, all of the old drivers were removed. While this shrank the list of supported hardware, it set the precedent for removing code which isn’t receiving regular maintenance. The assumption is that the code will be brought back up to date by someone if they actually need it. Otherwise, it’s just dead weight in the tree.
This change meant that all remaining drivers could be controlled with the
upsdrvctl
and ups.conf
, allowing the documentation to be greatly
simplified. There was no longer any reason to say "do this, unless you
have this driver, then do this".
IANA granted an official port number to the project, and the network code
switched to port 3493. It had previously been on 3305 which is assigned to
odette-ftp
. 3305 was probably picked in 1997 because it was the fifth
project to spawn from some common UDP server code.
After 0.50.1, the 0.99 tree was created to provide a tree which would receive nothing but bug fixes in preparation for the release of 1.0. As it turned out, very few things required fixing, and there were only three releases in this tree.
After nearly 5 years of having a 0.x version number, 1.0.0 was released on August 19, 2002. This milestone meant that all of the base features that you would expect to find were intact: good hardware support, a network server with security controls, and system shutdowns that worked.
The design was showing signs of wear from the rapid expansion, but this was intentionally ignored for the moment. The focus was on getting a good version out that would provide a reasonable base while the design issues could be addressed in the future, and I’m confident that we succeeded.
One day after the release of 1.0.0, 1.1.0 started the new development tree.
During that development cycle, the CGI programs were rewritten to use template
files instead of hard-coded HTML, thus bringing back the flexibility of the
original unreleased prototype from 5 years before. The multimon
was removed
from the tree, as the new upsstats
could do both jobs by loading different
templates.
A new client library called upsclient was created, and it replaced upsfetch. This new library only supported TCP connections, and used an opaque context struct to keep state for each connection. As a result, client programs could now do things that used multiple connections without any conflicts. This was done primarily to allow OpenSSL support, but there were other benefits from the redesign.
upsd and the clients could now use OpenSSL for basic authentication and encryption, but this was not included by default. This was provided as a bonus feature for those users who cared to read about it and enable the option, as the initial setup was complex.
After the 1.1 tree was frozen and deemed complete, it became the second stable tree with the release of 1.2.0 on November 5, 2002.
Following an extended period with no development tree, 1.3.0 got things moving again on April 13, 2003. The focus of this tree was to rewrite the driver-server communication layer and replace the static naming scheme for variables and commands.
Up to this point, all variables had names like STATUS, UTILITY, and OUTVOLT. They had been created as drivers were added to the tree, and there was little consistency. For example, it probably should have been INVOLT and OUTVOLT, but there was no OUTVOLT originally, so UTILITY was all we had. This same pattern repeated with ACFREQ — is it incoming or outgoing? — and many more.
To solve this problem, all variables and commands were renamed to a hierarchical scheme that had obvious grouping. STATUS became ups.status. UTILITY turned into input.voltage, and OUTVOLT is output.voltage. ACFREQ is input.frequency, and the new output.frequency is also now supported. Every other variable or command was renamed in this fashion.
These variables had been shared between the drivers and upsd as values. That is, for each name like STATUS, there was a #define somewhere in the tree with an INFO_ prefix that gave it a number. INFO_STATUS was 0x0006, INFO_UTILITY was 0x0004, and so on, with each name having a matching number. This number was stored in an int within a structure which was part of the array that was either written to disk or shared memory.
That structure had several restrictions on expansion and was dropped as the data sharing method between the drivers and the server. It was replaced by a new system of text-based messages over Unix domain sockets. Drivers now accepted a short list of commands from upsd, and would push out updates asynchronously. upsd no longer had to poll the state files or shared memory. It could just select all of the driver and client fds and act on events.
At the same time, the network protocol on port 3493 was overhauled to take advantage of the new naming scheme. The existing "REQ STATUS@su700", "ANS STATUS@su700 OL" scheme was showing signs of age, and it really only supported the UPS name (@su700) as an afterthought. The new protocol would now use commands like GET and LIST, leading to exchanges like "GET VAR su700 ups.status" and "VAR su700 ups.status OL". These responses contain enough data to stand alone, so clients can now handle them asynchronously.
On July 25, 2003, 1.4.0 was released. It contained support for both the old "REQ" style protocol (with names like STATUS), and the new "GET" style protocol (with names like ups.status). This tree is provided to bridge the gap between all of the old releases and the upcoming 2.0.
2.0 will be released without support for the old REQ/STATUS protocol. The hope is that client authors and those who have implemented their own monitoring software will use the 1.4 cycle to change to the new protocol. The 1.4 releases contain a lot of compatibility code to make sure both work at the same time.
1.5.0 forked from 1.4.0 and was released on July 29, 2003. The first changes were to throw out anything which was providing compatibility with the older versions of the software. This means that 1.5 and the eventual 2.0 will not talk to anything older than 1.4.
This tree continues to evolve with new serial routines for the drivers which are intended to replace the aging upscommon code which dates back to the early 0.x releases. The original routines would call alarm and read in a tight loop while fetching characters. The new functions are much cleaner, and wait for data with select. This makes for much cleaner code and easier strace/ktrace logs, since the number of syscalls has been greatly reduced.
There has also been a push to make sure the data from the UPS is well-formed and is actually usable before sending updates out to upsd. This started during 1.3 as drivers were adapted to use the dstate functions and the new variable/command names. Some drivers which were not converted to the new naming scheme or didn’t do sanity checks on the incoming UPS data from the serial port were dropped from the tree.
This tree was released as 2.0.0.
The old network code spans a range from about 0.41.1 when TCP support was introduced up to the recent 1.4 series. It used variable names like STATUS, UTILITY, and LOADPCT. Many of these names go back to the earliest prototypes of this software from 1997. At that point there was no way to know that so many drivers would come along and introduce so many new variables and commands. The resulting mess grew out of control over the years.
During the 1.3 development cycle, all variables and instant commands were renamed to fit into a tree-like structure. There are major groups, like input, output and battery. Members of those groups have been arranged to make sense - input.voltage and output.voltage compliment each other. The old names were UTILITY and OUTVOLT. The benefits in this change are obvious.
The 1.4 clients can talk to either type of server, and can handle either naming scheme. 1.4 servers have a compatibility mode where they can answer queries for both names, even though the drivers are internally using the new format.
When 1.4 clients talk to 1.4 or 2.0 (or more recent) servers, they will use the new names.
Here’s a table to make it easier to visualize:
Server version | ||||
---|---|---|---|---|
Client version | 1.0 | 1.2 | 1.4 | 2.0+ |
1.0 | yes | yes | yes | no |
1.2 | yes | yes | yes | no |
1.4 | yes | yes | yes | yes |
2.0+ | no | no | yes | yes |
Version 2.0, and more recent, do not contain backwards compatibility for the old protocol and variable/command names. As a result, 2.0 clients can’t talk to anything older than a 1.4 server. If you ask a 2.0 client to fetch "STATUS", it will fail. You’ll have to ask for "ups.status" instead.
Authors of separate monitoring programs should have used the 1.4 series to write support for the new variables and command names. Client software can easily support both versions as long as they like. If upsd returns ERR UNKNOWN-COMMAND to a GET request, you need to use REQ.
The bandwidth demands of a project like this have slowly been forcing me to offload certain parts to other servers. The download links have pointed offsite for many months, and other large things like certain UPS protocols have followed. As the traffic grows, it’s clear that having the project attached to exploits.org is not going to work.
The solution was to register a new domain and set up mirrors. There are two
initial web servers, with more on the way. The main project URL has changed
from http://www.exploits.org/nut/
to https://www.networkupstools.org.
The actual content is hosted on various mirrors which are updated regularly
with rsync, so the days of dribbling bits through my DSL should be over.
This is also when all of the web pages were redesigned to have a simpler look with fewer links on the left side. The old web pages used to have 30 or more links on the top page, and most of them vanished when you dropped down one level. The links are now constant on the entire site, and the old links now live in their own groups in separate directories.
The year 2004 was marked by a release slowdown, since Russell was busy with personal subjects. But the patches queue was still growing quickly.
At that time, the development process was still centralized. There was no revision control system (like the current Subversion repository), nor trackers to interact with NUT development. Russell was receiving all the patches and requests, and doing all the work on his own, including releases.
Russell was more and more thinking about giving the project leadership to Arnaud Quette, which finally happened with the 2.0.1 release in February 2005.
This marked a new era for NUT…
First, Arnaud aimed at opening up the development by creating a project on the Debian Alioth Forge. This allowed to build the team of hackers that Russell dreamed about. It also allows to ensure NUT’s continuation, whatever happens to the leader. And that would most of all boost the projects contributions.