docs: trim the reload rationale to the live constraint
Keeps why the setting exists (the bridge writes this file and cannot restart authelia) and drops the incident narrative and the answered objections -- that history belongs in the PR discussion, not in three comment blocks a future reader has to scroll past.
This commit is contained in:
parent
63fc54edc5
commit
4c7865cd8b
3 changed files with 11 additions and 49 deletions
|
|
@ -967,25 +967,12 @@ in
|
||||||
server.address = "tcp://127.0.0.1:${toString cfg.port}";
|
server.address = "tcp://127.0.0.1:${toString cfg.port}";
|
||||||
log.level = "info";
|
log.level = "info";
|
||||||
|
|
||||||
# Authelia reads this file once, at STARTUP. `watch` makes it
|
# `watch` is load-bearing, not a convenience: authelia reads
|
||||||
# re-read on change, and that is load-bearing rather than a
|
# this file once at startup, and `swarm-authelia-bridge` writes
|
||||||
# convenience.
|
# it to create agent identities while being unable to restart
|
||||||
#
|
# authelia — running unprivileged is the whole reason it may
|
||||||
# `swarm-authelia-bridge` writes this file to create agent
|
# write the file at all. Without this, an identity it creates is
|
||||||
# identities and **cannot** restart authelia: running
|
# real on disk and invisible until something unrelated restarts.
|
||||||
# unprivileged inside the container is the whole reason it is
|
|
||||||
# allowed to write the file at all, so "restart the unit" is
|
|
||||||
# exactly the privilege it was designed not to hold. Without
|
|
||||||
# `watch` every identity it creates is real on disk and
|
|
||||||
# invisible to the running authelia until something unrelated
|
|
||||||
# bounces the unit.
|
|
||||||
#
|
|
||||||
# `swarmctl` does restart authelia after writing — but that is
|
|
||||||
# a `systemctl -M` shellout that can fail, and when it did the
|
|
||||||
# symptom was a login refused for a user whose record was
|
|
||||||
# already correct on disk, with nothing implicating the
|
|
||||||
# reload. This setting is what makes correctness stop
|
|
||||||
# depending on that restart succeeding.
|
|
||||||
authentication_backend.file = {
|
authentication_backend.file = {
|
||||||
path = cfg.usersFile;
|
path = cfg.usersFile;
|
||||||
watch = true;
|
watch = true;
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,6 @@ let
|
||||||
# parameters baked into a hash have to match the verifier's.
|
# parameters baked into a hash have to match the verifier's.
|
||||||
SWARMCTL_AUTHELIA_BIN = "${autheliaCfg.package}/bin/authelia";
|
SWARMCTL_AUTHELIA_BIN = "${autheliaCfg.package}/bin/authelia";
|
||||||
SWARMCTL_AUTHELIA_USERS_FILE = autheliaCfg.hostUsersFile;
|
SWARMCTL_AUTHELIA_USERS_FILE = autheliaCfg.hostUsersFile;
|
||||||
# No MACHINE/UNIT here any more: `swarmctl` no longer restarts authelia,
|
|
||||||
# because authelia watches the users file itself. Those two values existed
|
|
||||||
# solely to name a `systemctl -M` target.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
natsCfg = config.services.hyperhive.swarm.nats;
|
natsCfg = config.services.hyperhive.swarm.nats;
|
||||||
|
|
|
||||||
|
|
@ -343,33 +343,11 @@ fn publish(paths: &Paths, store: &UserStore) -> Result<()> {
|
||||||
write_atomic(&paths.store, &format!("{store_json}\n"))?;
|
write_atomic(&paths.store, &format!("{store_json}\n"))?;
|
||||||
write_atomic(&paths.users_file, &rendered)?;
|
write_atomic(&paths.users_file, &rendered)?;
|
||||||
|
|
||||||
// No restart. Authelia is configured with
|
// No restart: authelia watches this file
|
||||||
// `authentication_backend.file.watch`, so it re-reads this file itself.
|
// (`authentication_backend.file.watch`). Deliberately not `swarmctl`'s job
|
||||||
//
|
// — `swarm-authelia-bridge` writes the same file and *cannot* restart
|
||||||
// This used to shell out to `systemctl -M <machine> restart <unit>`. That
|
// anything, since running unprivileged is the whole reason it may write
|
||||||
// was the wrong shape twice over: it could fail (it did — a login refused
|
// it. A reload that depends on which process wrote is not a reload.
|
||||||
// for a user whose record was already correct on disk, with nothing in
|
|
||||||
// either log implicating the reload), and it only ever worked for THIS
|
|
||||||
// writer. `swarm-authelia-bridge` writes the same file to create agent
|
|
||||||
// identities and cannot restart anything: running unprivileged inside the
|
|
||||||
// container is the whole reason it may write the file at all. A reload
|
|
||||||
// that depends on which process did the writing is not a reload.
|
|
||||||
//
|
|
||||||
// The three objections that previously kept `watch` out of this path are
|
|
||||||
// all now answered, and they were good objections — recorded here so the
|
|
||||||
// next reader does not have to re-earn them:
|
|
||||||
//
|
|
||||||
// - "could not be verified against the pinned build" — it is now:
|
|
||||||
// authelia v4.39.20's own `validate-config` accepts `watch` and
|
|
||||||
// *rejects* a deliberate misspelling of it, so the key is recognised
|
|
||||||
// rather than silently swallowed.
|
|
||||||
// - "does the watch survive the rename(2) used above" — yes: authelia
|
|
||||||
// watches the containing *directory*, so a rename into it is observed.
|
|
||||||
// A watch on the old inode alone would indeed have missed it.
|
|
||||||
// - "can it observe a partially written file" — it cannot, and that is
|
|
||||||
// structural rather than a debounce we are trusting: every writer of
|
|
||||||
// this file goes through `write_atomic` below, so no partial content is
|
|
||||||
// ever visible under the final name. (Authelia debounces as well.)
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue