hyperhive/nix/agent-modules/logs.nix
atlas 3662eda440 nix: move the agent option namespace under services.hyperhive.agent
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
2026-09-17 20:19:30 +02:00

90 lines
3.8 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# `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 ];
};
}