Watch
0
0
Fork
You've already forked hyperhive
0

swarm-secret-publish: drop RemainAfterExit so the path unit re-runs it

swarm-secret-publish.service was Type=oneshot with RemainAfterExit=true.
After its first successful run it stayed active (exited), so every later
start from swarm-secret-publish.path (PathChanged on authelia's client
secret dir) was a no-op: a secret minted or replaced after that first run
never reached the store, and nothing logged it.

Without RemainAfterExit the unit goes inactive after each run, so each
PathChanged event starts a fresh publish. Same shape as
swarm-bao-forge-publisher in hive-forge/default.nix. No unit requires,
wants, orders after, binds to or is part of swarm-secret-publish.service,
so nothing depended on it staying active.

This also covers the first-boot race where the publisher runs before
authelia's first mint: the mint writes the file, and the path unit now
starts the publisher again.

A module-eval case pins it: the path unit targets the service, the
service is a oneshot, and RemainAfterExit is unset or false.

Closes #5032
This commit is contained in:
atlas 2026-10-10 13:31:17 +02:00 • committed by mara
commit 6982b2ec14
2 changed files with 16 additions and 1 deletions

View file

@ -177,9 +177,10 @@ in
baoDeploy.package
pkgs.coreutils
];
# ⚠️ No `RemainAfterExit`. A oneshot that stays `active (exited)` turns
# every later start from the path unit above into a no-op.
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
# Bounded here rather than left to systemd's default, so the number a
# boot waits on is in the file that waits. A sealed store answers on
# the port and never answers the write.

View file

@ -379,6 +379,20 @@ let
&& !(m.systemd.services ? swarm-secret-publish)
&& !(m.systemd.paths ? swarm-secret-publish);
}
{
# The path unit's start is a no-op while its target is `active (exited)`,
# so a secret minted after the first run would never be published.
# `Type` is read too, so a missing `serviceConfig` cannot pass the arm.
name = "the publisher's path unit starts a oneshot that does not remain active";
ok =
let
m = secretPublisherHere;
sc = m.systemd.services.swarm-secret-publish.serviceConfig;
in
m.systemd.paths.swarm-secret-publish.pathConfig.Unit == "swarm-secret-publish.service"
&& sc.Type == "oneshot"
&& !(sc.RemainAfterExit or false);
}
];
in
runGroup "secret-publisher" cases