Watch
0
0
Fork
You've already forked hyperhive
0

Compare commits

..
Author SHA1 Message Date
atlas
60393d0e32 module-eval: fix the last stale 'four' count in the swarm-controller comment
Same slice, same fact: socketPath lost its pre-rename path, so only three
old paths are defined in the fixture now, not four. Missed this sentence
while fixing the count three lines below it.
2026-09-17 19:29:46 +02:00
atlas
b590038b0f module-eval: assert the swarm-controller socket's default, not its deleted shim
readOnly means socketPath can only ever hold the default, so the fixture's
old custom value can no longer reach the unit and the check.module-eval
assertion for it was failing. Assert the default instead of deleting the
check -- it still catches the env var vanishing or being misspelled, which
deleting it would not.

Also corrects the block's stale 'FOUR movers' count: socketPath lost its
pre-rename shim in the same slice, so only three of the asserted values
are still rename-shim movers.
2026-09-17 19:27:30 +02:00
atlas
fcb8a594bb swarm-controller: make socketPath readOnly instead of asserting it
readOnly makes a bad socketPath inexpressible rather than diagnosed
after the fact. Since readOnly rejects any definition including one
arriving through a rename shim, drop the deploy.nix rename entry for
it and the fixture line exercising it, and update the controllerOldPath
comment's shim count from seven to six.

Refs #4208
2026-09-17 19:27:30 +02:00
atlas
205986f77e swarm-controller: assert socketPath is not in a shared runtime dir
The socket is 0666 (nginx needs to connect(2) as a different user), so its
directory is the only thing bounding what the gateway's nginx can reach —
the crate's README already says so. A unit test pins DEFAULT_SOCKET, but
that only catches a developer editing the const; an operator setting the
documented socketPath option to a shared dir (notably /run/hyperhive,
which holds the host admin socket, or /run/hive) went unenforced.

Denylist rather than the general "not any other module's socket dir"
form — narrower, but it's what the README names and lands without pulling
in other modules' constants.

Refs #4208
2026-09-17 19:27:30 +02:00
3 changed files with 16 additions and 14 deletions

View file

@ -69,10 +69,6 @@ in
[ "services" "hyperhive" "swarm" "controller" "enable" ]
[ "services" "hyperhive" "deploy" "swarm-controller" "enable" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "controller" "socketPath" ]
[ "services" "hyperhive" "deploy" "swarm-controller" "socketPath" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "controller" "forgeTokenFile" ]
[ "services" "hyperhive" "deploy" "swarm-controller" "forgeTokenFile" ]

View file

@ -447,6 +447,7 @@ in
socketPath = lib.mkOption {
type = lib.types.str;
default = "/run/swarm-controller/controller.sock";
readOnly = true;
description = ''
Unix socket the daemon serves on, and the path the gateway's nginx
proxies to.

View file

@ -201,13 +201,12 @@ let
deploy.matrix.maxRequestSize = 99000000;
};
# `enable` is spelled the OLD way like everything else here, so all seven
# of the controller's shims are exercised rather than six.
# `enable` is spelled the OLD way like everything else here, so all six
# of the controller's shims are exercised rather than five.
controllerOldPath = hive {
swarm.controller.enable = true;
swarm.controller.package = pkgs.emptyDirectory;
swarm.controller.swarmctlPackage = pkgs.emptyDirectory;
swarm.controller.socketPath = "/run/test-ctrl/ctrl.sock";
swarm.controller.forgeTokenFile = "/run/secrets/ctrl-forge.token";
swarm.controller.authBridgeUrl = "http://127.0.0.1:19097";
swarm.controller.queue.clientSecretFile = "/run/secrets/ctrl-queue.secret";
@ -962,19 +961,25 @@ let
# Reads the host's tmpfiles rules, not the options: the socket directory
# nginx and the container share is created there, so a rename that
# resolved but stopped reaching the module would leave the gateway
# proxying to a path nothing creates. All four old paths are defined in
# the fixture, so removing any single shim fails the eval rather than
# only the one this assertion reads.
# All FOUR movers are asserted as rendered effects rather than as option
# values, so a rename that resolved but stopped reaching the module is
# caught per-option instead of only where one assertion happens to look.
# proxying to a path nothing creates. All three old paths are defined
# in the fixture, so removing any single shim fails the eval rather
# than only the one this assertion reads.
# THREE movers (authBridgeUrl, forgeTokenFile, queue.clientSecretFile)
# are asserted as rendered effects rather than as option values, so a
# rename that resolved but stopped reaching the module is caught
# per-option instead of only where one assertion happens to look.
# socketPath is no longer one of them: it went readOnly and lost its
# shim in the same slice, so it has no pre-rename path left to prove
# reaches the unit — the SOCKET line below instead pins the one value
# it can ever hold, the default, so the env var vanishing or being
# misspelled still fails this arm.
name = "a config written against the pre-rename swarm-controller paths still reaches the unit";
ok =
let
u = controllerOldPath.systemd.services.swarm-controller;
creds = u.serviceConfig.LoadCredential;
in
u.environment.SWARM_CONTROLLER_SOCKET == "/run/test-ctrl/ctrl.sock"
u.environment.SWARM_CONTROLLER_SOCKET == "/run/swarm-controller/controller.sock"
&& u.environment.SWARM_CONTROLLER_AUTH_BRIDGE_URL == "http://127.0.0.1:19097"
&& lib.any (c: lib.hasInfix "/run/secrets/ctrl-queue.secret" c) creds
&& lib.any (c: lib.hasInfix "/run/secrets/ctrl-forge.token" c) creds;