From 4bf06cdede50a84c8841f5e70c940397f9460429 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 10 Jan 2025 00:16:53 +0100 Subject: [PATCH 01/13] Makefile.am, configure.ac, NEWS.adoc: implement install-as-root [#1298] Signed-off-by: Jim Klimov --- Makefile.am | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++ NEWS.adoc | 4 ++ configure.ac | 5 ++ 3 files changed, 189 insertions(+) diff --git a/Makefile.am b/Makefile.am index eed7a7373a..9c70292dc9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -526,6 +526,186 @@ setver: @echo "Error: 'make setver' no longer exists." @echo "Edit configure.ac to set version number." +# Adjust permissions when installing as `root` into the actual system. +# We honour DESTDIR anyway, as someone can install into a chroot etc. +# NOTE: Might be an 'install-data-hook' (for dirs) and/or 'install-exec-hook' +# (for service restart) but better not force this on everyone? +# It is also up to the end-user making such an installation to remove (or not) +# dirs and files made below. +# To err on the safe side in cross builds, we ignore Windows builds and those +# not built for the same system as the build host. +install-data-hook: + @case "@target_os@" in *mingw*) exit 0;; esac ; \ + if [ x"@host_os@" != x"@build_os@" ]; then exit 0 ; fi ; \ + if [ x"@target_os@" != x"@build_os@" ]; then exit 0 ; fi ; \ + if (command -v id) && [ x"`id -u`" = x0 ] && [ x"$(DESTDIR)" = x -o x"$(DESTDIR)" = x/ ] ; then \ + echo "================================================================================" >&2 ; \ + echo "| NUT data files have been installed into the system, now consider running |" >&2 ; \ + echo "| '(sudo) make install-as-root' to apply permissions and service state changes |" >&2 ; \ + echo "================================================================================" >&2 ; \ + fi + +if HAVE_SYSTEMD +HAVE_SYSTEMD = true +else +HAVE_SYSTEMD = false +endif + +if WITH_SYSTEMD_TMPFILES +WITH_SYSTEMD_TMPFILES = true +else +WITH_SYSTEMD_TMPFILES = false +endif + +if WITH_SYSTEMD_PRESET +WITH_SYSTEMD_PRESET = true +else +WITH_SYSTEMD_PRESET = false +endif + +if WITH_CGI +WITH_CGI = true +else +WITH_CGI = false +endif + +if WITH_SOLARIS_SMF +WITH_SOLARIS_SMF = true +else +WITH_SOLARIS_SMF = false +endif + +if WITH_SOLARIS_INIT +WITH_SOLARIS_INIT = true +else +WITH_SOLARIS_INIT = false +endif + +# TODO: Actually move this into scripts like Solaris/postinstall +# using OS-specific `useradd`/`groupadd`, etc. +install-as-root: install + @case "@target_os@" in *mingw*) exit 0;; esac ; \ + if [ x"@host_os@" != x"@build_os@" ]; then exit 0 ; fi ; \ + if [ x"@target_os@" != x"@build_os@" ]; then exit 0 ; fi ; \ + prefix="@prefix@"; \ + if (command -v id) && [ x"`id -u`" = x0 ] ; then \ + if [ x"$(DESTDIR)" = x -o x"$(DESTDIR)" = x/ ] ; then \ + if $(HAVE_SYSTEMD) ; then \ + echo "$@: Stop NUT services, if any" >&2 ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ stop nut-monitor.service nut-server.service || true ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ stop nut-driver.service || true ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ stop nut-driver.target || true ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ stop nut.target || true ; \ + fi ; \ + if $(WITH_SOLARIS_SMF) || $(WITH_SOLARIS_INIT) ; then \ + if $(WITH_SOLARIS_SMF) ; then \ + echo "$@: Stop NUT services, if any" >&2 ; \ + SMF_ACTIVE="`/usr/bin/svcs -a -Hostate,fmri | grep svc:/system/power/ | grep -v disabled | awk '{print $$2}'`" ; \ + for S in $$SMF_ACTIVE ; do \ + /usr/bin/svcadm disable -ts $$S || true ; \ + done ; \ + fi ; \ + $(top_builddir)/scripts/Solaris/preremove && \ + $(top_builddir)/scripts/Solaris/preinstall && \ + $(top_builddir)/scripts/Solaris/postinstall ; \ + exit ; \ + fi ; \ + fi ; \ + echo " MKDIR $(DESTDIR)/@STATEPATH@ $(DESTDIR)/@STATEPATH@/upssched" >&2 ; \ + $(MKDIR_P) "$(DESTDIR)/@STATEPATH@/upssched" && \ + for D in "@PIDPATH@" "@ALTPIDPATH@" "@ALTSTATEPATH@" "@CONFPATH@" ; do \ + case x"$$D" in \ + x|x@*) ;; \ + *) echo " MKDIR $(DESTDIR)/$$D" >&2 ; \ + $(MKDIR_P) "$(DESTDIR)/$$D" \ + || exit ;; \ + esac ; \ + done ; \ + if (command -v chmod) ; then \ + echo " CHMOD(0770) $(DESTDIR)/@STATEPATH@ $(DESTDIR)/@STATEPATH@/upssched" >&2 ; \ + chmod 0770 "$(DESTDIR)/@STATEPATH@" "$(DESTDIR)/@STATEPATH@/upssched" \ + || exit ; \ + for D in "@PIDPATH@" "@ALTPIDPATH@" "@ALTSTATEPATH@" ; do \ + case x"$$D" in \ + x|x@*) ;; \ + *) echo " CHMOD(0770) $(DESTDIR)/$$D" >&2 ; \ + chmod 0770 "$(DESTDIR)/$$D" \ + || exit ;; \ + esac ; \ + done ; \ + echo " CHMOD(0751) $(DESTDIR)/@CONFPATH@" >&2 ; \ + chmod 0751 "$(DESTDIR)/@CONFPATH@" \ + || exit ; \ + for F in hosts.conf.sample upsstats-single.html.sample upsstats.html.sample upsset.conf.sample ; do \ + echo " CHMOD(0644) CGI: $(DESTDIR)/@CONFPATH@/$$F" >&2 ; \ + chmod 0644 "$(DESTDIR)/@CONFPATH@/$$F" \ + || { if $(WITH_CGI) ; then exit 1 ; else true ; fi ; } ; \ + done ; \ + for F in nut.conf.sample ups.conf.sample upsd.conf.sample upsd.users.sample upsmon.conf.sample upssched.conf.sample ; do \ + echo " CHMOD(0640) $(DESTDIR)/@CONFPATH@/$$F" >&2 ; \ + chmod 0640 "$(DESTDIR)/@CONFPATH@/$$F" \ + || exit ; \ + done ; \ + else \ + echo "$@: WARNING: Can not CHMOD created locations!" >&2 ; \ + fi ; \ + if (command -v chown) && test 0 -lt "`id -u '@RUN_AS_USER@'`" \ + && ( test 0 -lt "`getent group '@RUN_AS_GROUP@' | awk -F: '{print $$3}'`" || test 0 -lt "`id -g '@RUN_AS_GROUP@'`" ) \ + ; then \ + echo " CHOWN(@RUN_AS_USER@:@RUN_AS_GROUP@) $(DESTDIR)/@STATEPATH@ $(DESTDIR)/@STATEPATH@/upssched" >&2 ; \ + chown "@RUN_AS_USER@:@RUN_AS_GROUP@" "$(DESTDIR)/@STATEPATH@" "$(DESTDIR)/@STATEPATH@/upssched" \ + || exit ; \ + for D in "@PIDPATH@" "@ALTPIDPATH@" "@ALTSTATEPATH@" ; do \ + case x"$$D" in \ + x|x@*) ;; \ + *) echo " CHOWN(@RUN_AS_USER@:@RUN_AS_GROUP@) $(DESTDIR)/$$D" >&2 ; \ + chown "@RUN_AS_USER@:@RUN_AS_GROUP@" "$(DESTDIR)/$$D" \ + || exit ;; \ + esac ; \ + done ; \ + echo " CHOWN(root:@RUN_AS_GROUP@) $(DESTDIR)/@CONFPATH@" >&2 ; \ + chown "root:@RUN_AS_GROUP@" "$(DESTDIR)/@CONFPATH@" \ + || exit ; \ + for F in hosts.conf.sample upsstats-single.html.sample upsstats.html.sample upsset.conf.sample ; do \ + echo " CHOWN(root:@RUN_AS_GROUP@) CGI: $(DESTDIR)/@CONFPATH@/$$F" >&2 ; \ + chown "root:@RUN_AS_GROUP@" "$(DESTDIR)/@CONFPATH@/$$F" \ + || { if $(WITH_CGI) ; then exit 1 ; else true ; fi ; } ; \ + done ; \ + for F in nut.conf.sample ups.conf.sample upsd.conf.sample upsd.users.sample upsmon.conf.sample upssched.conf.sample ; do \ + echo " CHOWN(root:@RUN_AS_GROUP@) $(DESTDIR)/@CONFPATH@/$$F" >&2 ; \ + chown "root:@RUN_AS_GROUP@" "$(DESTDIR)/@CONFPATH@/$$F" \ + || exit ; \ + done ; \ + else \ + echo "$@: WARNING: Can not CHOWN created locations!" >&2 ; \ + fi ; \ + if [ x"$(DESTDIR)" = x -o x"$(DESTDIR)" = x/ ] ; then \ + if $(HAVE_SYSTEMD) ; then \ + echo "$@: Activate default systemd layout, restart services:" >&2 ; \ + if $(WITH_SYSTEMD_TMPFILES) ; then \ + echo "$@: Apply systemd-tmpfiles presets" >&2 ; \ + @SYSTEMD_TMPFILES_PROGRAM@ --create || exit ; \ + fi ; \ + echo "$@: Learn systemd definition changes" >&2 ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ daemon-reload || exit ; \ + if $(WITH_SYSTEMD_PRESET) ; then \ + echo "$@: Apply systemd enabled/disabled service presets" >&2 ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ preset-all || exit ; \ + else \ + echo "$@: Apply systemd enabled/disabled service defaults" >&2 ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ disable nut.target nut-driver.target nut-monitor nut-server nut-driver-enumerator.path nut-driver-enumerator.service || exit ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ enable nut.target nut-driver.target nut-monitor nut-server nut-driver-enumerator.path nut-driver-enumerator.service || exit ; \ + fi ; \ + echo "$@: Reconfigure nut-driver-enumerator (service instance wrapping)" >&2 ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ restart udev || true ; \ + $(top_builddir)/scripts/upsdrvsvcctl/nut-driver-enumerator.sh --reconfigure || exit ; \ + echo "$@: Restart NUT services" >&2 ; \ + @SYSTEMD_SYSTEMCTL_PROGRAM@ restart nut-driver-enumerator.service nut-monitor.service nut-server.service || exit ; \ + fi ; \ + fi ; \ + echo "$@: finished" >&2 ; \ + fi + # Clean the dist tarball and packages MAINTAINERCLEANFILES_DISTBALL = nut-*.tar.gz # HP-UX: diff --git a/NEWS.adoc b/NEWS.adoc index 5953dc7f15..702fafc080 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -579,6 +579,10 @@ relocated into new `shutdown.default` INSTCMD definitions. [#2670] - Introduced a simple experiment to expose NUT client readings as filesystem objects via FUSE, in `scripts/fuse/execfuse-nut` now. [#2591] + - Introduced `make install-as-root` to create directories not directly + populated by `make install` and NUT build artifacts, apply permissions + and (on some platforms) restart services involved with NUT. [#1298] + Release notes for NUT 2.8.2 - what's new since 2.8.1 ---------------------------------------------------- diff --git a/configure.ac b/configure.ac index b8155a7184..15f43c490f 100644 --- a/configure.ac +++ b/configure.ac @@ -4035,6 +4035,8 @@ 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 +AC_PATH_PROG([SYSTEMD_SYSTEMCTL_PROGRAM], [systemctl], [/usr/bin/systemctl]) + dnl Similarly for presets (list of svcs enabled/disabled by default) AC_MSG_CHECKING(whether to install systemd preset files) AC_ARG_WITH([systemdsystempresetdir], @@ -4075,6 +4077,7 @@ if test -n "${systemdsystempresetdir}"; then else AC_MSG_RESULT(no) fi +AM_CONDITIONAL([WITH_SYSTEMD_PRESET], [test x"${systemdsystempresetdir}" != "x"]) dnl Similarly for shutdown integration hooks AC_MSG_CHECKING(whether to install systemd shutdown files) @@ -4115,6 +4118,7 @@ if test -n "${systemdshutdowndir}"; then else AC_MSG_RESULT(no) fi +AM_CONDITIONAL([WITH_SYSTEMD_SHUTDOWN], [test x"${systemdshutdowndir}" != "x"]) dnl Note: if (systemd-)tmpfiles tech is present, it can be useful even for dnl daemons starting not as systemd units, to pre-create /var/run/nut etc. @@ -4153,6 +4157,7 @@ if test -n "${systemdtmpfilesdir}"; then else AC_MSG_RESULT(no) fi +AM_CONDITIONAL([WITH_SYSTEMD_TMPFILES], [test x"${systemdtmpfilesdir}" != "x"]) dnl What pathname would we embed into unit files ExecStartPre? dnl TODO? Any need to make it a --with-... argument? From e78cdcc6bc7fd3fd4aa4122a7ad9d55a5d00615c Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 14:23:35 +0100 Subject: [PATCH 02/13] Makefile.am: install-as-root: avoid chmod/chown of common OS locations like /run /var/run /etc [#1298] Signed-off-by: Jim Klimov --- Makefile.am | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9c70292dc9..e263917210 100644 --- a/Makefile.am +++ b/Makefile.am @@ -622,20 +622,23 @@ install-as-root: install esac ; \ done ; \ if (command -v chmod) ; then \ - echo " CHMOD(0770) $(DESTDIR)/@STATEPATH@ $(DESTDIR)/@STATEPATH@/upssched" >&2 ; \ - chmod 0770 "$(DESTDIR)/@STATEPATH@" "$(DESTDIR)/@STATEPATH@/upssched" \ + echo " CHMOD(0770) $(DESTDIR)/@STATEPATH@/upssched" >&2 ; \ + chmod 0770 "$(DESTDIR)/@STATEPATH@/upssched" \ || exit ; \ - for D in "@PIDPATH@" "@ALTPIDPATH@" "@ALTSTATEPATH@" ; do \ + for D in "@STATEPATH@" "@PIDPATH@" "@ALTPIDPATH@" "@ALTSTATEPATH@" ; do \ case x"$$D" in \ - x|x@*) ;; \ + x|x@*|x/run|x/var/run|x/tmp|x/var/tmp|x/dev/shm|x/etc|x/var|x/usr|x/usr/local|x/usr/local/etc|x/usr/etc) ;; \ *) echo " CHMOD(0770) $(DESTDIR)/$$D" >&2 ; \ chmod 0770 "$(DESTDIR)/$$D" \ || exit ;; \ esac ; \ done ; \ - echo " CHMOD(0751) $(DESTDIR)/@CONFPATH@" >&2 ; \ - chmod 0751 "$(DESTDIR)/@CONFPATH@" \ - || exit ; \ + case x"@CONFPATH@" in \ + x|x@*|x/run|x/var/run|x/tmp|x/var/tmp|x/dev/shm|x/etc|x/var|x/usr|x/usr/local|x/usr/local/etc|x/usr/etc) ;; \ + *) echo " CHMOD(0751) $(DESTDIR)/@CONFPATH@" >&2 ; \ + chmod 0751 "$(DESTDIR)/@CONFPATH@" \ + || exit ;; \ + esac ; \ for F in hosts.conf.sample upsstats-single.html.sample upsstats.html.sample upsset.conf.sample ; do \ echo " CHMOD(0644) CGI: $(DESTDIR)/@CONFPATH@/$$F" >&2 ; \ chmod 0644 "$(DESTDIR)/@CONFPATH@/$$F" \ @@ -652,20 +655,23 @@ install-as-root: install if (command -v chown) && test 0 -lt "`id -u '@RUN_AS_USER@'`" \ && ( test 0 -lt "`getent group '@RUN_AS_GROUP@' | awk -F: '{print $$3}'`" || test 0 -lt "`id -g '@RUN_AS_GROUP@'`" ) \ ; then \ - echo " CHOWN(@RUN_AS_USER@:@RUN_AS_GROUP@) $(DESTDIR)/@STATEPATH@ $(DESTDIR)/@STATEPATH@/upssched" >&2 ; \ - chown "@RUN_AS_USER@:@RUN_AS_GROUP@" "$(DESTDIR)/@STATEPATH@" "$(DESTDIR)/@STATEPATH@/upssched" \ + echo " CHOWN(@RUN_AS_USER@:@RUN_AS_GROUP@) $(DESTDIR)/@STATEPATH@/upssched" >&2 ; \ + chown "@RUN_AS_USER@:@RUN_AS_GROUP@" "$(DESTDIR)/@STATEPATH@/upssched" \ || exit ; \ - for D in "@PIDPATH@" "@ALTPIDPATH@" "@ALTSTATEPATH@" ; do \ + for D in "@STATEPATH@" "@PIDPATH@" "@ALTPIDPATH@" "@ALTSTATEPATH@" ; do \ case x"$$D" in \ - x|x@*) ;; \ + x|x@*|x/run|x/var/run|x/tmp|x/var/tmp|x/dev/shm|x/etc|x/var|x/usr|x/usr/local|x/usr/local/etc|x/usr/etc) ;; \ *) echo " CHOWN(@RUN_AS_USER@:@RUN_AS_GROUP@) $(DESTDIR)/$$D" >&2 ; \ chown "@RUN_AS_USER@:@RUN_AS_GROUP@" "$(DESTDIR)/$$D" \ || exit ;; \ esac ; \ done ; \ - echo " CHOWN(root:@RUN_AS_GROUP@) $(DESTDIR)/@CONFPATH@" >&2 ; \ - chown "root:@RUN_AS_GROUP@" "$(DESTDIR)/@CONFPATH@" \ - || exit ; \ + case x"@CONFPATH@" in \ + x|x@*|x/run|x/var/run|x/tmp|x/var/tmp|x/dev/shm|x/etc|x/var|x/usr|x/usr/local|x/usr/local/etc|x/usr/etc) ;; \ + *) echo " CHOWN(root:@RUN_AS_GROUP@) $(DESTDIR)/@CONFPATH@" >&2 ; \ + chown "root:@RUN_AS_GROUP@" "$(DESTDIR)/@CONFPATH@" \ + || exit ;; \ + esac ; \ for F in hosts.conf.sample upsstats-single.html.sample upsstats.html.sample upsset.conf.sample ; do \ echo " CHOWN(root:@RUN_AS_GROUP@) CGI: $(DESTDIR)/@CONFPATH@/$$F" >&2 ; \ chown "root:@RUN_AS_GROUP@" "$(DESTDIR)/@CONFPATH@/$$F" \ From 48b43f32d6abdc5926c25c71107c72689180250d Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 14:37:30 +0100 Subject: [PATCH 03/13] scripts/Solaris/Makefile.am: consider ISA info (specific 32/64-bit CPU support) of build target host in package naming as NUT/NUTx Signed-off-by: Jim Klimov --- scripts/Solaris/Makefile.am | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/scripts/Solaris/Makefile.am b/scripts/Solaris/Makefile.am index f3ba92eda1..f85f76d2d8 100644 --- a/scripts/Solaris/Makefile.am +++ b/scripts/Solaris/Makefile.am @@ -61,6 +61,23 @@ SOLARIS_PACKAGE_SVR4_HELPERSCRIPTS = makelocal.sh precheck.py preproto.pl SOLARIS_PACKAGE_SVR4_INSTALLSCRIPTS = preinstall postinstall preremove postremove SOLARIS_PACKAGE_SVR4_INSTALLDATA = pkginfo package-solaris-svr4: $(SOLARIS_PACKAGE_SVR4_HELPERSCRIPTS) $(SOLARIS_PACKAGE_SVR4_INSTALLSCRIPTS) $(SOLARIS_PACKAGE_SVR4_INSTALLDATA) + ISANAME=''; case x"$(target_cpu)" in \ + xi386|xsparc|xsparcv9|xamd64) ISANAME='$(target_cpu)' ;; \ + xx86_64) ISANAME='amd64' ;; \ + xi686) ISANAME='i386' ;; \ + xsparcv7)ISANAME='sparc' ;; \ + x) UNAME_P="`uname -p`" && ISANAME="$${UNAME_P}" ;; \ + esac ; \ + ISABITS=32; case x"$${ISANAME}" in \ + xi386|xsparc) ISABITS=32 ;; \ + xsparcv9|xamd64) ISABITS=64 ;; \ + x*) echo "WARNING: Unexpected ISANAME='$${ISANAME}'" >&2 ;; \ + esac; \ + case x"$${ISABITS}" in \ + x32) ISA_PKGNAME="NUT" ;; \ + x64) ISA_PKGNAME="NUTx" ;; \ + esac; \ + sed -e 's/^PKG="[^"][^"]*"$/PKG="'"$${ISA_PKGNAME}"'"/' -i $(builddir)/pkginfo ; \ if test -n "@auglensdir@" && test -d "$(DESTDIR)@auglensdir@" ; then \ $(MKDIR_P) "$(DESTDIR)@datadir@/augeas-lenses" && \ cd "$(DESTDIR)@auglensdir@" && \ @@ -75,15 +92,8 @@ endif cd $(PROTOTYPE_DIR) && rm -f prototype1 cd $(PROTOTYPE_DIR) && ./makelocal.sh cp $(PROTOTYPE_DIR)/*.gz $(builddir) - ISANAME=''; case x"$(target_cpu)" in \ - xi386|xsparc|xsparcv9|xamd64) ISANAME='$(target_cpu)' ;; \ - xx86_64) ISANAME='amd64' ;; \ - xi686) ISANAME='i386' ;; \ - xsparcv7)ISANAME='sparc' ;; \ - x) UNAME_P="`uname -p`" && ISANAME="$${UNAME_P}" ;; \ - esac ; \ if [ -n "$${ISANAME}" ] ; then \ - mv -f NUT_solaris_package.local.gz "$(abs_top_builddir)/NUT_solaris_$${ISANAME}_package-@PACKAGE_VERSION@.local.gz" ; \ + mv -f NUT*_solaris_package.local.gz "$(abs_top_builddir)/$${ISA_PKGNAME}_solaris_$${ISANAME}_package-@PACKAGE_VERSION@.local.gz" ; \ fi # TODO: Define support for IPS packaging (provide p5m files and make rules) From 09d6dc027e3475452728781b517240878227b979 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 14:56:01 +0100 Subject: [PATCH 04/13] INSTALL.nut.adoc, docs/config-notes.txt: update with info on `(sudo) make install-as-root` [#1298] Signed-off-by: Jim Klimov --- INSTALL.nut.adoc | 30 ++++++++++++++++++++++++++---- docs/config-notes.txt | 14 ++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/INSTALL.nut.adoc b/INSTALL.nut.adoc index 331134f832..43e2007304 100644 --- a/INSTALL.nut.adoc +++ b/INSTALL.nut.adoc @@ -306,11 +306,30 @@ Installation [NOTE] ===================================================================== +You should now gain privileges for installing software if necessary, e.g.: -you should now gain privileges for installing software if necessary: + su - - su +or prefix installation (not build/check!) commands with `sudo`, e.g.: + sudo make install ... +===================================================================== + +[NOTE] +===================================================================== +If you install NUT for direct consumption on the system that has just +built it from source, you might be aided for some of the steps listed +and explained below by running (as `root`): + + make install-as-root + +This should not only install the software, but also create directories +such as the state path, assign ownership and access permissions to +certain directories and sample configuration files which NUT user +and/or group accounts should be able to read and/or write, and, on +some platforms, also (re-)start the NUT daemons/services. + +See above "System User creation", that should be done first! ===================================================================== Install the files to a system level directory: @@ -328,7 +347,7 @@ have created. If you are packaging this software, then you will probably want to use the DESTDIR variable to redirect the build into another place, -i.e.: +also known as a "prototype directory" or a "staging area", i.e.: make DESTDIR=/tmp/package install make DESTDIR=/tmp/package install-conf @@ -337,9 +356,12 @@ i.e.: State path creation ^^^^^^^^^^^^^^^^^^^ +NOTE: See above about `make install-as-root`, if you use that -- skip +this step here. + Create the state path directory for the driver(s) and server to use for storing UPS status data and other auxiliary files, and make it -group-writable by the group of the system user you created. +group-writable by the group of the system user you created, e.g.: mkdir -p /var/state/ups chmod 0770 /var/state/ups diff --git a/docs/config-notes.txt b/docs/config-notes.txt index 6fc72d7ddc..1532b87f31 100644 --- a/docs/config-notes.txt +++ b/docs/config-notes.txt @@ -327,6 +327,13 @@ the user you created in the preparation process. The suggested configuration is to `chown` it to `root`, `chgrp` it to the group you created, then make it readable by the group. +NOTE: If you installed NUT from source and used `make install-as-root`, +or if your distribution packaging did, the sample configuration files +would have the suggested ownership and permissions assigned, so if you +use e.g. `cp -pf upsd.users.sample upsd.users` (as `root`) to start out +with some annotated comments and adapt that to your deployment, the +copied files should also get the expected safe permissions. + chown root:nut upsd.conf upsd.users chmod 0640 upsd.conf upsd.users @@ -660,6 +667,13 @@ The recommended setting is to have it owned by `root:nut`, then make it readable by the group and not by the world. This file contains passwords that could be used by an attacker to start a shutdown, so keep it secure. +NOTE: If you installed NUT from source and used `make install-as-root`, +or if your distribution packaging did, the sample configuration files +would have the suggested ownership and permissions assigned, so if you +use e.g. `cp -pf upsmon.conf.sample upsmon.conf` (as `root`) to start out +with some annotated comments and adapt that to your deployment, the +copied files should also get the expected safe permissions. + chown root:nut upsmon.conf chmod 0640 upsmon.conf From 95331fddbda64e06aacb188ac370d6d672a328d9 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 15:17:19 +0100 Subject: [PATCH 05/13] configure.ac: refine NUT_VERSION_DEPLOYED (seen when we ./configure --enable-inplace-runtime) Signed-off-by: Jim Klimov --- configure.ac | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 15f43c490f..f0aa0a9a10 100644 --- a/configure.ac +++ b/configure.ac @@ -463,7 +463,11 @@ AS_IF([test x"$nut_enable_inplace_runtime" = xyes -a x"${NUT_VERSION_DEPLOYED-}" && test x"${CONFIG_FLAGS_DEPLOYED}" != x \ || CONFIG_FLAGS_DEPLOYED="" - NUT_VERSION_DEPLOYED="`"${DEPLOYED_TOOL}" -DV 2>&1 | grep 'configured with flags:' | head -1 | sed 's,^.*Network UPS Tools version \(.*\) configured with flags:.*$,\1,'`" \ + dnl NOTE: Currntly NUT_VERSION_DEPLOYED is just informative (or a flag + dnl that we've "reentered" the configuration script), so we tolerate a + dnl better detailed string that is more than just a version, e.g.: + dnl 2.8.2.1829-1829-g8f8a4f417 (development iteration after 2.8.2) built with gcc (Debian 10.2.1-6) 10.2.1 20210110 + NUT_VERSION_DEPLOYED="`"${DEPLOYED_TOOL}" -DV 2>&1 | grep 'configured with flags:' | head -1 | sed -e 's,^.*Network UPS Tools version \(.*\) configured with flags:.*$,\1,' -e 's, and *$,,'`" \ && test x"${NUT_VERSION_DEPLOYED}" != x \ || NUT_VERSION_DEPLOYED="" From ea1bb83b8e7f9477133723c858aa9d7672f4b810 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 15:42:38 +0100 Subject: [PATCH 06/13] Makefile.am: install-as-root: separate service-stopping from "make install" of new files and creation/ownership/restart of new artifacts [#1298] Signed-off-by: Jim Klimov --- Makefile.am | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index e263917210..88738b9b02 100644 --- a/Makefile.am +++ b/Makefile.am @@ -583,8 +583,9 @@ endif # TODO: Actually move this into scripts like Solaris/postinstall # using OS-specific `useradd`/`groupadd`, etc. -install-as-root: install - @case "@target_os@" in *mingw*) exit 0;; esac ; \ +install-as-root: + @+echo "$@: starting (no-op if not root)" >&2 ; \ + case "@target_os@" in *mingw*) exit 0;; esac ; \ if [ x"@host_os@" != x"@build_os@" ]; then exit 0 ; fi ; \ if [ x"@target_os@" != x"@build_os@" ]; then exit 0 ; fi ; \ prefix="@prefix@"; \ @@ -605,7 +606,13 @@ install-as-root: install /usr/bin/svcadm disable -ts $$S || true ; \ done ; \ fi ; \ - $(top_builddir)/scripts/Solaris/preremove && \ + $(top_builddir)/scripts/Solaris/preremove \ + || exit ; \ + fi ; \ + fi ; \ + $(MAKE) $(AM_FLAGS) DESTDIR="$(DESTDIR)" install || exit ; \ + if [ x"$(DESTDIR)" = x -o x"$(DESTDIR)" = x/ ] ; then \ + if $(WITH_SOLARIS_SMF) || $(WITH_SOLARIS_INIT) ; then \ $(top_builddir)/scripts/Solaris/preinstall && \ $(top_builddir)/scripts/Solaris/postinstall ; \ exit ; \ From 8c7b7818e8f8dd09c081ac39d90c4fdbb81c8926 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 15:48:37 +0100 Subject: [PATCH 07/13] Makefile.am: install-as-root: fix NDE retcode 42 behaviour [#1298] Signed-off-by: Jim Klimov --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 88738b9b02..ab38abe417 100644 --- a/Makefile.am +++ b/Makefile.am @@ -711,7 +711,7 @@ install-as-root: fi ; \ echo "$@: Reconfigure nut-driver-enumerator (service instance wrapping)" >&2 ; \ @SYSTEMD_SYSTEMCTL_PROGRAM@ restart udev || true ; \ - $(top_builddir)/scripts/upsdrvsvcctl/nut-driver-enumerator.sh --reconfigure || exit ; \ + $(top_builddir)/scripts/upsdrvsvcctl/nut-driver-enumerator.sh --reconfigure || { RES=$$?; if [ $$RES != 42 ] ; then exit $$RES ; fi ; } ; \ echo "$@: Restart NUT services" >&2 ; \ @SYSTEMD_SYSTEMCTL_PROGRAM@ restart nut-driver-enumerator.service nut-monitor.service nut-server.service || exit ; \ fi ; \ From 77e7c262e27cff4844dd21fe2dcf183f92637232 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 15:54:17 +0100 Subject: [PATCH 08/13] Makefile.am: install-as-root: update comment [#1298] Signed-off-by: Jim Klimov --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index ab38abe417..ac68495831 100644 --- a/Makefile.am +++ b/Makefile.am @@ -583,6 +583,8 @@ endif # TODO: Actually move this into scripts like Solaris/postinstall # using OS-specific `useradd`/`groupadd`, etc. +# Note that as we stop services, we may be dealing with (older) +# distros that do not follow current naming in NUT code base. install-as-root: @+echo "$@: starting (no-op if not root)" >&2 ; \ case "@target_os@" in *mingw*) exit 0;; esac ; \ From bf11741fb94e35414abd704f5d0f84c0515a4918 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 18:58:44 +0100 Subject: [PATCH 09/13] configure.ac: fix fallback PROBE_OS_GROUP definition Signed-off-by: Jim Klimov --- configure.ac | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index f0aa0a9a10..b13159b9fd 100644 --- a/configure.ac +++ b/configure.ac @@ -294,7 +294,20 @@ AS_IF([test x"${GETENT}" != x], [ ],[ AS_IF([test x"${ID}" != x], [ PROBE_OS_USER="${ID} -u " - PROBE_OS_GROUP="${ID} -g " + AS_IF([test -r "/etc/groups"], [ + dnl FIXME: For command prefix usage like used in this + dnl script, we might be better off defining a shell + dnl function and referring to it. Grep would catch + dnl also user names that have a group as secondary! + PROBE_OS_GROUP="cat /etc/groups | grep -w " + ], [ + dnl This shows groups of a USER with specified name! + dnl But to probe for cases where string names are + dnl same (e.g. "nut" or "ups") this might be good + dnl enough. + PROBE_OS_GROUP="${ID} -g " + ]) + AC_MSG_WARN([Can not PROPERLY check existence of group accounts on this system, but can try best-effort]) ],[ AC_MSG_WARN([Can not check existence of user and group accounts on this system]) ]) @@ -307,7 +320,7 @@ dnl certain other configure options (e.g. "in-place replacement") RUN_AS_USER="nobody" RUN_AS_GROUP="nobody" AS_IF([test -n "`${PROBE_OS_GROUP} nogroup`" && ! test -n "`${PROBE_OS_GROUP} "${RUN_AS_GROUP}"`"], - [RUN_AS_GROUP="nogroup"] + [RUN_AS_GROUP="nogroup"] ) dnl NOTE: NUT legacy default, keep as is for least surprise From 8f78290132952f0ca7553c1e1b2d8839951101df Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 19:09:19 +0000 Subject: [PATCH 10/13] scripts/Solaris/Makefile.am: consider ISA info (specific 32/64-bit CPU support) of build target host in package naming as NUT/NUTx - Makefile typo fix Signed-off-by: Jim Klimov --- scripts/Solaris/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Solaris/Makefile.am b/scripts/Solaris/Makefile.am index f85f76d2d8..19e08da121 100644 --- a/scripts/Solaris/Makefile.am +++ b/scripts/Solaris/Makefile.am @@ -77,7 +77,7 @@ package-solaris-svr4: $(SOLARIS_PACKAGE_SVR4_HELPERSCRIPTS) $(SOLARIS_PACKAGE_SV x32) ISA_PKGNAME="NUT" ;; \ x64) ISA_PKGNAME="NUTx" ;; \ esac; \ - sed -e 's/^PKG="[^"][^"]*"$/PKG="'"$${ISA_PKGNAME}"'"/' -i $(builddir)/pkginfo ; \ + sed -e 's/^PKG="[^"][^"]*"$$/PKG="'"$${ISA_PKGNAME}"'"/' -i $(builddir)/pkginfo ; \ if test -n "@auglensdir@" && test -d "$(DESTDIR)@auglensdir@" ; then \ $(MKDIR_P) "$(DESTDIR)@datadir@/augeas-lenses" && \ cd "$(DESTDIR)@auglensdir@" && \ From ae6c9d0582a92d4c4f77c6a906b7f8a54f3e9534 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 19:16:06 +0000 Subject: [PATCH 11/13] scripts/Solaris/Makefile.am: combine "package-solaris-svr4" into one shell block (keep ISA vars defined) Signed-off-by: Jim Klimov --- scripts/Solaris/Makefile.am | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/scripts/Solaris/Makefile.am b/scripts/Solaris/Makefile.am index 19e08da121..9e33fd63e1 100644 --- a/scripts/Solaris/Makefile.am +++ b/scripts/Solaris/Makefile.am @@ -77,23 +77,24 @@ package-solaris-svr4: $(SOLARIS_PACKAGE_SVR4_HELPERSCRIPTS) $(SOLARIS_PACKAGE_SV x32) ISA_PKGNAME="NUT" ;; \ x64) ISA_PKGNAME="NUTx" ;; \ esac; \ - sed -e 's/^PKG="[^"][^"]*"$$/PKG="'"$${ISA_PKGNAME}"'"/' -i $(builddir)/pkginfo ; \ + sed -e 's/^PKG="[^"][^"]*"$$/PKG="'"$${ISA_PKGNAME}"'"/' -i $(builddir)/pkginfo || exit ; \ if test -n "@auglensdir@" && test -d "$(DESTDIR)@auglensdir@" ; then \ $(MKDIR_P) "$(DESTDIR)@datadir@/augeas-lenses" && \ - cd "$(DESTDIR)@auglensdir@" && \ - ( cp -prf ./ "$(DESTDIR)@datadir@/augeas-lenses/" || cp -rf ./ "$(DESTDIR)@datadir@/augeas-lenses/" ) ; fi - cd $(PROTOTYPE_DIR) && find . -print | pkgproto > prototype1 - cp $(SOLARIS_PACKAGE_SVR4_HELPERSCRIPTS) $(SOLARIS_PACKAGE_SVR4_INSTALLSCRIPTS) $(SOLARIS_PACKAGE_SVR4_INSTALLDATA) $(PROTOTYPE_DIR) - cd $(PROTOTYPE_DIR) && chmod +x $(SOLARIS_PACKAGE_SVR4_HELPERSCRIPTS) $(SOLARIS_PACKAGE_SVR4_INSTALLSCRIPTS) - cd $(PROTOTYPE_DIR) && perl preproto.pl -if HAVE_PYTHON - cd $(PROTOTYPE_DIR) && $(PYTHON) precheck.py -endif - cd $(PROTOTYPE_DIR) && rm -f prototype1 - cd $(PROTOTYPE_DIR) && ./makelocal.sh - cp $(PROTOTYPE_DIR)/*.gz $(builddir) + ( cd "$(DESTDIR)@auglensdir@" && \ + ( cp -prf ./ "$(DESTDIR)@datadir@/augeas-lenses/" || cp -rf ./ "$(DESTDIR)@datadir@/augeas-lenses/" ) ) || exit ; \ + fi ; \ + ( cd $(PROTOTYPE_DIR) && find . -print | pkgproto > prototype1 ) || exit ; \ + cp $(SOLARIS_PACKAGE_SVR4_HELPERSCRIPTS) $(SOLARIS_PACKAGE_SVR4_INSTALLSCRIPTS) $(SOLARIS_PACKAGE_SVR4_INSTALLDATA) $(PROTOTYPE_DIR) || exit ; \ + ( cd $(PROTOTYPE_DIR) && chmod +x $(SOLARIS_PACKAGE_SVR4_HELPERSCRIPTS) $(SOLARIS_PACKAGE_SVR4_INSTALLSCRIPTS) ) || exit ; \ + ( cd $(PROTOTYPE_DIR) && perl preproto.pl ) || exit ; \ + if test -n '$(PYTHON)' ; then \ + ( cd $(PROTOTYPE_DIR) && $(PYTHON) precheck.py ) || exit ; \ + fi ; \ + ( cd $(PROTOTYPE_DIR) && rm -f prototype1 ) || exit ; \ + ( cd $(PROTOTYPE_DIR) && ./makelocal.sh ) || exit ; \ + cp $(PROTOTYPE_DIR)/*.gz $(builddir) || exit ; \ if [ -n "$${ISANAME}" ] ; then \ - mv -f NUT*_solaris_package.local.gz "$(abs_top_builddir)/$${ISA_PKGNAME}_solaris_$${ISANAME}_package-@PACKAGE_VERSION@.local.gz" ; \ + mv -f NUT*_solaris_package.local.gz "$(abs_top_builddir)/$${ISA_PKGNAME}_solaris_$${ISANAME}_package-@PACKAGE_VERSION@.local.gz" || exit ; \ fi # TODO: Define support for IPS packaging (provide p5m files and make rules) From d5321e7e7ca82942d4b5d34d56b29d767be21305 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 19:25:47 +0000 Subject: [PATCH 12/13] Makefile.am: install-as-root: SMF: fix path to svcadm [#1298] Signed-off-by: Jim Klimov --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index ac68495831..d5bb7880f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -605,7 +605,7 @@ install-as-root: echo "$@: Stop NUT services, if any" >&2 ; \ SMF_ACTIVE="`/usr/bin/svcs -a -Hostate,fmri | grep svc:/system/power/ | grep -v disabled | awk '{print $$2}'`" ; \ for S in $$SMF_ACTIVE ; do \ - /usr/bin/svcadm disable -ts $$S || true ; \ + /usr/sbin/svcadm disable -ts $$S || true ; \ done ; \ fi ; \ $(top_builddir)/scripts/Solaris/preremove \ From 665e5c151556d46f5b0722dbebfd1e4837b4c685 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Sat, 11 Jan 2025 20:18:54 +0000 Subject: [PATCH 13/13] docs/config-prereqs.txt: update instructions for OpenIndiana (as of 2024.04) Signed-off-by: Jim Klimov --- docs/config-prereqs.txt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/config-prereqs.txt b/docs/config-prereqs.txt index 231a73f95d..bd085f437b 100644 --- a/docs/config-prereqs.txt +++ b/docs/config-prereqs.txt @@ -1164,7 +1164,7 @@ Typical tooling would include: :; pkg install \ asciidoc libxslt \ docbook/dtds docbook/dsssl docbook/xsl docbook docbook/sgml-common pygments-39 \ - graphviz expect graphviz-tcl + image/graphviz expect graphviz-tcl # For CGI graph generation - massive packages (X11): :; pkg install \ @@ -1175,9 +1175,9 @@ Typical tooling would include: library/augeas python/augeas \ libusb-1 libusbugen system/library/usb/libusb system/header/header-usb driver/usb/ugen \ libmodbus \ - neon \ - net-snmp \ - powerman \ + library/neon \ + system/management/snmp/net-snmp \ + system/management/powerman \ freeipmi \ avahi @@ -1216,10 +1216,14 @@ filenames, as automated below: :; pkg install \ developer/clang-13 runtime/clang-13 +# With OI 2024.04 there's also clang-18 available in the mix: +:; pkg install \ + developer/clang-18 runtime/clang-18 + # Get clang-cpp-X visible in standard PATH (for CI to reference the right one), # and make sure other frontends are exposed with versions (not all OI distro # releases have such symlinks packaged right), e.g.: -:; (cd /usr/bin && for X in 8 9 13 ; do for T in "" "++" "-cpp"; do \ +:; (cd /usr/bin && for X in 8 9 13 18 ; do for T in "" "++" "-cpp"; do \ ln -fs "../clang/$X.0/bin/clang$T" "clang${T}-${X}" ; \ done; done)