`plv8` depends on the outdated NodeJS 20. Upstream waits for v8-cmake to
make a move (https://github.com/plv8/plv8/issues/610), but that project
has been inactive for a bit more than a year.
Even when allowing the insecure nodejs20, the package fails to build.
Insecure and broken - we might as well drop it.
This commit adds a freeform type to accomodate for new options to use
with ALTER ROLE.
It also will perform extra checking and conversion for options with
parameters.
Converts option names into upper case with space instead of underscore.
...including a slightly more careful config around restarts, i.e.
* We have intervals of 5 seconds between restarts instead of 100ms.
* If we exceed 5 start attempts in 5*120s (with 120s being the timeout),
start job gets rate-limited and thus aborted. Do note that there are
at most 5 start attempts allowed in ~625s by default. If the startup
fails very quickly, either wait until the rate-limit is over or reset
the counter using `systemctl reset-failed postgresql.service`.
* The interval of 625s (plus 5s of buffer) are automatically derived
from RestartSec & TimeoutSec. Changing either will also affect
StartLimitIntervalSec unless overridden with `mkForce`.
At my employer's NixOS-based platform, PostgreSQL is configured with
`Restart=always` which got never upstreamed, unfortunately.
This however revealed an interesting problem when using bi-directional
BindsTo: when killing `postgresql.service`, sometimes both the service &
target starts back up and sometimes they don't. According to an upstream
bugreport[1] this is a known problem because you have two conflicting
operations scheduled in a single transaction, namely
* When (auto-)restarting, a restart job for all units bound to the
restarting unit are immediately scheduled[2].
* Due to the `BindsTo` relationship, a stop-job for `postgresql.target`
is scheduled immediately by the manager loop[3]. This is caused by the
`UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT` "atom" which is ONLY set for a
BindsTo relationship[4].
When this is processed first, the restart is inhibited:
Jul 12 13:25:51 nixos systemd[1]: postgresql.service: Main process exited, code=killed, status=9/KILL
Jul 12 13:25:51 nixos systemd[1]: postgresql.service: Changed running -> stop-sigterm
Jul 12 13:25:51 nixos systemd[1]: postgresql.target: Trying to enqueue job postgresql.target/stop/replace
Jul 12 13:25:51 nixos systemd[1]: postgresql.service: Installed new job postgresql.service/stop as 80053
Jul 12 13:25:51 nixos systemd[1]: postgresql.target: Installed new job postgresql.target/stop as 80052
Jul 12 13:25:51 nixos systemd[1]: postgresql.target: Enqueued job postgresql.target/stop as 80052
[...]
Jul 12 13:25:51 nixos systemd[1]: postgresql.service: Service restart not allowed.
It's subtle and non-obvious from the man-page, but the way how units are
stopped is different when using `PartOf=` or `Requires=` which don't have the
`UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT` property, but instead schedules the
stop/start of the target AFTER the stop-job of postgresql.service which
is turned into a start-job because of Restart=always:
Jul 12 13:33:00 nixos systemd[1]: postgresql.service: Main process exited, code=killed, status=9/KILL
[...]
Jul 12 13:33:00 nixos systemd[1]: postgresql.service: Failed with result 'signal'.
Jul 12 13:33:00 nixos systemd[1]: postgresql.service: Service will restart (restart setting)
[...]
Jul 12 13:33:00 nixos systemd[1]: postgresql.target: Installed new job postgresql.target/restart as 80996
Jul 12 13:33:00 nixos systemd[1]: postgresql.service: Installed new job postgresql.service/restart as 80907
[...]
Jul 12 13:33:00 nixos systemd[1]: postgresql.service: Scheduled restart job, restart counter is at 1.
[...]
Jul 12 13:33:00 nixos systemd[1]: Stopped target postgresql.target.
Jul 12 13:33:00 nixos systemd[1]: postgresql.target: Converting job postgresql.target/restart -> postgresql.target/start
Jul 12 13:33:00 nixos systemd[1]: Stopping postgresql.target...
[...]
Jul 12 13:33:00 nixos systemd[1]: Stopped postgresql.service.
Jul 12 13:33:00 nixos systemd[1]: postgresql.service: Converting job postgresql.service/restart -> postgresql.service/start
[...]
Jul 12 13:33:00 nixos systemd[1]: postgresql.service: Changed dead -> running
Jul 12 13:33:00 nixos systemd[1]: postgresql.service: Job 80907 postgresql.service/start finished, result=done
Jul 12 13:33:00 nixos systemd[1]: Started postgresql.service.
Jul 12 13:33:00 nixos systemd[1]: postgresql.target: Changed dead -> active
[...]
Jul 12 13:33:00 nixos systemd[1]: Reached target postgresql.target.
Do note that the stop job (including the restart) of postgresql.service
is fully processed here before dealing with PartOf/ConsistsOf
relationships.
I tested this against the following cases:
| Unit | Action | Propagates to |
| ------------------ | ------------ | ------------------ |
| postgresql.target | restart | postgresql.service |
| postgresql.target | start | postgresql.service |
| postgresql.target | stop | psotgresql.service |
| postgresql.service | start | postgresql.target |
| postgresql.service | restart | postgresql.target |
| postgresql.service | stop | postgresql.target |
| postgresql.service | auto-restart | postgresql.target |
| postgresql.service | failure | postgresql.target |
[1] e.g. systemd issue 8374
[2] https://github.com/systemd/systemd/blob/v256-stable/src/core/service.c#L2535-L2542
[3] https://github.com/systemd/systemd/blob/v256-stable/src/core/manager.c#L1611-L1626
[4] https://github.com/systemd/systemd/blob/v256-stable/src/core/unit-dependency-atom.c#L30-L35
The new postgresql.target will now wait until recovery is done and
read/write connections are possible.
This allows ensure* scripts and downstream migrations to work properly
after recovery from backup.
Resolves#346886
This avoids restarting the postgresql server, when only ensureDatabases
or ensureUsers have been changed. It will also allow to properly wait
for recovery to finish later.
To wait for "postgresql is ready" in other services, we now provide a
postgresql.target.
Resolves#400018
Co-authored-by: Marcel <me@m4rc3l.de>
Since v12, PostgreSQL doesn't support recovery.conf anymore and fails to
start up when this option is set:
FATAL: using recovery command file "recovery.conf" is not supported
This is documented at:
https://www.postgresql.org/docs/current/recovery-config.html
Closes#386804
The issue with coercing to `types.str` is that it's not mergeable, so
any declarations will result in an eval error like this:
error: The option `interactive.nodes.tmp.services.postgresql.settings.shared_preload_libraries' has conflicting definition values:
- In `/home/ma27/Projects/nixpkgs-hack/tmp.nix@node-tmp': "foo"
- In `/home/ma27/Projects/nixpkgs-hack/tmp.nix@node-tmp': "bar2"
Use `lib.mkForce value` or `lib.mkDefault value` to change the priority on any of these definitions.
Using a mergeable type (`types.comma`, i.e. a string, where all declarations
get joined with a comma as delimiter) fixes the problem.
Closes#385603
The problem described is that `wal-g` requires syscalls from `@resources`.
However, we don't have support for it in the module now and I don't
think it's reasonable to only support hardening adjustments for things
support by this module. Also, list is a bad datatype here since it
doesn't allow the level of customizations we need.
This is only for the syscall filterset since it's the option that's hard
to customize otherwise. For downstream configs, it's recommended to
adjust the hardening as needed in other cases.
Hence I decided to implement `services.postgresql.systemCallFilter` with
the following semantics:
* `systemCallFilter."~@resources" = true` adds `~@resources` to the
filterset.
* Setting this to `false` (e.g. in a downstream configuration using
`wal-g`) removes the entry `~@resources` from the filterset. In this
case it's sufficient since `@system-service` implies `@resources` and
the `~@resources` declaration after that discards that.
I decided to not implement logic about negations in here, but to keep
it rather simple by only allowing to set/unset entries.
As described in `systemd.exec(5)`, the ordering matters: e.g.
`@system-service` implies `@resources`, but `~@resources` _after_ that
reverts that. By default, the ordering of the keys is as follows:
* syscall groups (starting with `@`) come at first.
* negations of syscall groups (starting with `~@`) come after that.
* anything else at the end.
If further ordering is needed, it can be done like this:
```
{
services.postgresql.systemCallFilter."~@resources" = {
enable = true; # whether or not it's part of the final SystemCallFilter
priority = 23; # ordering priority in the filterset.
};
}
```
The lower the priority, the higher up the entry will be in the final
filterset.
In the case that the user wants to provide a custom data directory, we
need to grant `ReadWritePaths` for that directory. Previously this would
not happen when `/var/lib/postgresql` was used, because the condition
was not in fact checking for the default data directory, creating a gap
in then if-else scenario.
Fixes: #371680
After final improvements to the official formatter implementation,
this commit now performs the first treewide reformat of Nix files using it.
This is part of the implementation of RFC 166.
Only "inactive" files are reformatted, meaning only files that
aren't being touched by any PR with activity in the past 2 months.
This is to avoid conflicts for PRs that might soon be merged.
Later we can do a full treewide reformat to get the rest,
which should not cause as many conflicts.
A CI check has already been running for some time to ensure that new and
already-formatted files are formatted, so the files being reformatted here
should also stay formatted.
This commit was automatically created and can be verified using
nix-build https://github.com/infinisil/treewide-nixpkgs-reformat-script/archive/a08b3a4d199c6124ac5b36a889d9099b4383463f.tar.gz \
--argstr baseRev b32a094368
result/bin/apply-formatting $NIXPKGS_PATH
This will be EOL at the end of November, so there's little reason to
keep it in 24.11[1]. As discussed, we'd like to keep it for as long as
possible to make sure there's a state in nixpkgs that has the latest
minor of postgresql_12 available with the most recent CVEs fixed for
people who cannot upgrade[2].
This aspect has been made explicit in the manual now for the next .11
release.
During the discussions it has been brought up that if people just do
`services.postgresql.enable = true;` and let the code decide the
postgresql version based on `system.stateVersion`, there's a chance that
such EOL dates will be missed. To make this harder, a warning will now
be raised when using the stateVersion-condition and the oldest still
available major is selected.
Additionally regrouped the postgresql things in the release notes to
make sure these are all shown consecutively. Otherwise it's a little
hard to keep track of all the changes made to postgresql in 24.11.
[1] https://endoflife.date/postgresql
[2] https://github.com/NixOS/nixpkgs/pull/353158#issuecomment-2453056692
The test breaks like this otherwise:
machine # WARNING: error during JITing: Permission denied
machine # [ 14.012280] postgres[913]: [913] WARNING: error during JITing: Permission denied
machine # ERROR: failed to look up symbol "evalexpr_0_1": Failed to materialize symbols: { (main, { evalexpr_0_1, evalexpr_0_0 }) }
The issue was that the old test-case used `/tmp` to share data. Using
`JoinsNamespaceOf=` wasn't a real workaround since the private `/tmp` is
recreated when a service gets stopped/started which is the case here, so
the wals were still lost.
To keep the test building with `PrivateTmp=yes`, create a dedicated
directory in `/var/cache` with tmpfiles and allow the hardened
`postgresql.service` to access it via `ReadWritePaths`.
Upgrade default postgresql for stateVersion >=24.11.
This also rebuilds all packages linking against `libpq.so` to use
postgresql 16.
After re-reading https://www.postgresql.org/docs/16/release-16.html
I don't see any major risks about doing that.
these changes were generated with nixq 0.0.2, by running
nixq ">> lib.mdDoc[remove] Argument[keep]" --batchmode nixos/**.nix
nixq ">> mdDoc[remove] Argument[keep]" --batchmode nixos/**.nix
nixq ">> Inherit >> mdDoc[remove]" --batchmode nixos/**.nix
two mentions of the mdDoc function remain in nixos/, both of which
are inside of comments.
Since lib.mdDoc is already defined as just id, this commit is a no-op as
far as Nix (and the built manual) is concerned.
The enableJIT = true case was fixed in #221851 or
e2fb651752 respectively.
However this did not take the case into consideration, when doing this:
services.postgresql = {
enable = true;
enableJIT = false;
package = pkgs.postgresql_15_jit;
};
If enableJIT is treated as the source of truth, then this should indeed
cause JIT to be disabled, which this commit does.
The main idea behind that was to be able to do more sophisticated
merging for stuff that goes into `postgresql.conf`:
`shared_preload_libraries` is a comma-separated list in a `types.str`
and thus not mergeable. With this change, the option accepts both a
comma-separated string xor a list of strings.
This can be implemented rather quick using `coercedTo` +
freeform modules. The interface still behaves equally, but it allows to
merge declarations for this option together.
One side-effect was that I had to change the `attrsOf (oneOf ...)` part into
a submodule to allow declaring options for certain things. While at it,
I decided to move `log_line_prefix` and `port` into this structure as
well.
This makes it less error-prone to use the llvm package in extensions, because
it will always match the package used by the postgresql derivation itself.
Previously, you could've accidentally used llvm instead of postgresql.llvm
with a different result.
...effectively what was planned already in #266270, but it was too late
because the branches were restricted and didn't allow any breaking
changes anymore.
It also suffers from the same issue that we already had when discussing
this the last time[1] when `ensureDBOwnership` was ultimately introduced
as band-aid fix: newly created users don't get CREATE permission on
the `public` schema anymore (since psql 15), even with `ALL PRIVILEGES`.
If one's use-case is more sophisticated than having a single owner, it's
questionable anyways if this module is the correct tool since
permissions aren't dropped on a change to this option or a removal which
is pretty surprising in the context of NixOS.
[1] https://github.com/NixOS/nixpkgs/pull/266270