HIVE_AGENT_NATS_URL now reaches each container in its hive facts, from the host's deploy.hive-controller.queue.agentNatsUrl, instead of being rendered into the meta flake. The agent option services.hyperhive.agent.queue.natsUrl is removed; the harness unit imports the queue credential whenever the token endpoint is set. On deploy every agent rebuilds once (the rendered flake loses the address), and the harness reads the address from the facts file hive-priv writes before each start. Refs #4857
75 lines
2.9 KiB
Nix
75 lines
2.9 KiB
Nix
# The hive this container runs on, read at boot rather than built in, so an
|
|
# agent's closure does not carry it.
|
|
#
|
|
# hive-priv writes `/etc/hyperhive-hive-facts` into the container before every
|
|
# start, one `KEY=value` line each:
|
|
#
|
|
# - `HYPERHIVE_HIVE_NAME`, `HYPERHIVE_HIVE_DOMAIN`;
|
|
# - `HIVE_DASHBOARD_PORT`, read by the harness's web UI (7000 when absent);
|
|
# - `HYPERHIVE_CLAUDE_CODE_PATH`, the claude-code the hive pins (`claude` in
|
|
# ./default.nix runs this container's own when absent);
|
|
# - `HYPERHIVE_OTEL_EXTRA_RESOURCE_ATTRIBUTES`, appended to
|
|
# `OTEL_RESOURCE_ATTRIBUTES` by ./otel.nix (no extra labels when absent).
|
|
# - `HIVE_AGENT_NATS_URL`, where the harness reaches the swarm queue (it fails
|
|
# at boot when absent).
|
|
#
|
|
# Any of them may be absent: a hive-c0re older than the agent's build writes
|
|
# fewer. Two readers hand the lines on:
|
|
#
|
|
# - an environment generator, for the container's systemd: it passes them to
|
|
# every unit it starts, `machinectl shell` sessions (`hivectl choom`)
|
|
# included, since those are transient units of the same manager. A unit's
|
|
# own `Environment=` still overrides them.
|
|
# - `/etc/set-environment`, for login shells that no unit starts:
|
|
# `nixos-container root-login` / `run` (nsenter + `su -l`, which resets the
|
|
# environment) and getty logins.
|
|
#
|
|
# Tested by `checks.script-test-agent-hive-facts`.
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
userName = config.services.hyperhive.agent.user.name;
|
|
|
|
# Shell builtins only: nothing is assumed on PATH this early. Only the known
|
|
# keys are passed on. `|| [ -n "$key" ]` keeps a last line that has
|
|
# no trailing newline.
|
|
generator = pkgs.writeShellScript "hyperhive-hive-facts" ''
|
|
hive=unknown
|
|
if [ -r /etc/hyperhive-hive-facts ]; then
|
|
while IFS='=' read -r key value || [ -n "$key" ]; do
|
|
case "$key" in
|
|
HYPERHIVE_HIVE_NAME) hive=$value ;;
|
|
HYPERHIVE_HIVE_DOMAIN | HIVE_DASHBOARD_PORT) ;;
|
|
HYPERHIVE_CLAUDE_CODE_PATH | HYPERHIVE_OTEL_EXTRA_RESOURCE_ATTRIBUTES) ;;
|
|
HIVE_AGENT_NATS_URL) ;;
|
|
*) continue ;;
|
|
esac
|
|
printf '%s=%s\n' "$key" "$value"
|
|
done < /etc/hyperhive-hive-facts
|
|
fi
|
|
# Names claude's remote-control sessions `<hive>-<agent>`.
|
|
printf 'CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX=%s-%s\n' "$hive" ${lib.escapeShellArg userName}
|
|
'';
|
|
|
|
# Sourced by every shell's `/etc/set-environment`, so POSIX sh only. Each
|
|
# line is exported as one word and never evaluated.
|
|
profile = pkgs.writeText "hyperhive-hive-facts.sh" ''
|
|
while IFS= read -r __hyperhive_fact; do
|
|
case "$__hyperhive_fact" in
|
|
?*=*) export "$__hyperhive_fact" ;;
|
|
esac
|
|
done <<__HYPERHIVE_FACTS__
|
|
$(${generator})
|
|
__HYPERHIVE_FACTS__
|
|
unset __hyperhive_fact
|
|
'';
|
|
in
|
|
{
|
|
environment.etc."systemd/system-environment-generators/50-hyperhive-hive-facts".source = generator;
|
|
environment.etc."hyperhive/hive-facts.sh".source = profile;
|
|
environment.extraInit = ". /etc/hyperhive/hive-facts.sh";
|
|
}
|