diff --git a/docs/scheduler/ci.md b/docs/scheduler/ci.md index 689f73fd..93f63dfb 100644 --- a/docs/scheduler/ci.md +++ b/docs/scheduler/ci.md @@ -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 diff --git a/nix/host-modules/deploy.nix b/nix/host-modules/deploy.nix index 0f2795b9..cb8f8876 100644 --- a/nix/host-modules/deploy.nix +++ b/nix/host-modules/deploy.nix @@ -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 diff --git a/nix/module-eval/forge-placement.nix b/nix/module-eval/forge-placement.nix index fafe2a94..d639a65a 100644 --- a/nix/module-eval/forge-placement.nix +++ b/nix/module-eval/forge-placement.nix @@ -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