Co-Authored-By: Yonas Habteab <yonas.habteab@icinga.com>
Once the new worker process has read the config, it also includes a
`include */include.conf` statement within the config packages root
directory, and from there on we must not allow to delete any stage
directory from the config package. Otherwise, when the worker actually
evaluates that include statement, it will fail to find the directory
where the include file is located, or the `active.conf` file, which is
included from each stage's `include.conf` file, thus causing the worker
fail.
Previously, we used a simple boolean to track the state of the package updates,
and didn't reset it back when the config validation was successful because it was
assumed that if we successfully validated the config beforehand, then the worker
would also successfully reload the config afterwards, and that the old worker would
be terminated. However, this assumption is not always true due to a number of reasons
that I can't even think of right now, but the most obvious one is that after we successfully
validated the config, the config might have changed again before the worker was able
to reload it. If that happens, then the new worker might fail to successfully validate
the config due to the recent changes, in which case the old worker would remain active,
and this flag would still be set to true, causing any subsequent requests to fail with a
`423` until you manually restart the Icinga 2 service.
So, in order to prevent such a situation, we are additionally tracking the last time a reload
failed and allow to bypass the `m_RunningPackageUpdates` flag only if the last reload failed
time was changed since the previous request.
This commit intruduces a small helper class that wraps any writer and
provides a flush operation that performs the corresponding action if the
writer is an AsyncJsonWriter and does nothing otherwise.
Replacing invalid UTF-8 characters beforehand by our selves doesn't make
any sense, the serializer can literally perform the same replacement ops
with the exact same Unicode replacement character (U+FFFD) on its own.
So, why not just use it directly? Instead of wasting memory on a temporary
`String` object to always UTF-8 validate every and each value, we just
use the serializer to directly to dump the replaced char (if any) into
the output writer. No memory waste, no fuss!
The Array, Dictionary, and Namespace types provide a Freeze() method that makes
them read-only. So far, there was the possibility to call some methods with
`overrideFrozen=true` which would then bypass the corresponding check and allow
modification of the data structures nonetheless.
With 24b57f0d3a222835178e88489eabd595755ed883, this possibility was already
removed from the Namespace type. However, for interface compatibility, it kept
the parameter and just ignores it, throwing an exception on any modification on
a frozen instance.
The only place using `overrideFrozen` was processing of the `-D`/`--define`
command line flag that allows setting additional variables in the DSL. At the
time it is evaluated, there are no user-created data structures yet that could
be frozen, so the only frozen objects that could be encountered are Namespaces
(Icinga doesn't freeze other types by itself) and for these, `overrideFrozen`
already has no effect.
Hence, there is no harm in removing `overrideFrozen` altogether. This
simplifies the code and also means that frozen objects are now indeed read-only
without exceptions, allowing further optimizations regarding locking in the
future.
Within the GNU/Linux distribution specific installation guides, the "Set
up Icinga DB" section was only excluded for openSUSE. However, since
there is an openSUSE installation guide within Icinga DB[^0], this is
not consistent. Thus, the if-guard was removed, resulting in this
section being available for each distribution. Windows is already
excluded through an if-guard above.
Some cases for Fedora were missing, which were also added.
[^0]: https://icinga.com/docs/icinga-db/latest/doc/02-Installation/openSUSE/
With Fedora 41, DNF was upgraded to version 5, breaking the command line
API of "dnf config-manager"[^0]. Unfortunately, DNF 5's addrepo does not
work with a simple URL anymore, but requires to construct a .repo file.
Furthermore, no information about trusting the Icinga signing key was
available, resulting in one being unable to install packages. This was
already the case for Fedora 40, still using DNF 4.
Since we are building Icinga DB for Fedora, I have included Icinga DB
documentation for Fedora. Otherwise, this section was empty.
Finally, the icingadb-redis-selinux package was mentioned for
distributions were we started to build SELinux packages for[^1].
[^0]: https://docs.fedoraproject.org/en-US/quick-docs/adding-or-removing-software-repositories-in-fedora/#_adding_repositories
[^1]: https://github.com/Icinga/icingadb/issues/580