swarm builder: the all-swarm-services switch turns it on, like every other swarm service
deploy.builder.enable defaults on under deploy.allSwarmServices (mkDefault), where the host has the builder's store identity pair, as for the review classifier. An explicit false still wins.
This commit is contained in:
parent
5b49e0e539
commit
d24dbaeadf
7 changed files with 68 additions and 26 deletions
|
|
@ -268,9 +268,11 @@ the container and the threat model are in
|
||||||
### Builder
|
### Builder
|
||||||
|
|
||||||
The swarm builder, in a `swarm-builder` container on the host that sets
|
The swarm builder, in a `swarm-builder` container on the host that sets
|
||||||
`deploy.builder.enable`. It doesn't derive from `allSwarmServices`: it
|
`deploy.builder.enable`. `allSwarmServices` defaults it on wherever the host
|
||||||
evaluates and builds unreviewed config PRs through its host's nix daemon, so
|
has the builder's store identity, as for the review classifier below: the host
|
||||||
running one is a decision of its own, as for the CI runner.
|
that runs the store has it. Set `deploy.builder.enable = false` to opt out. It
|
||||||
|
evaluates unreviewed config PRs and builds them through its host's nix daemon,
|
||||||
|
from a container with its own network namespace.
|
||||||
|
|
||||||
When an `agent-configs/<agent>` PR opens, reopens or gets a new push,
|
When an `agent-configs/<agent>` PR opens, reopens or gets a new push,
|
||||||
swarm-controller queues a `build_agent` job. Jobs run one at a time, and a
|
swarm-controller queues a `build_agent` job. Jobs run one at a time, and a
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,8 @@ checkpoints**, not about sandboxing the agent from its own tools:
|
||||||
scheduled prompts are operator-only, set at swarm level
|
scheduled prompts are operator-only, set at swarm level
|
||||||
(see [`schedules.md`](../swarm/schedules.md)).
|
(see [`schedules.md`](../swarm/schedules.md)).
|
||||||
Before that merge, the swarm builder evaluates an unmerged config PR
|
Before that merge, the swarm builder evaluates an unmerged config PR
|
||||||
off-hive, on any host that sets `deploy.builder.enable`: it builds the
|
off-hive, on any host that sets `deploy.builder.enable` (the
|
||||||
|
all-swarm-services switch defaults it on): it builds the
|
||||||
PR's head with a read-only forge token, in its own netns, as an untrusted
|
PR's head with a read-only forge token, in its own netns, as an untrusted
|
||||||
client of its host's nix daemon (see [`builder.md`](../swarm/builder.md)).
|
client of its host's nix daemon (see [`builder.md`](../swarm/builder.md)).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -694,13 +694,13 @@ in
|
||||||
this host's nix daemon, and swarm-controller writes the result as a
|
this host's nix daemon, and swarm-controller writes the result as a
|
||||||
`swarm-builder` commit status on the PR.
|
`swarm-builder` commit status on the PR.
|
||||||
|
|
||||||
Not derived from
|
On by default where
|
||||||
{option}`services.hyperhive.deploy.allSwarmServices`: the builder
|
{option}`services.hyperhive.deploy.allSwarmServices` is set and this
|
||||||
evaluates and builds unreviewed config PRs on this host's nix daemon,
|
host has the builder's store identity (the pair
|
||||||
so running one is a decision of its own, as for the CI runner. It needs
|
{option}`services.hyperhive.deploy.bao.builderClientCertFile` and
|
||||||
the builder's store identity
|
`builderClientKeyFile`, minted on the store's host). It evaluates
|
||||||
({option}`services.hyperhive.deploy.bao.builderClientCertFile` and
|
unreviewed config PRs and builds them through this host's nix daemon,
|
||||||
`builderClientKeyFile`), which the store's host mints.
|
from a container with its own network namespace.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
# The swarm builder, in a `swarm-builder` container on the host that sets
|
# The swarm builder, in a `swarm-builder` container on the host that sets
|
||||||
# `deploy.builder.enable`, which nothing turns on for the operator: it runs
|
# `deploy.builder.enable`, which `deploy.allSwarmServices` defaults on where the
|
||||||
|
# host has the builder's store identity (./swarm-required-services.nix). It runs
|
||||||
# unreviewed config PRs through the host's nix daemon. It builds agent configs
|
# unreviewed config PRs through the host's nix daemon. It builds agent configs
|
||||||
# for swarm-controller: the controller sends a config PR's head over the
|
# for swarm-controller: the controller sends a config PR's head over the
|
||||||
# queue, and the daemon builds that config on this host's agent base and
|
# queue, and the daemon builds that config on this host's agent base and
|
||||||
|
|
|
||||||
|
|
@ -117,4 +117,13 @@ in
|
||||||
&& deployCfg.bao.reviewClassifierClientCertFile != null
|
&& deployCfg.bao.reviewClassifierClientCertFile != null
|
||||||
&& deployCfg.bao.reviewClassifierClientKeyFile != null
|
&& deployCfg.bao.reviewClassifierClientKeyFile != null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# The builder, by the same rule and for the same reason: its module asserts
|
||||||
|
# the builder's store identity. It evaluates unreviewed config PRs, which is
|
||||||
|
# why ./swarm-builder.nix gives it a container with its own netns.
|
||||||
|
config.services.hyperhive.deploy.builder.enable = lib.mkDefault (
|
||||||
|
deployCfg.allSwarmServices
|
||||||
|
&& deployCfg.bao.builderClientCertFile != null
|
||||||
|
&& deployCfg.bao.builderClientKeyFile != null
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
servicesHere = hiveWithController { deploy.allSwarmServices = true; };
|
servicesHere = hiveWithController { deploy.allSwarmServices = true; };
|
||||||
|
# Short-circuits on `assertion`, so only a failing one has its message read.
|
||||||
|
refusedWithoutIdentity =
|
||||||
|
m:
|
||||||
|
lib.any (a: !a.assertion && lib.hasInfix "deploy.builder.enable requires" a.message) m.assertions;
|
||||||
|
|
||||||
natsHere = hive {
|
natsHere = hive {
|
||||||
swarm.nats.enable = true;
|
swarm.nats.enable = true;
|
||||||
|
|
@ -54,13 +58,17 @@ let
|
||||||
ok = !(bare.containers ? swarm-builder) && withBuilder.containers ? swarm-builder;
|
ok = !(bare.containers ? swarm-builder) && withBuilder.containers ? swarm-builder;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
# It runs unreviewed config PRs through the host's nix daemon, so hosting
|
# The store's host mints the builder's leaf, so the switch needs no
|
||||||
# the shared services, even with the store's leaf here, does not turn it
|
# manual identity step: the pair is set and the module's identity
|
||||||
# on. `nats` is the control that the switch is on at all.
|
# assertion, which nothing else reads in this fixture, passes. `nats` is
|
||||||
name = "hosting the shared services leaves the builder off";
|
# the control that the switch is on.
|
||||||
|
name = "hosting the shared services turns the builder on, with its store identity";
|
||||||
ok =
|
ok =
|
||||||
!servicesHere.services.hyperhive.deploy.builder.enable
|
servicesHere.services.hyperhive.deploy.builder.enable
|
||||||
&& !(servicesHere.containers ? swarm-builder)
|
&& servicesHere.containers ? swarm-builder
|
||||||
|
&& servicesHere.services.hyperhive.deploy.bao.builderClientCertFile != null
|
||||||
|
&& servicesHere.services.hyperhive.deploy.bao.builderClientKeyFile != null
|
||||||
|
&& !(refusedWithoutIdentity servicesHere)
|
||||||
&& servicesHere.services.hyperhive.deploy.bao.enable
|
&& servicesHere.services.hyperhive.deploy.bao.enable
|
||||||
&& servicesHere.services.hyperhive.deploy.nats.enable;
|
&& servicesHere.services.hyperhive.deploy.nats.enable;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,10 +90,12 @@ let
|
||||||
# swarm-required-services.nix documents the switch for.
|
# swarm-required-services.nix documents the switch for.
|
||||||
swarmServicesHere = hiveWithController { deploy.allSwarmServices = true; };
|
swarmServicesHere = hiveWithController { deploy.allSwarmServices = true; };
|
||||||
|
|
||||||
# Same, with the operator opting out of the classifier alone.
|
# Same, with the operator opting out of the classifier and the builder,
|
||||||
swarmServicesWithoutClassifier = hiveWithController {
|
# which the switch defaults on and everything else it owns stays on.
|
||||||
|
swarmServicesOptedOut = hiveWithController {
|
||||||
deploy.allSwarmServices = true;
|
deploy.allSwarmServices = true;
|
||||||
deploy.review-classifier.enable = false;
|
deploy.review-classifier.enable = false;
|
||||||
|
deploy.builder.enable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Same, with one of those services placed on another host. Every derivation
|
# Same, with one of those services placed on another host. Every derivation
|
||||||
|
|
@ -161,8 +163,8 @@ let
|
||||||
lib.filter (l: swarmServiceLinkDomains ? ${l.label}) cfg.services.hyperhive.swarm.controller.links;
|
lib.filter (l: swarmServiceLinkDomains ? ${l.label}) cfg.services.hyperhive.swarm.controller.links;
|
||||||
|
|
||||||
# Every service container at once: the services-only host plus the CI
|
# Every service container at once: the services-only host plus the CI
|
||||||
# runner. The CI runner, the review classifier and the metrics store are the
|
# runner. The CI runner, the review classifier, the builder and the metrics
|
||||||
# three containers on a netns of their own.
|
# store are the four containers on a netns of their own.
|
||||||
serviceContainersWithCi = hive {
|
serviceContainersWithCi = hive {
|
||||||
deploy.hive-controller.enable = false;
|
deploy.hive-controller.enable = false;
|
||||||
deploy.allSwarmServices = true;
|
deploy.allSwarmServices = true;
|
||||||
|
|
@ -212,9 +214,19 @@ let
|
||||||
# without the line is the control.
|
# without the line is the control.
|
||||||
name = "an explicit false keeps the review classifier off where the shared services are hosted";
|
name = "an explicit false keeps the review classifier off where the shared services are hosted";
|
||||||
ok =
|
ok =
|
||||||
!swarmServicesWithoutClassifier.services.hyperhive.deploy.review-classifier.enable
|
!swarmServicesOptedOut.services.hyperhive.deploy.review-classifier.enable
|
||||||
&& !(swarmServicesWithoutClassifier.containers ? swarm-review-classifier)
|
&& !(swarmServicesOptedOut.containers ? swarm-review-classifier)
|
||||||
&& swarmServicesWithoutClassifier.services.hyperhive.deploy.nats.enable;
|
&& swarmServicesOptedOut.services.hyperhive.deploy.nats.enable;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Same as the classifier's case above, for the builder: the opt-out is
|
||||||
|
# the only difference from `swarmServicesHere`, which has the container.
|
||||||
|
name = "an explicit false keeps the swarm builder off where the shared services are hosted";
|
||||||
|
ok =
|
||||||
|
!swarmServicesOptedOut.services.hyperhive.deploy.builder.enable
|
||||||
|
&& !(swarmServicesOptedOut.containers ? swarm-builder)
|
||||||
|
&& swarmServicesHere.containers ? swarm-builder
|
||||||
|
&& swarmServicesOptedOut.services.hyperhive.deploy.nats.enable;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
# The classifier's module asserts a store identity that only the store's
|
# The classifier's module asserts a store identity that only the store's
|
||||||
|
|
@ -226,6 +238,15 @@ let
|
||||||
&& !(swarmServicesBaoElsewhere.containers ? swarm-review-classifier)
|
&& !(swarmServicesBaoElsewhere.containers ? swarm-review-classifier)
|
||||||
&& swarmServicesBaoElsewhere.services.hyperhive.deploy.nats.enable;
|
&& swarmServicesBaoElsewhere.services.hyperhive.deploy.nats.enable;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
# The builder's module asserts its own store identity, so the same
|
||||||
|
# holds for it. `nats` is the control.
|
||||||
|
name = "the swarm builder stays off where the shared services are hosted without the store";
|
||||||
|
ok =
|
||||||
|
!swarmServicesBaoElsewhere.services.hyperhive.deploy.builder.enable
|
||||||
|
&& !(swarmServicesBaoElsewhere.containers ? swarm-builder)
|
||||||
|
&& swarmServicesBaoElsewhere.services.hyperhive.deploy.nats.enable;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
# The switch fills in for an operator who has not spoken and yields to
|
# The switch fills in for an operator who has not spoken and yields to
|
||||||
# one who has — that is what keeps a shared service placeable on a host
|
# one who has — that is what keeps a shared service placeable on a host
|
||||||
|
|
@ -489,7 +510,7 @@ let
|
||||||
# that lost a container can't pass by comparing fewer of them.
|
# that lost a container can't pass by comparing fewer of them.
|
||||||
name = "every service container restates its host-side privateNetwork";
|
name = "every service container restates its host-side privateNetwork";
|
||||||
ok =
|
ok =
|
||||||
lib.length (lib.attrNames serviceContainers) == 11
|
lib.length (lib.attrNames serviceContainers) == 12
|
||||||
&& lib.all (
|
&& lib.all (
|
||||||
c: c.privateNetwork == (c.config.services.hyperhive.swarmContainer.privateNetwork or null)
|
c: c.privateNetwork == (c.config.services.hyperhive.swarmContainer.privateNetwork or null)
|
||||||
) (lib.attrValues serviceContainers);
|
) (lib.attrValues serviceContainers);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue