Watch
0
0
Fork
You've already forked hyperhive
0

default swarm.attic domain and cache to the swarm's own cache on every host

This commit is contained in:
atlas 2026-10-27 19:00:59 +01:00 • committed by mara
commit 606817a994
6 changed files with 80 additions and 57 deletions

View file

@ -521,9 +521,10 @@ in
{option}`services.hyperhive.deploy.bao.atticClientCertFile` and
`atticClientKeyFile`, minted on the store's host).
With it on, {option}`services.hyperhive.swarm.attic.domain` and `cache`
default to the cache's own name and cache; naming either yourself wins.
With it off, those two options name an external cache or stay unset.
{option}`services.hyperhive.swarm.attic.domain` and `cache` default to
this cache on every host. For an external cache, override both and
leave this unset, or set it to `lib.mkForce false` under
`allSwarmServices`.
'';
};

View file

@ -1,7 +1,7 @@
# The binary cache the swarm pushes agent closures to, as every host sees it:
# which attic server, and which cache on it. A host that sets
# `deploy.attic.enable` runs the swarm's own and fills both in (./swarm-attic.nix);
# otherwise the instance is the operator's, outside the swarm.
# which attic server, and which cache on it. Both default to the swarm's own,
# which the host that sets `deploy.attic.enable` runs (./swarm-attic.nix); an
# operator with an instance outside the swarm overrides both.
{ lib, config, ... }:
let
swarmDomain = config.services.hyperhive.swarm.domain;
@ -35,8 +35,7 @@ in
defaultText = lib.literalExpression ''"attic.''${services.hyperhive.swarm.domain}"'';
description = ''
Read-only: the name the swarm's own cache is served under, which
{option}`services.hyperhive.deploy.attic.enable` defaults
{option}`services.hyperhive.swarm.attic.domain` to. A sibling of the
{option}`services.hyperhive.swarm.attic.domain` defaults to. A sibling of the
swarm's other service names, so the swarm-services sub-CA can issue for it,
and in `swarm.serviceDomains` on every host whether or not one runs it.
'';
@ -44,7 +43,8 @@ in
domain = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
default = config.services.hyperhive.swarm.attic.ownDomain;
defaultText = lib.literalExpression "services.hyperhive.swarm.attic.ownDomain";
example = "cache.example.org";
description = ''
Name of the attic server, with no scheme: the swarm builder pushes to
@ -53,13 +53,15 @@ in
{option}`services.hyperhive.swarm.attic.cache`; evaluation fails when only
one is set.
Defaults to the swarm's own cache, the same on every host. For a cache
outside the swarm, override both options and leave
{option}`services.hyperhive.deploy.attic.enable` unset. With no cache
behind the default, a push fails and the closure record says it is not
cached.
Null pushes nothing: the swarm builder does not push, and the closure
record says it is not cached.
{option}`services.hyperhive.deploy.attic.enable` defaults this to
`attic.<swarm.domain>` on the host that runs the swarm's own cache. Every
other host reads it from the same option, so name it there too.
The push token is not an option. It is at
`secret/swarm/services/attic/push-token` in the swarm secret store
(field `value`), and the builder reads it on every push. The swarm's own
@ -70,12 +72,12 @@ in
cache = lib.mkOption {
# attic's own rule for a cache name; the builder checks the same at start.
type = lib.types.nullOr (lib.types.strMatching "^[A-Za-z0-9][A-Za-z0-9_+-]{0,49}$");
default = null;
default = "swarm";
example = "grid";
description = ''
Name of the cache on {option}`services.hyperhive.swarm.attic.domain`
that the swarm builder pushes closures to, `swarm` by default on the
host that runs the swarm's own cache. The push token must be allowed to
that the swarm builder pushes closures to, the swarm's own cache by
default. The push token must be allowed to
push to it. The name follows attic's rule: 1 to 50 letters,
digits, `-`, `_` or `+`, starting with a letter or digit.
'';

View file

@ -14,9 +14,8 @@
# and attic's own tokens are the authentication. Storage is local disk under the
# container's state.
#
# The two `swarm.attic` options every host reads (./swarm-attic-options.nix) get
# their values from here, at `mkDefault`: naming them yourself wins, and with
# the switch off nothing is set.
# The two `swarm.attic` options every host reads (./swarm-attic-options.nix)
# default to this cache's names on every host, whether or not it runs here.
{
pkgs,
lib,
@ -168,11 +167,6 @@ in
};
config = lib.mkIf cfg.enable {
services.hyperhive.swarm.attic = {
domain = lib.mkDefault atticCfg.ownDomain;
cache = lib.mkDefault "swarm";
};
assertions = [
{
assertion = haveClientIdentity;

View file

@ -132,7 +132,7 @@ in
# The binary cache, on the same terms: its units log in to the store as the
# cache's own principal. An operator running an external cache sets this to
# `false` and names `swarm.attic.{domain,cache}` itself.
# `lib.mkForce false` and overrides `swarm.attic.{domain,cache}`.
config.services.hyperhive.deploy.attic.enable = lib.mkDefault (
deployCfg.allSwarmServices
&& deployCfg.bao.atticClientCertFile != null

View file

@ -45,6 +45,7 @@ let
deploy.bao.enable = true;
deploy.builder.enable = true;
swarm.attic.domain = "cache.example.org";
swarm.attic.cache = null;
};
refusedHalfCache =
m:
@ -67,13 +68,23 @@ let
svc = inner.systemd.services.swarm-builder;
env = svc.environment;
hasOnPath = name: s: lib.any (p: lib.getName p == name) s.path;
# A builder with no cache named anywhere.
# A builder that opts out of pushing: both options null.
withBuilderNoCache = hive {
deploy.bao.enable = true;
deploy.builder.enable = true;
swarm.attic.domain = null;
swarm.attic.cache = null;
};
withoutCache = withBuilderNoCache.containers.swarm-builder.config.systemd.services.swarm-builder;
# A builder on a host that doesn't run the cache and names nothing.
builderDefaults = hive {
deploy.bao.enable = true;
deploy.builder.enable = true;
};
defaultsEnv =
builderDefaults.containers.swarm-builder.config.systemd.services.swarm-builder.environment;
# Hosting the shared services runs the swarm's own cache, which names itself.
atticHere = servicesHere;
atticDeploy = atticHere.services.hyperhive.deploy.attic;
@ -83,7 +94,7 @@ let
atticTokens = atticHere.systemd.services.swarm-bao-attic-tokens;
atticVhost = atticHere.services.hyperhive.gateway.vhosts."attic.t.local";
# The cache switched on while the operator names the options by hand.
# The cache switched on while the operator overrides the options.
atticByHand = hive {
deploy.bao.enable = true;
deploy.attic.enable = true;
@ -310,10 +321,10 @@ let
}
{
# The switch is on wherever the shared services are and the host holds the
# cache's leaf, and the two options every host reads come from the cache.
# The builder on the same host pushes to it. `bare` is the control that the
# lookup reads null where nothing runs a cache.
name = "hosting the shared services runs the swarm's cache and fills the cache options, which the builder follows";
# cache's leaf.
# The builder on the same host pushes to it. `bare` is the control that no
# cache renders where nothing enables it.
name = "hosting the shared services runs the swarm's cache, and the builder pushes to it";
ok =
atticDeploy.enable
&& atticHere.containers ? swarm-attic
@ -327,10 +338,23 @@ let
&&
atticHere.containers.swarm-builder.config.systemd.services.swarm-builder.environment.SWARM_BUILDER_ATTIC_CACHE
== "swarm"
&& (atticSwarm bare).domain == null
&& (atticSwarm bare).cache == null
&& !(hasAtticHost bare);
}
{
# The options default to the swarm's own cache on every host, so a
# builder host that runs no cache pushes to it. `atticHere` is the control
# that the cache host reads the same values.
name = "a builder host that doesn't run the cache pushes to the swarm's own by default";
ok =
!(hasAtticHost builderDefaults)
&& (atticSwarm builderDefaults).domain == "attic.t.local"
&& (atticSwarm builderDefaults).cache == "swarm"
&& (atticSwarm bare).domain == (atticSwarm atticHere).domain
&& (atticSwarm bare).cache == (atticSwarm atticHere).cache
&& defaultsEnv.SWARM_BUILDER_ATTIC_DOMAIN == "attic.t.local"
&& defaultsEnv.SWARM_BUILDER_ATTIC_CACHE == "swarm"
&& !(builderDefaults.systemd.services ? swarm-bao-attic-tokens);
}
{
# Names the operator gives win over the cache's own, and the gateway then
# serves the cache under the operator's name. `atticHere` is the control

View file

@ -304,12 +304,12 @@ let
}
{
# The cache's units assert the store identity the store's host mints, as
# the router's do; its options stay as unset as they were.
# the router's do; its options keep the same defaults.
name = "the swarm's cache stays off where the shared services are hosted without the store";
ok =
!swarmServicesBaoElsewhere.services.hyperhive.deploy.attic.enable
&& !(swarmServicesBaoElsewhere.containers ? swarm-attic)
&& swarmServicesBaoElsewhere.services.hyperhive.swarm.attic.domain == null
&& swarmServicesBaoElsewhere.services.hyperhive.swarm.attic.domain == "attic.t.local"
&& swarmServicesHere.services.hyperhive.deploy.attic.enable
&& swarmServicesBaoElsewhere.services.hyperhive.deploy.nats.enable;
}