Every per-agent harness option lived at the top-level `hyperhive.*` while the host tier has always been `services.hyperhive.*`. Move all 52 agent-tier option leaves (33 top-level names across 16 modules) to `services.hyperhive.agent.*`, repoint every read, and keep existing agent configs evaluating through one `mkRenamedOptionModule` per old leaf path in the new nix/agent-modules/renamed-options.nix. The shims are per leaf rather than per namespace: `user`, `mcp`, `otel`, `queue`, `docs`, `forge`, `frontend`, `github`, `gui`, `logs`, `matrix` and `cargo` are plain attrsets of declarations, not submodule-typed options, so a parent-path rename would not reach their children. Three read-only options (`frontend.mergedDist`, `queue.clientIdFile`, `queue.clientSecretFile`) deliberately get no shim — a rename contributes a definition, which a read-only option refuses; the exclusions are commented in place. Refs #4473
90 lines
3.8 KiB
Nix
90 lines
3.8 KiB
Nix
# `swarm-logs` on this agent's PATH, configured for this swarm's log store.
|
||
#
|
||
# The binary reads its coordinates from the environment and defaults nothing
|
||
# (see `swarm-logs/README.md`), so it is installed **wrapped** rather than
|
||
# bare — the same shape `swarm-controller.nix` installs `swarmctl` in, and for
|
||
# the same reason: every value here is derived from an option a module owns,
|
||
# and a default inside the binary would be an address we hope points at
|
||
# something.
|
||
#
|
||
# ⚠️ Gated on the queue being configured as well as on the query URL, because
|
||
# the identity this CLI presents IS the queue's: one per-hive machine client,
|
||
# one credential pair, delivered once. A swarm with a log store and no agent
|
||
# credential has nothing for this to authenticate as, and installing a binary
|
||
# that can only fail would be worse than leaving it off PATH — an agent would
|
||
# read the 401 as "no logs", which is the exact confusion the store's machine
|
||
# route was added to end.
|
||
{
|
||
lib,
|
||
pkgs,
|
||
config,
|
||
...
|
||
}:
|
||
let
|
||
cfg = config.services.hyperhive.agent.logs;
|
||
queueCfg = config.services.hyperhive.agent.queue;
|
||
configured = cfg.queryUrl != null && queueCfg.tokenEndpoint != null;
|
||
|
||
# The four coordinates `swarm-logs` reads, all-or-none on its side. Bound
|
||
# here as one attrset so the wrapper below cannot set three of them: a
|
||
# half-set environment is the failure the binary reports as a deployment
|
||
# bug, and it should not be reachable from the module that sets it.
|
||
#
|
||
# 🩸 Two of these are credential **paths**. Neither the id nor the secret
|
||
# is read here — a value in `--set` lands in the wrapper script, which is
|
||
# in the world-readable nix store.
|
||
wrapperEnv = {
|
||
HIVE_AGENT_LOGS_QUERY_URL = cfg.queryUrl;
|
||
HIVE_AGENT_OIDC_TOKEN_ENDPOINT = queueCfg.tokenEndpoint;
|
||
HIVE_AGENT_OIDC_CLIENT_ID_FILE = queueCfg.clientIdFile;
|
||
HIVE_AGENT_OIDC_CLIENT_SECRET_FILE = queueCfg.clientSecretFile;
|
||
};
|
||
|
||
# Same shape `swarm-controller.nix` wraps `swarmctl` in — `symlinkJoin` +
|
||
# `wrapProgram`, not a `writeShellScriptBin` shim, because the wrapper has
|
||
# to leave the binary's `--help`, its exit status and its streams intact.
|
||
# The whole point of the CLI is that its stdout pipes into `grep`.
|
||
swarmLogsConfigured = pkgs.symlinkJoin {
|
||
name = "swarm-logs-configured";
|
||
paths = [ config.services.hyperhive.agent.packages.swarm-logs ];
|
||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||
postBuild = ''
|
||
wrapProgram $out/bin/swarm-logs ${
|
||
lib.concatStringsSep " " (
|
||
lib.mapAttrsToList (name: value: "--set ${name} ${lib.escapeShellArg value}") wrapperEnv
|
||
)
|
||
}
|
||
'';
|
||
};
|
||
in
|
||
{
|
||
options.services.hyperhive.agent.logs = {
|
||
queryUrl = lib.mkOption {
|
||
type = lib.types.nullOr lib.types.str;
|
||
default = null;
|
||
example = "https://logs.example.com/select/logsql/query";
|
||
description = ''
|
||
The swarm log store's LogsQL query endpoint, as this container
|
||
reaches it — the machine route `swarm-victorialogs.nix` puts on the
|
||
gateway, not the browser one at `/`.
|
||
|
||
Set by the generated meta flake from the host's own
|
||
{option}`services.hyperhive.swarm.victorialogs.domain`.
|
||
|
||
⚠️ The **whole URL**, not a host to build one from, because this same
|
||
string is also the audience `swarm-logs` mints its token for. Two
|
||
spellings of one address present as a valid token refused at the
|
||
store — the rule `swarm-otel.nix` already states over its own push
|
||
targets.
|
||
|
||
`null` means this hive has not been given the log store's address for
|
||
its agents, and `swarm-logs` is then not installed at all. Deliberately
|
||
not defaulted: a guessed address resolves cleanly to the wrong place.
|
||
'';
|
||
};
|
||
};
|
||
|
||
config = lib.mkIf configured {
|
||
environment.systemPackages = [ swarmLogsConfigured ];
|
||
};
|
||
}
|