# 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. { lib, config, ... }: let swarmDomain = config.services.hyperhive.swarm.domain; # Total on a null swarm domain, as every sibling module is: the # required-domain assertion in hive-network.nix is what an operator should # see, not a coercion error from here. domainBase = if swarmDomain == null then "invalid" else swarmDomain; in { options.services.hyperhive.swarm.attic = { otel.clientId = lib.mkOption { type = lib.types.str; readOnly = true; default = "swarm-attic-collector"; description = '' OAuth2 client id the journal forwarder inside the cache's container authenticates as, and the audience it asks its token for. Read-only because three hosts have to agree on it: authelia registers the client (`glue-attic-otel-oidc-client.nix`), the swarm collector admits it on the container's receiver (`swarm.otel.serviceProducers`), and the secret publisher carries its secret to the store. ''; }; ownDomain = lib.mkOption { type = lib.types.str; readOnly = true; default = "attic.${domainBase}"; 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 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. ''; }; domain = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; example = "cache.example.org"; description = '' Name of the attic server, with no scheme: the swarm builder pushes to `https://`, and trusts the certificate the system roots do, so a Let's Encrypt certificate works and none is pinned. Set together with {option}`services.hyperhive.swarm.attic.cache`; evaluation fails when only one is set. 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.` 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 cache creates it; for an external cache the operator writes it. ''; }; 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; 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 push to it. The name follows attic's rule: 1 to 50 letters, digits, `-`, `_` or `+`, starting with a letter or digit. ''; }; }; }