diff --git a/Makefile.am b/Makefile.am index f570c0bf46..8261bad6ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -76,6 +76,7 @@ DISTCHECK_VALGRIND_FLAGS = --with-all=auto --with-ssl=auto --with-doc=skip --wit # Note: this rule uses envvar DISTCHECK_FLAGS expanded at run-time DISTCHECK_CONFIGURE_FLAGS = ${DISTCHECK_FLAGS} \ --with-systemdsystemunitdir='$${prefix}/lib/systemd/system' \ + --with-systemdsystempresetdir='$${prefix}/usr/lib/systemd/system-preset' \ --with-systemdshutdowndir='$${prefix}/lib/systemd/system-shutdown' \ --with-systemdtmpfilesdir='$${prefix}/usr/lib/tmpfiles.d' \ --with-augeas-lenses-dir='$${prefix}/usr/share/augeas/lenses' \ diff --git a/NEWS.adoc b/NEWS.adoc index 678d06328c..7bec29669c 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -329,6 +329,8 @@ https://github.com/networkupstools/nut/milestone/11 should be handled similar (avoid stale UPS data and rash decisions) for summer/winter time change on non-UTC deployments, a debugger suspending the `upsmon` process, etc. [#2597] + * Introduced delivery of default systemd presets (lists of enabled/disabled + units). [#2721] - gamatronic driver revised for safer memory operations; this was reported to have fixed a Segmentation Fault seen in earlier NUT releases with diff --git a/UPGRADING.adoc b/UPGRADING.adoc index 52b4fc831d..47c4a554b3 100644 --- a/UPGRADING.adoc +++ b/UPGRADING.adoc @@ -44,6 +44,11 @@ Changes from 2.8.2 to 2.8.3 Please use it, it immensely helps with community troubleshooting! [issue #1949] +- When packaging or custom-building for (Linux) distributions with systemd, + you can now take advantage of `nut-systemd.preset` file to enable or + disable certain NUT units by default; its comments document each choice. + [issue #2721] + - Reference packages prepared by `make package` should now separate the `PACKAGE_VERSION` from the platform-dependent prefix by a dash character in the ultimate package file name. Previously they were glued together diff --git a/clients/upslog.c b/clients/upslog.c index 33b8505822..4b88cd9421 100644 --- a/clients/upslog.c +++ b/clients/upslog.c @@ -157,10 +157,15 @@ static void help(const char *prog) printf(" -F - stay foregrounded even if logging into a file\n"); printf(" -B - stay backgrounded even if logging to stdout\n"); printf(" -p - Base name for PID file (defaults to \"%s\")\n", prog); + printf(" - NOTE: PID file is written regardless of fore/back-grounding\n"); printf(" -s - Monitor UPS - @[:]\n"); printf(" - Example: -s myups@server\n"); printf(" -m - Monitor UPS \n"); printf(" - Example: -m myups@server,/var/log/myups.log\n"); + printf(" - NOTE: You can use '-' as logfile for stdout\n"); + printf(" and it would not imply foregrounding\n"); + printf(" - NOTE: '-s ups' and/or '-l file' options are ignored\n"); + printf(" if tuples are used, but you can specify many tuples\n"); printf(" -u - Switch to if started as root\n"); printf(" -V - Display the version of this software\n"); printf(" -h - Display this help text\n"); diff --git a/configure.ac b/configure.ac index 24e79b7b73..b8155a7184 100644 --- a/configure.ac +++ b/configure.ac @@ -3997,11 +3997,17 @@ AC_ARG_WITH([systemdsystemunitdir], case "${systemdsystemunitdir}" in yes|auto|"") AS_IF([test x"$have_PKG_CONFIG" = xyes], - [systemdsystemunitdir="`$PKG_CONFIG --variable=systemdsystemunitdir systemd 2>/dev/null`" && test -n "$systemdsystemunitdir" || systemdsystemunitdir="`$PKG_CONFIG --variable=systemdsystemunitdir libsystemd 2>/dev/null`"], - [AS_IF([test "${systemdsystemunitdir}" = yes], + [def_systemdsystemunitdir="`$PKG_CONFIG --variable=systemdsystemunitdir systemd 2>/dev/null`" && test -n "$def_systemdsystemunitdir" || \ + def_systemdsystemunitdir="`$PKG_CONFIG --variable=systemdsystemunitdir libsystemd 2>/dev/null`" || def_systemdsystemunitdir=""], + [def_systemdsystemunitdir=""]) + + AS_IF([test x"${def_systemdsystemunitdir}" = x], [ + AS_IF([test "${systemdsystemunitdir}" = yes], [AC_MSG_ERROR([--with-systemdsystemunitdir=${systemdsystemunitdir} was requested, but PKG_CONFIG could not be queried for the system settings])]) - systemdsystemunitdir="" - ]) + systemdsystemunitdir="" + ], [systemdsystemunitdir="${def_systemdsystemunitdir}"]) + + unset def_systemdsystemunitdir ;; no) systemdsystemunitdir="" @@ -4029,6 +4035,48 @@ dnl This option is only provided so that make distcheck can override it, dnl otherwise we ask pkg-config whenever --with-systemdsystemunitdir is dnl given +dnl Similarly for presets (list of svcs enabled/disabled by default) +AC_MSG_CHECKING(whether to install systemd preset files) +AC_ARG_WITH([systemdsystempresetdir], + [AS_HELP_STRING([--with-systemdsystempresetdir=DIR], [Directory for systemd preset files (auto)])], + [systemdsystempresetdir="${withval}"], + [systemdsystempresetdir="auto"]) + +dnl Note: this option is enabled only if systemdsystemunitdir is not trivial +if test -n "${systemdsystemunitdir}"; then + case "${systemdsystempresetdir}" in + yes|auto|"") + AS_IF([test x"$have_PKG_CONFIG" = xyes], + [def_systemdsystempresetdir="`$PKG_CONFIG --variable=systemdsystempresetdir systemd 2>/dev/null`" && test -n "$def_systemdsystempresetdir" || \ + def_systemdsystempresetdir="`$PKG_CONFIG --variable=systemdsystempresetdir libsystemd 2>/dev/null`" || def_systemdsystempresetdir=""], + [def_systemdsystempresetdir=""]) + + AS_IF([test x"${def_systemdsystempresetdir}" = x], [ + AS_IF([test "${systemdsystempresetdir}" = yes], + [AC_MSG_ERROR([--with-systemdsystempresetdir=${systemdsystempresetdir} was requested, but PKG_CONFIG could not be queried for the system settings])]) + systemdsystempresetdir="" + ], [systemdsystempresetdir="${def_systemdsystempresetdir}"]) + + unset def_systemdsystempresetdir + ;; + no) + systemdsystempresetdir="" + ;; + *) + AS_IF([test -d "${systemdsystempresetdir}"], [], + [AC_MSG_WARN([--with-systemdsystempresetdir='${systemdsystempresetdir}' was requested, but that location does not currently exist in build environment - just so you know...])]) + ;; + esac +fi +if test "${systemdsystempresetdir}" = "auto" ; then systemdsystempresetdir=""; fi +if test -n "${systemdsystempresetdir}"; then + AC_MSG_RESULT(using ${systemdsystempresetdir}) + NUT_REPORT_PATH_INTEGRATIONS([Service unit presets for systemd], [${systemdsystempresetdir}]) +else + AC_MSG_RESULT(no) +fi + +dnl Similarly for shutdown integration hooks AC_MSG_CHECKING(whether to install systemd shutdown files) AC_ARG_WITH([systemdshutdowndir], AS_HELP_STRING([--with-systemdshutdowndir=DIR], [Directory for systemd shutdown scripts (auto)]), @@ -4039,11 +4087,17 @@ if test -n "${systemdsystemunitdir}"; then case "${systemdshutdowndir}" in yes|auto|"") AS_IF([test x"$have_PKG_CONFIG" = xyes], - [systemdshutdowndir="`$PKG_CONFIG --variable=systemdshutdowndir systemd 2>/dev/null`" && test -n "$systemdshutdowndir" || systemdshutdowndir="`$PKG_CONFIG --variable=systemdshutdowndir libsystemd 2>/dev/null`"], - [AS_IF([test "${systemdshutdowndir}" = yes], + [def_systemdshutdowndir="`$PKG_CONFIG --variable=systemdshutdowndir systemd 2>/dev/null`" && test -n "$def_systemdshutdowndir" || \ + def_systemdshutdowndir="`$PKG_CONFIG --variable=systemdshutdowndir libsystemd 2>/dev/null`" || def_systemdshutdowndir=""], + [def_systemdshutdowndir=""]) + + AS_IF([test x"${def_systemdshutdowndir}" = x], [ + AS_IF([test "${systemdshutdowndir}" = yes], [AC_MSG_ERROR([--with-systemdshutdowndir=${systemdshutdowndir} was requested, but PKG_CONFIG could not be queried for the system settings])]) - systemdshutdowndir="" - ]) + systemdshutdowndir="" + ], [systemdshutdowndir="${def_systemdshutdowndir}"]) + + unset def_systemdshutdowndir ;; no) systemdshutdowndir="" @@ -4072,11 +4126,17 @@ AC_ARG_WITH([systemdtmpfilesdir], case "${systemdtmpfilesdir}" in yes|auto|"") AS_IF([test x"$have_PKG_CONFIG" = xyes], - [systemdtmpfilesdir="`$PKG_CONFIG --variable=tmpfilesdir systemd 2>/dev/null`" && test -n "$systemdtmpfilesdir" || systemdtmpfilesdir="`$PKG_CONFIG --variable=tmpfilesdir libsystemd 2>/dev/null`"], - [AS_IF([test "${systemdtmpfilesdir}" = yes], + [def_systemdtmpfilesdir="`$PKG_CONFIG --variable=tmpfilesdir systemd 2>/dev/null`" && test -n "$def_systemdtmpfilesdir" || \ + def_systemdtmpfilesdir="`$PKG_CONFIG --variable=tmpfilesdir libsystemd 2>/dev/null`" || def_systemdtmpfilesdir=""], + [def_systemdtmpfilesdir=""]) + + AS_IF([test x"${def_systemdtmpfilesdir}" = x], [ + AS_IF([test "${systemdtmpfilesdir}" = yes], [AC_MSG_ERROR([--with-systemdtmpfilesdir=${systemdtmpfilesdir} was requested, but PKG_CONFIG could not be queried for the system settings])]) - systemdtmpfilesdir="" - ]) + systemdtmpfilesdir="" + ], [systemdtmpfilesdir="${def_systemdtmpfilesdir}"]) + + unset def_systemdtmpfilesdir ;; no) systemdtmpfilesdir="" @@ -4167,6 +4227,8 @@ AS_IF([test x"${with_libsystemd}" = xyes && test x"${SYSTEMD_SUPPORTS_DAEMON_TYP dnl needed for `upsd -c reload` in legacy scripts and old habits to work: SYSTEMD_DAEMON_ARGS_UPSD="-FF" SYSTEMD_DAEMON_TYPE_UPSD="notify" + SYSTEMD_DAEMON_ARGS_UPSLOG="-F" + SYSTEMD_DAEMON_TYPE_UPSLOG="notify" SYSTEMD_DAEMON_ARGS_UPSMON="-F" SYSTEMD_DAEMON_TYPE_UPSMON="notify" SYSTEMD_DAEMON_ARGS_DRIVER="-FF" @@ -4183,29 +4245,36 @@ AS_IF([test x"${with_libsystemd}" = xyes && test x"${SYSTEMD_SUPPORTS_DAEMON_TYP SYSTEMD_DAEMON_NOTIFYACCESS_DRIVER="NotifyAccess=all" dnl Similar for UPSMON with its two processes: SYSTEMD_DAEMON_NOTIFYACCESS_UPSMON="NotifyAccess=all" - dnl UPSD is started directly by systemd and do not fork: + dnl UPSD is started directly by systemd and does not fork: SYSTEMD_DAEMON_NOTIFYACCESS_UPSD="NotifyAccess=main" + dnl Similarly for upslog (per settings above): + SYSTEMD_DAEMON_NOTIFYACCESS_UPSLOG="NotifyAccess=main" dnl Note: at this time we do not pre-define watchdog settings, dnl to avoid breaking something by a poorly hardcoded guess. dnl This is something end-users should do for their deployment, dnl especially for drivers SYSTEMD_DAEMON_WATCHDOG_DRIVER="#WatchdogSec=240s" SYSTEMD_DAEMON_WATCHDOG_UPSD="#WatchdogSec=240s" + SYSTEMD_DAEMON_WATCHDOG_UPSLOG="#WatchdogSec=240s" SYSTEMD_DAEMON_WATCHDOG_UPSMON="#WatchdogSec=240s" ], [ dnl "Usual" daemons that happen to be spawned by systemd SYSTEMD_DAEMON_ARGS_UPSD="-F" SYSTEMD_DAEMON_TYPE_UPSD="simple" + SYSTEMD_DAEMON_ARGS_UPSLOG="-F" + SYSTEMD_DAEMON_TYPE_UPSLOG="simple" SYSTEMD_DAEMON_ARGS_UPSMON="-F" SYSTEMD_DAEMON_TYPE_UPSMON="simple" SYSTEMD_DAEMON_ARGS_DRIVER="" SYSTEMD_DAEMON_TYPE_DRIVER="forking" SYSTEMD_DAEMON_NOTIFYACCESS_DRIVER="" SYSTEMD_DAEMON_NOTIFYACCESS_UPSD="" + SYSTEMD_DAEMON_NOTIFYACCESS_UPSLOG="" SYSTEMD_DAEMON_NOTIFYACCESS_UPSMON="" dnl Watchdog should not be configured for not-notifying units, right? SYSTEMD_DAEMON_WATCHDOG_DRIVER="#WatchdogSec=240s" SYSTEMD_DAEMON_WATCHDOG_UPSD="#WatchdogSec=240s" + SYSTEMD_DAEMON_WATCHDOG_UPSLOG="#WatchdogSec=240s" SYSTEMD_DAEMON_WATCHDOG_UPSMON="#WatchdogSec=240s" ]) @@ -4924,14 +4993,18 @@ AC_SUBST(LIBSYSTEMD_CFLAGS) AC_SUBST(LIBSYSTEMD_LIBS) AC_SUBST(SYSTEMD_DAEMON_ARGS_UPSD) AC_SUBST(SYSTEMD_DAEMON_TYPE_UPSD) +AC_SUBST(SYSTEMD_DAEMON_ARGS_UPSLOG) +AC_SUBST(SYSTEMD_DAEMON_TYPE_UPSLOG) AC_SUBST(SYSTEMD_DAEMON_ARGS_UPSMON) AC_SUBST(SYSTEMD_DAEMON_TYPE_UPSMON) AC_SUBST(SYSTEMD_DAEMON_ARGS_DRIVER) AC_SUBST(SYSTEMD_DAEMON_TYPE_DRIVER) AC_SUBST(SYSTEMD_DAEMON_NOTIFYACCESS_DRIVER) AC_SUBST(SYSTEMD_DAEMON_NOTIFYACCESS_UPSD) +AC_SUBST(SYSTEMD_DAEMON_NOTIFYACCESS_UPSLOG) AC_SUBST(SYSTEMD_DAEMON_NOTIFYACCESS_UPSMON) AC_SUBST(SYSTEMD_DAEMON_WATCHDOG_UPSD) +AC_SUBST(SYSTEMD_DAEMON_WATCHDOG_UPSLOG) AC_SUBST(SYSTEMD_DAEMON_WATCHDOG_UPSMON) AC_SUBST(SYSTEMD_DAEMON_WATCHDOG_DRIVER) AC_SUBST(SYSTEMD_TMPFILES_PROGRAM) @@ -4972,6 +5045,7 @@ AC_SUBST(htmldocdir) AC_SUBST(htmlmandir) AC_SUBST(pkgconfigdir) AC_SUBST(systemdsystemunitdir) +AC_SUBST(systemdsystempresetdir) AC_SUBST(systemdshutdowndir) AC_SUBST(systemdtmpfilesdir) AC_SUBST(auglensdir) @@ -5592,7 +5666,9 @@ AC_CONFIG_FILES([ scripts/systemd/Makefile scripts/systemd/nut.target scripts/systemd/nut-common-tmpfiles.conf + scripts/systemd/nut-driver.target scripts/systemd/nut-driver@.service + scripts/systemd/nut-logger.service scripts/systemd/nut-monitor.service scripts/systemd/nut-server.service scripts/systemd/nut-driver-enumerator.service @@ -5602,6 +5678,7 @@ AC_CONFIG_FILES([ scripts/systemd/nut-driver-enumerator-daemon-activator.path scripts/Solaris/nut-driver-enumerator.xml scripts/Solaris/nut-driver.xml + scripts/Solaris/nut-logger.xml scripts/Solaris/nut-monitor.xml scripts/Solaris/nut-server.xml scripts/Solaris/nut.xml @@ -5638,6 +5715,7 @@ m4_foreach_w([SCRIPTFILE], [ scripts/upsdrvsvcctl/upsdrvsvcctl scripts/systemd/nutshutdown scripts/Solaris/svc-nut-server + scripts/Solaris/svc-nut-logger scripts/Solaris/svc-nut-monitor scripts/Solaris/precheck.py scripts/Solaris/preinstall diff --git a/docs/configure.txt b/docs/configure.txt index 84e74c5108..bf3228dd62 100644 --- a/docs/configure.txt +++ b/docs/configure.txt @@ -756,6 +756,21 @@ settings with pkg-config, or fail configuration if not possible. Use `--with-systemdsystemunitdir=no` to disable this feature altogether. + --with-systemdsystempresetdir=PATH + +Where to install Linux systemd unit presets (lists of services enabled +or disabled by default). Useless and harmless on other OSes, including +Linux distributions without systemd, just adding a little noise to the +configure script output. + +Use `--with-systemdsystempresetdir=auto` (default) to detect the settings +using pkg-config if possible. + +Use `--with-systemdsystempresetdir(=yes)` to require detection of these +settings with pkg-config, or fail configuration if not possible. + +Use `--with-systemdsystempresetdir=no` to disable this feature altogether. + --with-systemdshutdowndir=PATH Where to install Linux systemd unit definitions for shutdown handling. diff --git a/docs/man/upslog.txt b/docs/man/upslog.txt index 1f0b64efc0..478af0f9ac 100644 --- a/docs/man/upslog.txt +++ b/docs/man/upslog.txt @@ -22,6 +22,13 @@ variables that interest you, format them, and write them to a file. The default format string includes variables that are supported by many common UPS models. See the description below to make your own. +NOTE: Historically this daemon supported logging of data for one UPS system +(specified by the `-s` option) into one log file name or `stdout` (specified +by the `-l` option). Later it allowed to log several devices (each into its +destination) as specified by multiple `-m tuple` options. The two modes are +effectively exclusive of each other (single-UPS options are ignored if tuples +are also provided). + OPTIONS ------- @@ -70,6 +77,8 @@ Store the results in this file. + You can use "-" for stdout, but upslog will remain in the foreground by default. ++ +Ignored if you also provide `-m tuple` option(s). *-F*:: upslog will run in the foreground, regardless of logging target. @@ -80,11 +89,25 @@ upslog will run in the background, regardless of logging target. *-s* 'ups':: Monitor this UPS. The format for this option is +upsname[@hostname[:port]]+. The default hostname is "localhost". ++ +Ignored if you also provide `-m tuple` option(s). *-m* 'tuple':: -Monitor multiple UPSs. The format for this option is a tuple of -ups and logfile separated by commas. An example would be: -`upsname@hostname:9999,/var/log/nut/cps.log` +Monitor multiple UPSs (provided several instances of such option). ++ +Overrides the single-UPS settings passed by `-s` and `-l` options. ++ +The format for this option is a tuple of UPS system and log file +specification, separated by commas. An example would be: +---- +upsname@hostname:9999,/var/log/nut/cps.log +---- ++ +Tuples may specify `-` as the logfile, to emit messages on `stdout` +(e.g. to be collected by the system journal for services). ++ +Use of `stdout` via tuple-based logging specifications does not +imply that upslog will remain in the foreground by default. *-u* 'username':: diff --git a/docs/nut.dict b/docs/nut.dict index d003824ac9..74485ae569 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,4 +1,4 @@ -personal_ws-1.1 en 3274 utf-8 +personal_ws-1.1 en 3275 utf-8 AAC AAS ABI @@ -2966,6 +2966,7 @@ syslogd systemctl systemd systemdshutdowndir +systemdsystempresetdir systemdsystemunitdir systemdtmpfilesdir systemtest diff --git a/scripts/Solaris/.gitignore b/scripts/Solaris/.gitignore index 4d4f0e1425..2f18535250 100644 --- a/scripts/Solaris/.gitignore +++ b/scripts/Solaris/.gitignore @@ -7,9 +7,11 @@ /precheck.py /preproto.pl /svc-nut-server +/svc-nut-logger /svc-nut-monitor /nut-driver.xml /nut-driver-enumerator.xml +/nut-logger.xml /nut-monitor.xml /nut-server.xml /nut.xml diff --git a/scripts/Solaris/Makefile.am b/scripts/Solaris/Makefile.am index 93f4b625be..f3ba92eda1 100644 --- a/scripts/Solaris/Makefile.am +++ b/scripts/Solaris/Makefile.am @@ -8,12 +8,14 @@ PYTHON = @PYTHON@ SOLARIS_SMF_MANIFESTS = \ nut.xml \ nut-server.xml \ + nut-logger.xml \ nut-monitor.xml \ nut-driver.xml \ nut-driver-enumerator.xml SOLARIS_SMF_METHODSCRIPTS = \ svc-nut-server \ + svc-nut-logger \ svc-nut-monitor if WITH_SOLARIS_SMF diff --git a/scripts/Solaris/nut-logger.xml.in b/scripts/Solaris/nut-logger.xml.in new file mode 100644 index 0000000000..88ab145c49 --- /dev/null +++ b/scripts/Solaris/nut-logger.xml.in @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/Solaris/svc-nut-logger.in b/scripts/Solaris/svc-nut-logger.in new file mode 100755 index 0000000000..6623dda74a --- /dev/null +++ b/scripts/Solaris/svc-nut-logger.in @@ -0,0 +1,75 @@ +#!/sbin/sh + +# Trivial (better is yet to come) SMF method script to start nut services +# Adapted for OpenIndiana userland from init.d script template in NUT sources +# Adaptation copyright (C) 2016-2025 Jim Klimov + +if [ -z "$SMF_FMRI" ]; then + echo "$0 must be called in SMF context!" >&2 + exit 1 +fi + +# smf(5) +. /lib/svc/share/smf_include.sh || exit + +prefix="@prefix@" +NUT_DIR="@prefix@" +NUT_SBIN_DIR="${NUT_DIR}/sbin" +NUT_LIB_DIR="${NUT_DIR}/lib" +NUT_RUN_DIR="@ALTPIDPATH@" +CONFIG="@CONFPATH@/nut.conf" +DAEMON_CONFIG="@CONFPATH@/upslog.conf" +NUTUSER="@RUN_AS_USER@" +NUTGROUP="@RUN_AS_GROUP@" + +# We anticipate some tighter integration with SMF later: +#NUT_QUIET_INIT_UPSNOTIFY=true +#export NUT_QUIET_INIT_UPSNOTIFY + +if [ -f "$CONFIG" ] ; then + . "$CONFIG" +fi + +if [ -s "$DAEMON_CONFIG" ] ; then + . "$DAEMON_CONFIG" +else + echo "Daemon config file '$DAEMON_CONFIG' not found or populated, not starting anything" >&2 + exit $SMF_EXIT_ERR_CONFIG +fi + +ups_start () { + if [ "$MODE" = "none" ];then + echo "No NUT mode set, not starting anything" >&2 + exit $SMF_EXIT_ERR_CONFIG + fi + + if [ x"${UPSLOG_ARGS-}" = x ; then + echo "UPSLOG_ARGS not found or populated in configuration, not starting anything" >&2 + exit $SMF_EXIT_ERR_CONFIG + fi + + # Default rights inspired by NUT scripts/Solaris/postinstall.in + mkdir -p "@PIDPATH@" # (for privileged processes) + mkdir -p "$NUT_RUN_DIR" && \ + chown "root:$NUTGROUP" "$NUT_RUN_DIR" && \ + chmod 770 "$NUT_RUN_DIR" \ + || exit $SMF_EXIT_ERR_FATAL + + # Fork and background regardless of logging to a file or stdout (-) + LD_LIBRARY_PATH="${NUT_LIB_DIR}:$LD_LIBRARY_PATH" "${NUT_SBIN_DIR}"/upslog -B $UPSLOG_ARGS #> /dev/null 2>&1 +} + +case "$1" in +'start') + ups_start + ;; + +*) + echo "" + echo "Usage: '$0' {start}" + echo "" + exit $SMF_EXIT_ERR_CONFIG + ;; +esac + +exit $? diff --git a/scripts/systemd/.gitignore b/scripts/systemd/.gitignore index e56937b1e7..93843a6e1f 100644 --- a/scripts/systemd/.gitignore +++ b/scripts/systemd/.gitignore @@ -2,8 +2,11 @@ /nut-common-tmpfiles.conf.in /nut-common-tmpfiles.conf /nut.target +# Singular nut-driver.service is obsolete, help with old build workspaces: /nut-driver.service +/nut-driver.target /nut-driver@.service +/nut-logger.service /nut-monitor.service /nut-server.service /nutshutdown diff --git a/scripts/systemd/Makefile.am b/scripts/systemd/Makefile.am index 577456cb29..58ecac0f68 100644 --- a/scripts/systemd/Makefile.am +++ b/scripts/systemd/Makefile.am @@ -11,6 +11,7 @@ systemdsystemunit_DATA = \ nut-driver-enumerator-daemon-activator.service \ nut-driver-enumerator-daemon.service \ nut-driver@.service \ + nut-logger.service \ nut-monitor.service \ nut-server.service \ nut-driver.target \ @@ -24,7 +25,11 @@ endif !WITH_LIBSYSTEMD_INHIBITOR systemdtmpfiles_DATA = \ nut-common-tmpfiles.conf -EXTRA_DIST += nut-driver.target nut-sleep.service +systemdsystempreset_DATA = \ + nut-systemd.preset + +# Add files not generated from .in templates +EXTRA_DIST += nut-sleep.service nut-systemd.preset systemdshutdown_SCRIPTS = nutshutdown @@ -34,8 +39,11 @@ sbin_SCRIPTS = ../upsdrvsvcctl/upsdrvsvcctl else !HAVE_SYSTEMD EXTRA_DIST += \ - nut-driver@.service.in nut-monitor.service.in nut-sleep.service \ - nut-server.service.in nutshutdown.in nut-driver.target nut.target.in \ + nut.target.in nut-systemd.preset \ + nut-driver@.service.in nut-driver.target.in \ + nut-server.service.in \ + nut-logger.service.in nut-monitor.service.in \ + nut-sleep.service nutshutdown.in \ nut-driver-enumerator.path.in nut-driver-enumerator.service.in \ nut-driver-enumerator-daemon-activator.path.in \ nut-driver-enumerator-daemon-activator.service.in \ diff --git a/scripts/systemd/nut-driver-enumerator-daemon-activator.path.in b/scripts/systemd/nut-driver-enumerator-daemon-activator.path.in index 568216b714..f749da2213 100644 --- a/scripts/systemd/nut-driver-enumerator-daemon-activator.path.in +++ b/scripts/systemd/nut-driver-enumerator-daemon-activator.path.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ diff --git a/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in b/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in index 9a22a82f78..29a3a876e8 100644 --- a/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in +++ b/scripts/systemd/nut-driver-enumerator-daemon-activator.service.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ diff --git a/scripts/systemd/nut-driver-enumerator-daemon.service.in b/scripts/systemd/nut-driver-enumerator-daemon.service.in index 25c972a18c..5523f5b7cb 100644 --- a/scripts/systemd/nut-driver-enumerator-daemon.service.in +++ b/scripts/systemd/nut-driver-enumerator-daemon.service.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ diff --git a/scripts/systemd/nut-driver-enumerator.path.in b/scripts/systemd/nut-driver-enumerator.path.in index 2e63437af8..eff7a4ed22 100644 --- a/scripts/systemd/nut-driver-enumerator.path.in +++ b/scripts/systemd/nut-driver-enumerator.path.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ diff --git a/scripts/systemd/nut-driver-enumerator.service.in b/scripts/systemd/nut-driver-enumerator.service.in index 4a7930eef0..44d7028ada 100644 --- a/scripts/systemd/nut-driver-enumerator.service.in +++ b/scripts/systemd/nut-driver-enumerator.service.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ diff --git a/scripts/systemd/nut-driver.target b/scripts/systemd/nut-driver.target.in similarity index 92% rename from scripts/systemd/nut-driver.target rename to scripts/systemd/nut-driver.target.in index c22a593d68..a29e0ddb11 100644 --- a/scripts/systemd/nut-driver.target +++ b/scripts/systemd/nut-driver.target.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ diff --git a/scripts/systemd/nut-driver@.service.in b/scripts/systemd/nut-driver@.service.in index 4a439f2100..c8c245be4d 100644 --- a/scripts/systemd/nut-driver@.service.in +++ b/scripts/systemd/nut-driver@.service.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ diff --git a/scripts/systemd/nut-logger.service.in b/scripts/systemd/nut-logger.service.in new file mode 100644 index 0000000000..914566fc0d --- /dev/null +++ b/scripts/systemd/nut-logger.service.in @@ -0,0 +1,59 @@ +# Network UPS Tools (NUT) systemd integration +# Copyright (C) 2011-2025 by NUT contirbutors +# Distributed under the terms of GPLv2+ +# See https://networkupstools.org/ +# and https://github.com/networkupstools/nut/ + +[Unit] +Description=Network UPS Tools - optional logging daemon (for status collection and analysis) +# Log UPS values to a file for later collection and analysis +After=local-fs.target network.target nut-server.service +# Note: We do not specify Requires nut-server.service because +# the `upsd` daemon(s) may be running on a different machine +# (connected to the UPSes) than this client program. +# The "Wants" directive would try to start the nut-server but +# would not abort if that attempt fails for whatever reason. +Wants=nut-server.service +# Extending the unit does not require *this* file to be edited, you +# can instead drop in an additional piece of configuration, e.g. to +# require the logging client to only start after external networking +# is configured (usable IP addresses appear in the system) you can +# add a `/etc/systemd/system/nut-logger.service.d/network.conf` with: +# [Unit] +# Requires=network-online.target +# After=network-online.target +PartOf=nut.target +Before=nut.target ### not enabled by default, but ordered if enabled by user + +Documentation=man:upslog(8) +Documentation=@NUT_WEBSITE_BASE@/docs/man/upslog.html +Documentation=man:nut.conf(5) +Documentation=@NUT_WEBSITE_BASE@/docs/man/nut.conf.html + +# Should contain UPSLOG_ARGS=... (or a systemd drop-in could provide it) +# with a series of `-m upsname@server,logfile` definitions, where `logfile` +# may be `-` for stdout. See about more variants in man page. +ConditionPathExists=@CONFPATH@/upslog.conf + +[Service] +EnvironmentFile=-@CONFPATH@/nut.conf +EnvironmentFile=@CONFPATH@/upslog.conf +SyslogIdentifier=%N +ExecStartPre=-@SYSTEMD_TMPFILES_PROGRAM@ --create @systemdtmpfilesdir@/nut-common-tmpfiles.conf +ExecStartPre=/bin/test -n "${UPSLOG_ARGS-}" +ExecStart=@SBINDIR@/upslog @SYSTEMD_DAEMON_ARGS_UPSLOG@ $UPSLOG_ARGS +# NOTE: SIGHUP is supported to re-open the log file, +# which is the default systemd ReloadSignal +PIDFile=@PIDPATH@/upslog.pid +# With this program, the PID file always exists and "kill -TERM" in particular +# can be used from command-line or some legacy scripts, it causes a clean and +# intentional exit of the daemon (some other signals are also supported). +# Then systemd should not revive it - hence restart it only on failure: +Restart=on-failure +Type=@SYSTEMD_DAEMON_TYPE_UPSLOG@ +@SYSTEMD_DAEMON_WATCHDOG_UPSLOG@ +@SYSTEMD_DAEMON_NOTIFYACCESS_UPSLOG@ + +[Install] +# WantedBy=nut.target ### not enabled by default +Alias=upslog.service diff --git a/scripts/systemd/nut-monitor.service.in b/scripts/systemd/nut-monitor.service.in index fe615459f5..0799d14ee8 100644 --- a/scripts/systemd/nut-monitor.service.in +++ b/scripts/systemd/nut-monitor.service.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ diff --git a/scripts/systemd/nut-server.service.in b/scripts/systemd/nut-server.service.in index 545f7312cf..029001d4b7 100644 --- a/scripts/systemd/nut-server.service.in +++ b/scripts/systemd/nut-server.service.in @@ -1,5 +1,5 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ diff --git a/scripts/systemd/nut-sleep.service b/scripts/systemd/nut-sleep.service index bb93c8c832..73f30129ff 100644 --- a/scripts/systemd/nut-sleep.service +++ b/scripts/systemd/nut-sleep.service @@ -1,11 +1,11 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ # A rather blunt solution for system sleeping support, for cases where -# we can not use a native libssytemd "inhibitor interface". This helps +# we can not use a native libsystemd "inhibitor interface". This helps # avoid NUT shutting down a woken-up system just because its power state # was critical before the sleep, and a next-read timestamp was not seen # (deemed to be a stale UPS, meaning lost comms during critical state, diff --git a/scripts/systemd/nut-systemd.preset b/scripts/systemd/nut-systemd.preset new file mode 100644 index 0000000000..afe682920c --- /dev/null +++ b/scripts/systemd/nut-systemd.preset @@ -0,0 +1,65 @@ +# Network UPS Tools (NUT) systemd integration +# Copyright (C) 2011-2025 by NUT contirbutors +# Distributed under the terms of GPLv2+ +# See https://networkupstools.org/ +# and https://github.com/networkupstools/nut/ + +# This file enables a default selection of NUT systemd units, +# reasonable for a typical server with one or a few UPS devices +# (their drivers, NDE, and data server), and the upsmon client. +# Adapt to your system as needed. + +# There are several separate variants of NDE usage to process the +# "ups.conf" file and create/update/remove `nut-driver@.service` +# unit instances: +# * Manual run of `nut-driver-enumerator.sh (--reconfigure)` +# * Single run at system start-up (nut-driver-enumerator.service unit) +# ** perhaps additionally upon edits of the file (path unit), +# if it works (may get ignored on busy systems) +# * Daemon mode that runs once to update the nut-driver population, +# and then loops to to pick up any subsequent changes (maybe more +# reliably than the filesystem notification processing would allow). +# ** nut-driver-enumerator-daemon.service provides the daemon +# ** nut-driver-enumerator-daemon-activator.* units optionally +# reload it if "ups.conf" is edited (if the path unit does work) +# and apply changes without waiting for the inter-loop sleep. +# Typical systems do not monitor hordes of devices with a dynamically +# changing population of those (e.g. data center monitoring appliances), +# so the daemon mode is an overkill for these smaller use-cases. +disable nut-driver-enumerator-daemon-activator.path +disable nut-driver-enumerator-daemon-activator.service +disable nut-driver-enumerator-daemon.service +enable nut-driver-enumerator.path +enable nut-driver-enumerator.service + +# Activate systemd unit instances prepared by NDE (service above +# or a manual run of the script), each wrapping one NUT driver. +# Requires "ups.conf" with corresponding section for the device: +enable nut-driver.target +# I don't think a template can be activated/deactivated; anyhow +# this is NDE's bread and butter at run-time: +#enable nut-driver@.service + +# Activate the "upsd" data server, to represent drivers on the network. +# Requires "ups.conf", "upsd.conf", "upsd.users": +enable nut-server.service + +# Activate the "upsmon" client to shut down the local system. +# Can run on same or different system as the data server. +# Requires "upsmon.conf": +enable nut-monitor.service + +# Pull in activated units, to orchestrate their starting or stopping +# in one command: +enable nut.target + +# OPTIONAL: Normally NUT programs are built to use the native libsystemd +# "inhibitor interface" to gracefully handle clock jumps when the server +# sleeps and later wakes up. If this is not possible for whatever reason, +# this "sleep hook" unit provides a workaround (stop/start nut.target): +disable nut-sleep.service + +# OPTIONAL: Log snapshots of UPS state into a file (or stdout to +# systemd journal); needs an "upslog.conf" file defining tuples like +# UPSLOG_ARGS="-m ups,file -m ups,file..." +disable nut-logger.service diff --git a/scripts/systemd/nut.target.in b/scripts/systemd/nut.target.in index f44ac4dd87..1a58ef9986 100644 --- a/scripts/systemd/nut.target.in +++ b/scripts/systemd/nut.target.in @@ -1,14 +1,15 @@ # Network UPS Tools (NUT) systemd integration -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Distributed under the terms of GPLv2+ # See https://networkupstools.org/ # and https://github.com/networkupstools/nut/ [Unit] Description=Network UPS Tools - target for power device drivers, data server and monitoring client (if enabled) on this system -After=local-fs.target nut-driver.target nut-server.service nut-monitor.service +After=local-fs.target nut-driver.target nut-server.service nut-monitor.service nut-logger.service Wants=local-fs.target nut-driver.target nut-server.service nut-monitor.service # network.target +# nut-logger.service ### not enabled by default # TODO: Dedicated man pages? Documentation=man:ups.conf(@MAN_SECTION_CFG@) diff --git a/scripts/systemd/nutshutdown.in b/scripts/systemd/nutshutdown.in index 0c60ec9e64..4c3a0c8030 100755 --- a/scripts/systemd/nutshutdown.in +++ b/scripts/systemd/nutshutdown.in @@ -8,7 +8,7 @@ # and their configuration files to be present locally and on still-mounted # filesystems (may be read-only). # -# Copyright (C) 2011-2024 by NUT contirbutors +# Copyright (C) 2011-2025 by NUT contirbutors # Michal Hlavinka, Laurent Bigonville, Arnaud Quette, Jim Klimov et al. # # See https://networkupstools.org/