Watch
0
0
Fork
You've already forked hyperhive
0

deploy: forward swarm.forge.ci to deploy.ci-runner, say what the forwarded enable needs

swarm.forge.ci.* were per-host options that 4423da48 had already moved to deploy.forgejo.ci.*, so they rename straight to deploy.ci-runner like the forgejo.ci ones; ciRunnerRemoved goes with its last caller.

The forwarded enable now trips deploy.ci-runner's store-identity assertion on a host with no deploy.bao.enable. The assertion names both options and the default, the doc states the requirement, and a module-eval case pins the refusal.
This commit is contained in:
atlas 2026-10-05 21:36:11 +02:00
commit 65505f5235
4 changed files with 79 additions and 45 deletions

View file

@ -32,32 +32,6 @@
let
deployCfg = config.services.hyperhive.deploy;
# A removed CI-runner option. Its replacement has the same name under
# `deploy.ci-runner`.
ciRunnerRemoved =
from: opt:
lib.mkRemovedOptionModule
(
[
"services"
"hyperhive"
]
++ from
++ [ opt ]
)
''
The CI runner is the swarm service in swarm-ci-runner.nix. It runs on
any host, needs neither the forge nor a hive there, and registers with
the token swarm-controller publishes to the secret store. Set
services.hyperhive.deploy.ci-runner.${opt} instead.
The runner registers as a new runner on the forge, so delete the old
one in the forge's admin panel (Site administration, Actions, Runners).
A forge host that runs the swarm-controller keeps resolving
`uses: actions/checkout` from itself unless
services.hyperhive.deploy.forgejo.actionsFromSelf is false there.
See docs/scheduler/ci.md.
'';
in
{
imports = [
@ -200,13 +174,28 @@ in
[ "services" "hyperhive" "deploy" "ci-runner" "jobTimeout" ]
)
# The `swarm.forge.ci` spellings fail evaluation and name the option under
# `deploy.ci-runner` to set instead.
(ciRunnerRemoved [ "swarm" "forge" "ci" ] "enable")
(ciRunnerRemoved [ "swarm" "forge" "ci" ] "name")
(ciRunnerRemoved [ "swarm" "forge" "ci" ] "concurrency")
(ciRunnerRemoved [ "swarm" "forge" "ci" ] "labels")
(ciRunnerRemoved [ "swarm" "forge" "ci" ] "package")
# The runner toggle sat under `swarm.forge.ci` before `deploy.forgejo.ci`.
# Both were per-host, so each forwards straight to its final path.
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "forge" "ci" "enable" ]
[ "services" "hyperhive" "deploy" "ci-runner" "enable" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "forge" "ci" "name" ]
[ "services" "hyperhive" "deploy" "ci-runner" "name" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "forge" "ci" "concurrency" ]
[ "services" "hyperhive" "deploy" "ci-runner" "concurrency" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "forge" "ci" "labels" ]
[ "services" "hyperhive" "deploy" "ci-runner" "labels" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "forge" "ci" "package" ]
[ "services" "hyperhive" "deploy" "ci-runner" "package" ]
)
# The queue's callout identity. What stays under `swarm.nats` is what the
# queue IS to every hive — the ports it answers on and the client id it is

View file

@ -167,9 +167,11 @@ in
swarm-bao-ci-runner.service reads the forge's runner registration
token with it, and the runner cannot register without that token.
On the host that runs the store, glue-bao-tls.nix supplies both as
defaults. Elsewhere, copy ci-runner.pem and ci-runner-key.pem from
the store host's /var/lib/swarm-bao-pki/ and name them here.
Both default to the pair glue-bao-tls.nix mints when
services.hyperhive.deploy.bao.enable is true (the host that runs
the store). Otherwise copy ci-runner.pem and ci-runner-key.pem from
the store host's /var/lib/swarm-bao-pki/ and name them in those two
options.
'';
}
];

View file

@ -74,8 +74,21 @@ let
deploy.bao.ciRunnerClientCertFile = "/etc/pki/bao-ci-runner.pem";
deploy.bao.ciRunnerClientKeyFile = "/etc/pki/bao-ci-runner-key.pem";
};
# The old name alone, with no store identity placed and none defaulted.
ciUnderForgeNoIdentity = hive {
deploy.hive-controller.enable = false;
deploy.forgejo.ci.enable = true;
};
# The older spelling, under the swarm-level forge options.
ciUnderSwarmForge = hive { swarm.forge.ci.enable = true; };
ciUnderSwarmForge = hive {
swarm.forge.ci.enable = true;
swarm.forge.ci.name = "older-runner";
swarm.forge.ci.concurrency = 2;
swarm.forge.ci.labels = [ "nix:host" ];
swarm.forge.ci.package = pkgs.hello;
deploy.bao.ciRunnerClientCertFile = "/etc/pki/bao-ci-runner.pem";
deploy.bao.ciRunnerClientKeyFile = "/etc/pki/bao-ci-runner-key.pem";
};
runsForge = m: m.services.hyperhive.deploy.forgejo.enable && m.containers ? hive-forge;
@ -241,9 +254,30 @@ let
&& !(lib.any (a: !a.assertion) ciUnderForge.assertions);
}
{
# A removed option evaluates to an assertion naming the replacement.
name = "a CI option under swarm.forge names its replacement under deploy.ci-runner";
ok = refusedOver ciUnderSwarmForge "services.hyperhive.deploy.ci-runner.enable instead";
# The control is the container: it only exists if `enable` arrived.
name = "a CI option under swarm.forge sets the same option under deploy.ci-runner";
ok =
let
r = ciUnderSwarmForge.services.hyperhive.deploy.ci-runner;
in
r.enable
&& r.name == "older-runner"
&& r.concurrency == 2
&& r.labels == [ "nix:host" ]
&& r.package == pkgs.hello
&& ciUnderSwarmForge.containers ? swarm-ci-runner
&& lib.any (lib.hasInfix "services.hyperhive.swarm.forge.ci.enable") ciUnderSwarmForge.warnings
&& !(lib.any (a: !a.assertion) ciUnderSwarmForge.assertions);
}
{
# The rename carries `enable` but not the identity: an old config with
# only the old name is refused, and the message says what to set. The
# control is the placed pair in `ciUnderForge` above.
name = "an old CI enable without a store identity is refused naming the options to set";
ok =
refusedOver ciUnderForgeNoIdentity "services.hyperhive.deploy.bao.ciRunnerClientCertFile"
&& refusedOver ciUnderForgeNoIdentity "services.hyperhive.deploy.bao.ciRunnerClientKeyFile"
&& refusedOver ciUnderForgeNoIdentity "services.hyperhive.deploy.bao.enable";
}
{
# Nothing writes the delivery path away from the forge, and a