Watch
0
0
Fork
You've already forked hyperhive
0

read the running rev and the hyperhive flake from /etc files, not the unit

This commit is contained in:
atlas 2026-11-06 04:44:27 +01:00 • committed by mara
commit aed7c8451a
2 changed files with 416 additions and 85 deletions

View file

@ -127,7 +127,7 @@ let
builderCheck =
agentModule:
let
src = env.SWARM_BUILDER_HYPERHIVE_FLAKE;
src = withBuilder.services.hyperhive.deploy.hyperhiveFlake;
hyperhive = (import "${src}/flake.nix").outputs (
self.inputs
// {
@ -262,10 +262,15 @@ let
}
{
# The check builds on the sources this host was deployed with, so a green check means
# the same hyperhive and nixpkgs base.
# the same hyperhive and nixpkgs base. The hyperhive source is a file the
# daemon re-reads, not part of its unit.
name = "the builder builds on the hyperhive and nixpkgs this host was deployed with";
ok =
env.SWARM_BUILDER_HYPERHIVE_FLAKE == withBuilder.services.hyperhive.deploy.hyperhiveFlake
(builtins.fromJSON (
builtins.unsafeDiscardStringContext inner.environment.etc."hyperhive/swarm-builder.json".text
)).hyperhive_flake
== builtins.unsafeDiscardStringContext withBuilder.services.hyperhive.deploy.hyperhiveFlake
&& !(env ? SWARM_BUILDER_HYPERHIVE_FLAKE)
&& env.SWARM_BUILDER_NIXPKGS_FLAKE == withBuilder.services.hyperhive.deploy.builder.nixpkgsFlake
&& lib.hasSuffix "-check-flake" env.SWARM_BUILDER_CHECK_FLAKE
&& env.SWARM_BUILDER_SYSTEM == pkgs.stdenv.hostPlatform.system

View file

@ -33,6 +33,14 @@ let
inherit (shared) allLocal;
# `allLocal` on another hyperhive commit and source, which differ from its
# own in nothing else.
allLocalMoved = hiveWithController {
deploy.singleHostSwarm = true;
deploy.hyperhiveFlake = "/nix/store/00000000000000000000000000000000-hyperhive-moved";
deploy.hive-controller.hyperhiveRev = lib.fixedWidthString 40 "b" "";
};
bare = shared.bareWithController;
# `lib.hasInfix` matches by regex, which refuses a needle that refers to a
@ -308,18 +316,68 @@ let
&& !((env "hive-priv") ? HIVE_PRIV_FORGE_URL);
}
{
# `hyperhive_rev` defaults to none on the controller, so a settings JSON
# `hyperhive_rev` defaults to none on the controller, so a rev file
# without the key is accepted and the pin would never move: the key has
# to be there, carrying the option it is wired from.
name = "the controller hands its running rev to the meta flake settings";
# to be there, carrying the option it is wired from. The settings JSON
# must not carry it: the daemon refuses a key it does not know, and a
# rev in the unit restarts the controller on every commit.
name = "the controller hands its running rev to the meta flake through its rev file";
ok =
let
revFile = builtins.fromJSON (
builtins.unsafeDiscardStringContext allLocal.environment.etc."hyperhive/swarm-controller.json".text
);
settings = builtins.fromJSON allLocal.systemd.services.swarm-controller.environment.SWARM_CONTROLLER_META_FLAKE;
in
settings ? hyperhive_rev
&& settings.hyperhive_rev == allLocal.services.hyperhive.deploy.hive-controller.hyperhiveRev
revFile ? hyperhive_rev
&& revFile.hyperhive_rev == allLocal.services.hyperhive.deploy.hive-controller.hyperhiveRev
&& !(settings ? hyperhive_rev)
&& settings ? git_base;
}
{
# A deploy that changes only the commit and the hyperhive source must
# leave both long-running units as they are, or systemd restarts them:
# the controller drops its job graph and the builder its build. The
# moved host differs in exactly those two options, and its files carry
# them, which is the control that the comparison reads what changed.
name = "a new hyperhive commit and source leave the controller's and the builder's units unchanged";
ok =
let
unit = m: m.systemd.services.swarm-controller;
builderUnit = m: m.containers.swarm-builder.config.systemd.services.swarm-builder;
same =
f:
let
a = f allLocal;
b = f allLocalMoved;
in
a.environment == b.environment
&& a.serviceConfig == b.serviceConfig
&& map toString a.path == map toString b.path;
etcText = m: name: builtins.unsafeDiscardStringContext m.environment.etc.${name}.text;
builderEtc = m: m.containers.swarm-builder.config;
movedRev = allLocalMoved.services.hyperhive.deploy.hive-controller.hyperhiveRev;
movedFlake = allLocalMoved.services.hyperhive.deploy.hyperhiveFlake;
in
same unit
&& same builderUnit
&& movedRev != allLocal.services.hyperhive.deploy.hive-controller.hyperhiveRev
&& movedFlake != allLocal.services.hyperhive.deploy.hyperhiveFlake
&&
(builtins.fromJSON (etcText allLocalMoved "hyperhive/swarm-controller.json")).hyperhive_rev
== movedRev
&&
etcText allLocal "hyperhive/swarm-controller.json"
!= etcText allLocalMoved "hyperhive/swarm-controller.json"
&&
(builtins.fromJSON (etcText (builderEtc allLocalMoved) "hyperhive/swarm-builder.json"))
.hyperhive_flake == builtins.unsafeDiscardStringContext movedFlake
&&
etcText (builderEtc allLocal) "hyperhive/swarm-builder.json"
!= etcText (builderEtc allLocalMoved) "hyperhive/swarm-builder.json"
&& !((builderUnit allLocal).environment ? SWARM_BUILDER_HYPERHIVE_FLAKE)
&& (builderUnit allLocal).environment ? SWARM_BUILDER_NIXPKGS_FLAKE;
}
{
# An agent connects to the queue with its own secret, so the hive hands
# its agents no shared credential and no token endpoint to mint one at.