`assert` has the annoying property that it dumps a lot of code at the
user without the built in capability to display a nicer message. We have
worked around this using `assertMsg` which would *additionally* display
a nice message. We can do even better: By using `throw` we can make
evaluation fail before assert draws its conclusions and prevent it from
displaying the code making up the assert condition, so we get the nicer
message of `throw` and the syntactical convenience of `assert`.
Before:
nix-repl> python.override { reproducibleBuild = true; stripBytecode = false; }
trace: Deterministic builds require stripping bytecode.
error: assertion (((lib).assertMsg (reproducibleBuild -> stripBytecode)) "Deterministic builds require stripping bytecode.") failed at /home/lukas/src/nix/nixpkgs/pkgs/development/interpreters/python/cpython/2.7/default.nix:45:1
After:
nix-repl> python.override { reproducibleBuild = true; stripBytecode = false; }
error: Deterministic builds require stripping bytecode.
The `extraConfig` parameter only handles text - it doesn't support
arbitrary secrets and, with the way it's processed in the setup
script, it's very easy to accidentally unescape the echoed string and
run shell commands / feed garbage to bash.
To fix this, implement a new option, `config`, which instead takes a
typed attribute set, generates the `.env` file in nix and does
arbitrary secret replacement. This option is then used to provide the
configuration for all other options which change the `.env` file.
When upgrading bookstack, if something in the cache conflicts with the
new installation, the artisan commands might fail. To solve this, make
the cache lifetime bound to the setup service. This also removes the
`cacheDir` option, since the path is now handled automatically by
systemd.
network.target is reached earlier, but with much fewer services
available. DNS is likely to be not functional before
network-online.target, so waiting for that seems better for that reason
alone. the existing backends for network-online.target all seem to do
reasonable things (wait until all links are in *some* stable state), so
we shouldn't lose anything from waiting.
This removes `/run/nixos/activation-reload-list` (which we will need in
the future when reworking the reload logic) and makes
`/run/nixos/activation-restart-list` honor `restartIfChanged` and
`reloadIfChanged`. This way activation scripts don't have to bother with
choosing between reloading and restarting.
Instead of referencing all library functions through `lib.` and
builtins through `builtins.` at every invocation, inherit them into
the appropriate scope.
The tsm-client needs a tsm-server to do anything useful.
Without a server, automated tests can just
check diagnostic outputs for plausibility.
The commit at hand adds two tests:
1.
The command line interface `dsmc` is called,
then it is verified that the program does
* report the correct client version,
* find its configuration file,
* report a connection error.
2.
To check the GUI (and the tsm-client nixos module), we add a
vm test which uses the module to install `tsm-client-withGui`.
To verify that the GUI's basic functionality is present,
we skip over all connection failure related error
messages and open the "Connection Information"
dialog from the main application window.
This dialog presents the node name and the client version;
both are verified by the test.
Note: Our `tsm-client` build recipe consists of two packages:
The "unwrapped" package and the final package.
This commit puts the unwrapped one into the final
package's `passthru` so that tests can access
the original version string that is needed to check
the client version reported by the application.
The module option type `nonEmptyStr` was introduced in commit
a3c5f0cba8
The tsm modules previously simply used
`strMatching ".+"` to prevent empty option strings,
but the new type is more thorough as
it also catches space-only strings.
This enables some systemd sandboxing
options for the `tsm-backup.service`.
Those settings have been determined by expermentation.
This commit tries hard to protect the filesystem from
write access, but not to hide anything from read access,
so users can backup all files they choose to backup.
An exception are API filesystems (`/dev`, `/proc`, `/sys`):
As their "files" are not stored on persistent storage,
they are sandboxed away as much as possible.
Note that the service still has to run with root
privileges to reach files with limited access permissions.
The obvious alternative to use a dedicated user account and
the `CAP_DAC_READ_SEARCH` capability to permit system-wide
read access while blocking write access does not work.
Experiments have shown that `dsmc` verifies access permissions
for each file before attempting to open it for reading.
Hence `dsmc` refuses to copy files where the file permission
mode blocks read access -- even if process capabilities
would allow it to proceed irrespective of permissions.
Use systemd's LoadCredential mechanism to make the secret files
available to the service.
This gets rid of the privileged part of the ExecPreStart script which
only served to copy these files and assign the correct
permissions. There's been issues with this approach when used in
combination with DynamicUser, where sometimes the user isn't created
before the ExecPreStart script runs, causing the error
install: invalid user ‘keycloak’
This should fix that issue.
Unfortunately, all of the ExecPreStart script had to be moved to
ExecStart, since credentials aren't provided to ExecPreStart. See
https://github.com/systemd/systemd/issues/19604.