Watch
0
0
Fork
You've already forked hyperhive
0

deploy: rename the old forgejo.ci options to ci-runner instead of removing them

deploy.forgejo.ci.{enable,name,concurrency,labels,package,jobTimeout} each
have a same-typed, same-meaning counterpart under deploy.ci-runner on the
same host, so they are mkRenamedOptionModule entries again and a config that
still sets them evaluates with the standard rename warning. The swarm.forge.ci
spellings stay removals.

docs/scheduler/ci.md states the rename, that the old hive-ci runner's entry
is deleted by hand in the forge admin panel, and that actionsFromSelf
defaults on where the controller runs.
This commit is contained in:
atlas 2026-10-05 21:31:38 +02:00
commit b114c6b165
3 changed files with 77 additions and 14 deletions

View file

@ -125,6 +125,13 @@ name), `jobTimeout` (per-job wall-clock cap, default `"1h"`, Go duration string
for example `"3h"` — a job that exceeds it's killed so a hung or runaway build
can't hold the runner's single slot indefinitely).
The old `services.hyperhive.deploy.forgejo.ci.{enable,name,concurrency,labels,package,jobTimeout}`
are still accepted: each is a rename of the same-named option under
`deploy.ci-runner`, same type and meaning, and evaluation warns naming both
paths. Set the new name to silence the warning. The two `name` defaults
differ (`hive-ci` before, `swarm-ci-runner` now), so a host that never set the
old `name` shows up under the new default.
## Container design
- **Private netns, bridge-attached**: the container runs in its own network namespace (`privateNetwork = true`, `hostBridge`), takes its address from the gateway's DHCP, and resolves through the gateway's dnsmasq on the bridge IP. It can't reach host-loopback services — the core dashboard at `127.0.0.1:7000` and the raw forge port are unreachable from CI.
@ -180,7 +187,10 @@ can't hold the runner's single slot indefinitely).
and act as this runner; see the security section below.
A new registration is a new runner on the forge: the previous entry stays in
the forge admin panel as offline until an admin deletes it.
the forge admin panel as offline until an admin deletes it. The runner the old
`hive-ci` module registered is one such entry, since this runner registers
under its own name and token. Delete it under Site administration, Actions,
Runners.
## Actions checkout mirror
@ -192,6 +202,11 @@ controller seeds an `actions/checkout` pull-mirror on the forge and Forgejo's
`uses: actions/checkout@vN` steps then resolve on the forge, with no external
DNS on the CI critical path.
A forge host that runs the swarm controller therefore resolves
`uses: actions/checkout` from itself, with or without a runner on that host.
Set `actionsFromSelf = false` there to resolve actions from `data.forgejo.org`
and seed no mirror.
The option defaults to whether the forge's host also runs the swarm controller
(`services.hyperhive.deploy.swarm-controller.enable`): on when it does, off
otherwise. Setting it `true` on a forge host without the controller leaves

View file

@ -173,20 +173,40 @@ in
[ "services" "hyperhive" "deploy" "swarm-otel" "clientSecretFile" ]
)
# Removed rather than renamed: the runner is a different container with a
# registration of its own, so an old definition is a deployment to re-read
# rather than a path to forward.
# The runner moved from `deploy.forgejo.ci` to `deploy.ci-runner` with
# every option keeping its type and meaning, so the old paths forward.
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "deploy" "forgejo" "ci" "enable" ]
[ "services" "hyperhive" "deploy" "ci-runner" "enable" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "deploy" "forgejo" "ci" "name" ]
[ "services" "hyperhive" "deploy" "ci-runner" "name" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "deploy" "forgejo" "ci" "concurrency" ]
[ "services" "hyperhive" "deploy" "ci-runner" "concurrency" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "deploy" "forgejo" "ci" "labels" ]
[ "services" "hyperhive" "deploy" "ci-runner" "labels" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "deploy" "forgejo" "ci" "package" ]
[ "services" "hyperhive" "deploy" "ci-runner" "package" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "deploy" "forgejo" "ci" "jobTimeout" ]
[ "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")
(ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "enable")
(ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "name")
(ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "concurrency")
(ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "labels")
(ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "package")
(ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "jobTimeout")
# 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

@ -63,8 +63,19 @@ let
deploy.ci-runner.enable = true;
};
# A host config that still names the runner under the forge.
ciUnderForge = hive { deploy.forgejo.ci.enable = true; };
# A host config that still names the runner under the forge, every option.
ciUnderForge = hive {
deploy.forgejo.ci.enable = true;
deploy.forgejo.ci.name = "old-runner";
deploy.forgejo.ci.concurrency = 3;
deploy.forgejo.ci.labels = [ "nix:host" ];
deploy.forgejo.ci.package = pkgs.hello;
deploy.forgejo.ci.jobTimeout = "2h";
deploy.bao.ciRunnerClientCertFile = "/etc/pki/bao-ci-runner.pem";
deploy.bao.ciRunnerClientKeyFile = "/etc/pki/bao-ci-runner-key.pem";
};
# The older spelling, under the swarm-level forge options.
ciUnderSwarmForge = hive { swarm.forge.ci.enable = true; };
runsForge = m: m.services.hyperhive.deploy.forgejo.enable && m.containers ? hive-forge;
@ -212,10 +223,27 @@ let
name = "the CI runner compares .runner's labels in the form the daemon writes them";
ok = registerService.environment.SWARM_CI_RUNNER_LABELS == "hive-ci:host,nix:host";
}
{
# The control is the container: it only exists if `enable` arrived.
name = "a CI option under deploy.forgejo sets the same option under deploy.ci-runner";
ok =
let
r = ciUnderForge.services.hyperhive.deploy.ci-runner;
in
r.enable
&& r.name == "old-runner"
&& r.concurrency == 3
&& r.labels == [ "nix:host" ]
&& r.package == pkgs.hello
&& r.jobTimeout == "2h"
&& ciUnderForge.containers ? swarm-ci-runner
&& lib.any (lib.hasInfix "services.hyperhive.deploy.forgejo.ci.enable") ciUnderForge.warnings
&& !(lib.any (a: !a.assertion) ciUnderForge.assertions);
}
{
# A removed option evaluates to an assertion naming the replacement.
name = "a CI option under deploy.forgejo names its replacement under deploy.ci-runner";
ok = refusedOver ciUnderForge "services.hyperhive.deploy.ci-runner.enable instead";
name = "a CI option under swarm.forge names its replacement under deploy.ci-runner";
ok = refusedOver ciUnderSwarmForge "services.hyperhive.deploy.ci-runner.enable instead";
}
{
# Nothing writes the delivery path away from the forge, and a