diff --git a/nix/host-modules/hive-ci.nix b/nix/host-modules/hive-ci.nix index 408e490a..f215e49e 100644 --- a/nix/host-modules/hive-ci.nix +++ b/nix/host-modules/hive-ci.nix @@ -24,6 +24,30 @@ let useSelfSigned = caTrust.useSelfSigned; caContainerPath = caTrust.caContainerPath; + # The runner daemon needs the hive CA too, and `NODE_EXTRA_CA_CERTS` above + # does not give it to them: that variable is Node's, and it is ADDITIVE. + # `gitea-runner` is Go, whose trust store is REPLACING -- it reads + # `SSL_CERT_FILE` and then trusts only what that file contains. So the two + # consumers need different treatment from the same CA, which is exactly the + # split the helper documents at its head. + # + # Without this the daemon fails every startup call with + # `x509: certificate signed by unknown authority` the moment it reaches a + # TLS endpoint -- and it reaches one whenever the address it is registered + # at redirects to the gateway's https vhost. The unit then crash-loops on + # `Restart=on-failure`, no job is ever picked up, and nothing reports it as + # broken: every pull request simply sits at "Waiting to run". + # + # ⚠️ This is deliberately NOT claimed as the whole story of that outage -- + # what address the daemon holds is a separate question. It is here because + # the trust gap is real under every explanation of it, and adding a CA to + # one unit cannot break a path that already works. + caBundleModule = caTrust.trustBundle { + inherit pkgs; + name = "hive-ci"; + consumers = [ "gitea-runner-hive" ]; + }; + in { # Forgejo Actions runner in a `hive-ci` nixos-container. @@ -224,6 +248,11 @@ in config = { pkgs, lib, ... }: { + # Assembles system CAs + the hive CA into one bundle and sets + # `SSL_CERT_FILE` on the runner unit. See `caBundleModule` above for + # why the Node variable beside it is not enough. + imports = [ caBundleModule ]; + system.stateVersion = "26.05"; # Point the forge domain at the bridge IP so the runner can