Skip to content

Commit

Permalink
INSTALL.nut: update with "in-place" rebuilds chapter [networkupstools…
Browse files Browse the repository at this point in the history
  • Loading branch information
jimklimov committed Feb 6, 2023
1 parent 7a20723 commit b5a57fe
Show file tree
Hide file tree
Showing 2 changed files with 251 additions and 1 deletion.
245 changes: 245 additions & 0 deletions INSTALL.nut
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ To build NUT from a Git checkout you may need some additional tools
(referenced just a bit below) and run `./autogen.sh` to generate the
needed files. For common developer iterations, porting to new platforms,
or in-place testing, running the `./ci_build.sh` script can be helpful.
The "<<Installing_inplace,Building NUT for in‐place upgrades or non‐disruptive
tests>>" section details some more hints about such workflow, including some
`systemd` integration.

The NUT linkdoc:packager-guide[Packager Guide], which presents the best
practices for installing and integrating NUT, is also a good reading.
Expand Down Expand Up @@ -80,6 +83,9 @@ do this, you will have problems later on when you try to start upsd.
Build and install
~~~~~~~~~~~~~~~~~

NOTE: See also <<Installing_inplace,Building NUT for in‐place upgrades
or non‐disruptive tests>>.

[[Configuration]]
Configuration
^^^^^^^^^^^^^
Expand Down Expand Up @@ -210,6 +216,245 @@ You are now ready to configure NUT, and start testing and using it.

You can jump directly to the <<Configuration_notes,NUT configuration>>.

[[Installing_inplace]]
Building NUT for in‐place upgrades or non‐disruptive tests
----------------------------------------------------------

NOTE: The NUT GitHub Wiki article at
https://github.com/networkupstools/nut/wiki/Building-NUT-for-in%E2%80%90place-upgrades-or-non%E2%80%90disruptive-tests
may contain some more hints as contributed by the community.

Overview
~~~~~~~~

Since late 2022/early 2023 NUT codebase supports "in-place" builds
which try their best to discover the configuration of an earlier build
(configuration and run-time paths and OS accounts involved, maybe an
exact configuration if stored in deployed binaries).

This optional mode is primarily intended for several use-cases:

* Test recent GitHub "master" branch or a proposed PR to see if it
solves a practical problem for a particular user;
* Replace an existing deployment, e.g. if OS-provided packages deliver
obsolete code, to use newer NUT locally in "production mode".
- In such cases ideally get your distribution, NAS vendor, etc.
to provide current NUT -- and benefit from a better integrated
and tested product.

Note that "just testing" often involves building the codebase and new
drivers or tools in question, and running them right from the build
workspace (without installing into the system and so risking an
unpredictable-stability state). In case of testing new driver builds,
note that you would need to stop the normally running instances to
free up the communications resources (USB/serial ports, etc.), run the
new driver program in data-dump mode, and restart the normal systems
operations.

Such tests still benefit from matching the build configuration to what
is already deployed, in order to request same configuration files and
system access permissions (e.g. to own device nodes for physical-media
ports involved, and to read the production configuration files).

Pre-requisites
^^^^^^^^^^^^^^

The <<Config_Prereqs,Prerequisites for building NUT on different OSes>>
document details tools and dependencies that were added on NUT CI build
environments, which now cover many operating systems. This should
provide a decent starting point for the build on yours (PRs to update
the document are welcome!)

NOTE: "Config Prereqs" document for latest NUT iteration can be found at
https://github.com/networkupstools/nut/blob/master/docs/config-prereqs.txt

Note that unlike distribution tarballs, Git sources do not include a
`configure` script and some other files -- these should be generated by
running `autogen.sh` (or `ci_build.sh` that calls it).

Getting the right sources
^^^^^^^^^^^^^^^^^^^^^^^^^

To build the current tip of development iterations (usually after PR
merges that passed CI, reviews and/or other tests), just clone the NUT
repository and "master" branch should get checked out by default (also
can request that explicitly, per example posted below).

If you want to quickly test a particular pull request, see the link on
top of the PR page that says `... wants to merge ... from : ...` and
copy the proposed-source URL of that "from" part.

For example, in some PR this says `jimklimov:issue-1234` and links to
`https://github.com/jimklimov/nut/tree/issue-1234`.
For manual git-cloning, just paste that URL into the shell and replace
the `/tree/` with "`-b`" CLI option for branch selection, like this:

:; cd /tmp
### Checkout https://github.com/jimklimov/nut/tree/issue-1234
:; git clone https://github.com/jimklimov/nut -b issue-1234

Testing with CI helper
~~~~~~~~~~~~~~~~~~~~~~

NOTE: this uses the `ci_build.sh` script to arrange some rituals and
settings, in this case primarily to default the choice of drivers to
auto-detection of what can be built, and to skip building documentation.
Also note that this script supports many other scenarios for CI and
developers, managed by `BUILD_TYPE` and other environment variables,
which are not explored here.

An "in-place" _testing_ build and run would probably go along these lines:

:; cd /tmp
:; git clone -b master https://github.com/networkupstools/nut
:; cd nut
:; ./ci_build.sh inplace
### Temporarily stop your original drivers
:; ./drivers/nutdrv_qx -a DEVNAME_FROM_UPS_CONF -d1 -DDDDDD \
# -x override...=... -x subdriver=...
### Can start back your original drivers
### Analyze and/or post back the data-dump

[NOTE]
======
To probe a device for which you do not have an `ups.conf` section
yet, you must specify `-s name` and all config options (including
`port`) on command-line with `-x` arguments, e.g.:

:; ./drivers/nutdrv_qx -s temp-ups \
-d1 -DDDDDD -x port=auto \
-x vendorid=... -x productid=... \
-x subdriver=...
======

Replacing a NUT deployment
~~~~~~~~~~~~~~~~~~~~~~~~~~

While `ci_build.sh inplace` can be a viable option for preparation of
local builds, you may want to have precise control over `configure`
options (e.g. choice of required drivers, or enabled documentation).

A sound starting point would be to track down packaging recipes used by
your distribution (e.g.
link:https://src.fedoraproject.org/rpms/nut/blob/rawhide/f/nut.spec[RPM spec]
or
link:https://salsa.debian.org/debian/nut/-/blob/debian/debian/rules[DEB rules]
files, etc.) to detail the same paths if you intend to replace those,
and copy the parameters for `configure` script from there -- especially
if your system is not currently running NUT v2.8.1 or newer (which embeds
this information to facilitate in-place upgrade rebuilds).

Note that the primary focus of in-place automated configuration mode is
about critical run-time options, such as OS user accounts, configuration
location and state/PID paths, so it alone might not replace your driver
binaries that the package would put into an obscure location like
`/lib/nut`. It would however install init-scripts or systemd units that
would refer to new locations specified by the current build, so such old
binaries would just consume disk space but not run.

Replacing any NUT deployment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

NOTE: For deployments on OSes with `systemd` see the next section.

This goes similar to usual build and install from Git:

:; cd /tmp
:; git clone https://github.com/networkupstools/nut
:; cd nut
:; ./autogen.sh
:; ./configure --enable-inplace-runtime # --maybe-some-other-options
:; make -j 4 all check && sudo make install

Note that `make install` does not currently handle all the nuances that
packaging installation scripts would, such as customizing filesystem
object ownership, daemon restarts, etc. or even creating locations like
`/var/state/ups` and `/var/run/nut` as part of the `make` target (but
e.g. the delivered `systemd-tmpfiles` configuration can handle that for
a large part of the audience). This aspect is tracked as
link:https://github.com/networkupstools/nut/issues/1298[issue #1298]

At this point you should revise the locations for PID files
(e.g. `/var/run/nut`) and pipe files (e.g. `/var/state/ups`) that they
exist and permissions remain suitable for NUT run-time user selected by
your configuration, and typically stop your original NUT drivers,
data-server (upsd) and upsmon, and restart them using the new binaries.

Replacing a systemd-enabled NUT deployment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For modern Linux distributions with `systemd` this replacement procedure
could be enhanced like below, to also re-enable services (creating proper
symlinks) and to get them started:

:; cd /tmp
:; git clone https://github.com/networkupstools/nut
:; cd nut
:; ./autogen.sh
:; ./configure --enable-inplace-runtime # --maybe-some-other-options
:; make -j 4 all check && \
{ sudo systemctl stop nut-monitor nut-server || true ; } && \
{ sudo systemctl stop nut-driver.service || true ; } && \
{ sudo systemctl stop nut-driver.target || true ; } && \
{ sudo systemctl stop nut.target || true ; } && \
sudo make install && \
sudo systemctl daemon-reload && \
sudo systemd-tmpfiles --create && \
sudo systemctl disable nut.target nut-driver.target \
nut-monitor nut-server nut-driver-enumerator.path \
nut-driver-enumerator.service && \
sudo systemctl enable nut.target nut-driver.target \
nut-monitor nut-server nut-driver-enumerator.path \
nut-driver-enumerator.service && \
{ sudo systemctl restart udev || true ; } && \
sudo systemctl restart nut-driver-enumerator.service \
nut-monitor nut-server

Note the several attempts to stop old service units -- naming did change
from 2.7.4 and older releases, through 2.8.0, and up to current codebase.
Most of the NUT units are now `WantedBy=nut.target` (which is in turn
`WantedBy=multi-user.target` and so bound to system startup). You should
only `systemctl enable` those units you need on this system -- this allows
it to not start the daemons you do not need (e.g. not run `upsd` NUT data
server on systems which are only `upsmon secondary` clients).

The `nut-driver-enumerator` units (and corresponding shell script) are
part of a new feature introduced in NUT 2.8.0, which automatically
discovers `ups.conf` sections and changes to their contents, and manages
instances of a `nut-driver@.service` definition.

You may also have to restart (or reload if supported) some system services
if your updates impact them, like `udev` for updates USB support (note also
link:https://github.com/networkupstools/nut/pull/1342[PR #1342] regarding
the change from `udev.rules` to `udev.hwdb` file with NUT v2.8.0 or later --
you may have to remove the older file manually).

Iterating with a systemd deployment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you are regularly building NUT from GitHub "master" branch, or iterating
local development branches of your own, you *may* get away with shorter
constructs to just restart the services after installing newly built files
(if you know there were no changes to unit file definitions and dependencies),
e.g.:

...
:; make -j 4 all check && \
sudo make install && \
sudo systemctl daemon-reload && \
sudo systemd-tmpfiles --create && \
sudo systemctl restart \
nut-driver-enumerator.service nut-monitor nut-server

Next steps after an in-place upgrade
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can jump directly to the <<Configuration_notes,NUT configuration>>
if you need to revise the settings for your new NUT version, take advantage
of new configuration options, etc.

Check the linkdoc:NEWS and linkdoc:UPGRADING[Upgrade Notes] files in your
Git workspace to review features that should be present in your new build.

[[Installing_packages]]
Installing from packages
Expand Down
7 changes: 6 additions & 1 deletion docs/nut.dict
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
personal_ws-1.1 en 3090 utf-8
personal_ws-1.1 en 3095 utf-8
AAS
ABI
ACFAIL
Expand Down Expand Up @@ -236,6 +236,7 @@ DATAPATH
DCE
DDD
DDDDD
DDDDDD
DDF
DDThh
DEADTIME
Expand All @@ -247,6 +248,7 @@ DELPHYS
DELRANGE
DES
DESTDIR
DEVNAME
DF
DHEA
DIGYS
Expand Down Expand Up @@ -1346,6 +1348,7 @@ WS
WSE
WTU
Waldie
WantedBy
WatchdogSec
Werror
Wextra
Expand Down Expand Up @@ -1992,6 +1995,7 @@ httpd
https
huawei
hunnox
hwdb
hypervisor
hypervisors
iBox
Expand Down Expand Up @@ -2082,6 +2086,7 @@ jbus
jdk
jenkins
jessie
jimklimov
journalctl
jpg
jpgraph
Expand Down

0 comments on commit b5a57fe

Please sign in to comment.