docs: the agent config meta-flake input is the local applied mirror, not forge git+http
config-changes.md § Meta flake, hive-c0re nix comments and the meta.rs/exec.rs doc comments still described the declared agent-<n> input as a forge-hosted git+http repo; meta.rs renders git+file://<applied>.
This commit is contained in:
parent
66c1a564a4
commit
295e8af43a
5 changed files with 33 additions and 36 deletions
|
|
@ -114,27 +114,26 @@ transient.
|
||||||
|
|
||||||
The hive-c0re-owned repo at `/var/lib/hyperhive/meta/`
|
The hive-c0re-owned repo at `/var/lib/hyperhive/meta/`
|
||||||
declares one flake input per agent (`agent-<n>.url =
|
declares one flake input per agent (`agent-<n>.url =
|
||||||
"git+http://<forge>/agent-configs/<n>.git"`) and one
|
"git+file://<applied>"`, the agent's local `applied` mirror) and one
|
||||||
`nixosConfigurations.<n>` output per agent. Each output wraps
|
`nixosConfigurations.<n>` output per agent. Each output wraps
|
||||||
`inputs.agent-<n>.nixosModules.default` with the identity +
|
`inputs.agent-<n>.nixosModules.default` with the identity +
|
||||||
`HIVE_PORT` / `HIVE_LABEL` / `HIVE_DASHBOARD_PORT` injection module.
|
`HIVE_PORT` / `HIVE_LABEL` / `HIVE_DASHBOARD_PORT` injection module.
|
||||||
Containers run against `--flake /var/lib/hyperhive/meta#<n>`.
|
Containers run against `--flake /var/lib/hyperhive/meta#<n>`.
|
||||||
|
|
||||||
The declared input url is the agent's **forge config repo** (the
|
The declared input url is the agent's **local `applied` mirror**
|
||||||
same `agent-configs/<n>` config PRs merge into), so the meta flake
|
(`/var/lib/hyperhive/applied/<n>`) of its forge config repo
|
||||||
references a reviewable, reproducible source rather than a local
|
(`agent-configs/<n>`, the one config PRs merge into). The meta flake
|
||||||
checkout. hive-c0re authenticates that `git+http` fetch via a git
|
therefore resolves entirely from on-disk state: building, and booting,
|
||||||
credential helper that reads the live forge-core token — no token in
|
never depend on the forge being reachable. hive-c0re fills the mirror
|
||||||
the url or the lock. The rebuild paths, however, do **not** re-lock
|
by fast-forwarding `applied/<n>/main` to the merged config commit,
|
||||||
from the forge: they `--override-input agent-<n>
|
reading the forge with the hive's read token
|
||||||
git+file:///var/lib/hyperhive/applied/<n>`, locking the exact config
|
(`forge::reader_token()`); the forge repo is the review and audit
|
||||||
`applied/<n>/main` was fast-forwarded to. That keeps a rebuild
|
surface, not a flake input. The rebuild paths re-lock the input with
|
||||||
reproducible and independent of forge reachability — rebuilds fire on
|
`--override-input agent-<n> git+file:///var/lib/hyperhive/applied/<n>`,
|
||||||
crash-restart and meta bumps, not just config merges — while the
|
locking the exact config `applied/<n>/main` was fast-forwarded to.
|
||||||
declared url stays the forge. `sync_agents` re-renders + re-locks the
|
Rebuilds fire on crash-restart and meta bumps, not just config
|
||||||
persistent input; a plain `nix flake lock` leaves an existing applied
|
merges, so the lock stays on that head. `sync_agents` re-renders and
|
||||||
override in place (it only re-locks when the declared url itself
|
re-locks the persistent input.
|
||||||
changes), so the forge-declared / applied-deployed split is stable.
|
|
||||||
|
|
||||||
Lock updates are single-phase and commit when the lock changed:
|
Lock updates are single-phase and commit when the lock changed:
|
||||||
`meta::lock_update_for_rebuild(name)` relocks one agent's input for a
|
`meta::lock_update_for_rebuild(name)` relocks one agent's input for a
|
||||||
|
|
|
||||||
|
|
@ -884,7 +884,7 @@ fn parse_agent_input_names(inputs: &[String]) -> Vec<String> {
|
||||||
/// validating parser every other agent-name wire field in this codebase
|
/// validating parser every other agent-name wire field in this codebase
|
||||||
/// goes through, so a name that reaches
|
/// goes through, so a name that reaches
|
||||||
/// [`fast_forward_applied_main`](crate::forge::fast_forward_applied_main) or
|
/// [`fast_forward_applied_main`](crate::forge::fast_forward_applied_main) or
|
||||||
/// a `git+http://.../agent-configs/<name>.git` URL built off it has already
|
/// an `agent-configs/<name>` forge URL built off it has already
|
||||||
/// passed the same bar as one that arrived over a socket. Not just a
|
/// passed the same bar as one that arrived over a socket. Not just a
|
||||||
/// helper for [`parse_agent_input_names`]: `run_meta_lock`'s `fanout`
|
/// helper for [`parse_agent_input_names`]: `run_meta_lock`'s `fanout`
|
||||||
/// parameter carries pre-computed agent names too, and while today's only
|
/// parameter carries pre-computed agent names too, and while today's only
|
||||||
|
|
|
||||||
|
|
@ -235,9 +235,8 @@ pub async fn lock_update_for_rebuild(name: &str) -> Result<()> {
|
||||||
let _guard = META_LOCK.lock().await;
|
let _guard = META_LOCK.lock().await;
|
||||||
let dir = crate::paths::meta_root();
|
let dir = crate::paths::meta_root();
|
||||||
let input = format!("agent-{name}");
|
let input = format!("agent-{name}");
|
||||||
// Re-lock from the local applied mirror, not the persistent forge URL:
|
// Re-lock against `applied/<n>/main` explicitly, so the lock is the
|
||||||
// build exactly `applied/<n>/main` and stay reproducible when the forge
|
// exact applied head whatever the declared input url says.
|
||||||
// is unreachable.
|
|
||||||
let applied = applied_override_url(&crate::paths::applied_dir(name));
|
let applied = applied_override_url(&crate::paths::applied_dir(name));
|
||||||
nix(
|
nix(
|
||||||
&dir,
|
&dir,
|
||||||
|
|
@ -264,12 +263,12 @@ pub async fn lock_update_for_rebuild(name: &str) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `--override-input` URL re-locking an agent's config input against its
|
/// `--override-input` URL re-locking an agent's config input against its
|
||||||
/// LOCAL applied mirror (`git+file://<applied_dir>`, current `main` head)
|
/// LOCAL applied mirror (`git+file://<applied_dir>`, current `main` head),
|
||||||
/// instead of the persistent forge URL declared in the meta flake. The
|
/// the same url the meta flake declares. The deploy + rebuild paths re-lock
|
||||||
/// deploy + rebuild paths re-lock from here: the applied tree was already
|
/// from here: the applied tree was already fast-forwarded to the reviewed
|
||||||
/// fast-forwarded to the reviewed head, so this builds exactly that config
|
/// head, so this builds exactly that config with no forge access. No
|
||||||
/// and stays reproducible when the forge is unreachable. No `?rev` — `main`
|
/// `?rev` — `main` head is the reviewed head at deploy time. Pure so it's
|
||||||
/// head is the reviewed head at deploy time. Pure so it's unit-testable.
|
/// unit-testable.
|
||||||
fn applied_override_url(applied_dir: &Path) -> String {
|
fn applied_override_url(applied_dir: &Path) -> String {
|
||||||
format!("git+file://{}", applied_dir.display())
|
format!("git+file://{}", applied_dir.display())
|
||||||
}
|
}
|
||||||
|
|
@ -1456,8 +1455,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn applied_override_url_targets_local_mirror_main_head() {
|
fn applied_override_url_targets_local_mirror_main_head() {
|
||||||
// Deploy + rebuild re-lock against the local applied mirror's `main`
|
// Deploy + rebuild re-lock against the local applied mirror's `main`
|
||||||
// head (no `?rev`), never the persistent forge URL — so a rebuild
|
// head (no `?rev`) — so a rebuild survives forge unreachability and
|
||||||
// survives forge unreachability and builds the fast-forwarded config.
|
// builds the fast-forwarded config.
|
||||||
let p = Path::new("/var/lib/hyperhive/agents/iris/applied");
|
let p = Path::new("/var/lib/hyperhive/agents/iris/applied");
|
||||||
let url = applied_override_url(p);
|
let url = applied_override_url(p);
|
||||||
assert_eq!(url, "git+file:///var/lib/hyperhive/agents/iris/applied");
|
assert_eq!(url, "git+file:///var/lib/hyperhive/agents/iris/applied");
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,9 @@ let
|
||||||
username = core
|
username = core
|
||||||
[http]
|
[http]
|
||||||
# Abort a stalled fetch instead of blocking startup indefinitely. If a
|
# Abort a stalled fetch instead of blocking startup indefinitely. If a
|
||||||
# git+http transfer (e.g. `nix flake lock` of the forge-hosted config
|
# git http transfer from the forge (e.g. filling an applied mirror)
|
||||||
# inputs) drops below 1 KiB/s for 30s -- forge unreachable / not ready
|
# drops below 1 KiB/s for 30s -- forge unreachable / not ready on cold
|
||||||
# on cold boot -- git fails fast rather than hanging the whole daemon.
|
# boot -- git fails fast rather than hanging the whole daemon.
|
||||||
# Pairs with GIT_TERMINAL_PROMPT=0 (no credential-prompt hang) and the
|
# Pairs with GIT_TERMINAL_PROMPT=0 (no credential-prompt hang) and the
|
||||||
# migration shellout timeout in migrate.rs.
|
# migration shellout timeout in migrate.rs.
|
||||||
lowSpeedLimit = 1024
|
lowSpeedLimit = 1024
|
||||||
|
|
@ -265,8 +265,8 @@ in
|
||||||
after = [ "hive-c0re.socket" ];
|
after = [ "hive-c0re.socket" ];
|
||||||
path = [
|
path = [
|
||||||
pkgs.git
|
pkgs.git
|
||||||
# `git-credential-hive-forge` on PATH so git finds it when nix fetches
|
# `git-credential-hive-forge` on PATH so git finds it for git+http
|
||||||
# the forge-hosted agent-config inputs (helper = hive-forge).
|
# fetches from the forge (helper = hive-forge).
|
||||||
forgeCredHelper
|
forgeCredHelper
|
||||||
"/run/current-system/sw"
|
"/run/current-system/sw"
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,8 @@ in
|
||||||
# Never let git block on an interactive credential prompt. hive-core is a
|
# Never let git block on an interactive credential prompt. hive-core is a
|
||||||
# TTY-less system user, so a prompt (e.g. the forge credential helper
|
# TTY-less system user, so a prompt (e.g. the forge credential helper
|
||||||
# returns nothing because the forge isn't reachable yet on cold boot)
|
# returns nothing because the forge isn't reachable yet on cold boot)
|
||||||
# would hang forever — this is what froze the whole daemon during startup
|
# would hang forever and freeze the daemon during startup. With this set,
|
||||||
# migration's `nix flake lock` of the forge-hosted config inputs. With
|
# git fails fast instead of prompting. Paired with the git http
|
||||||
# this set, git fails fast instead of prompting. Paired with the git http
|
|
||||||
# low-speed abort in `safeDirGitconfig` (bounds a stalled transfer) and
|
# low-speed abort in `safeDirGitconfig` (bounds a stalled transfer) and
|
||||||
# the 120s migration shellout timeout in migrate.rs.
|
# the 120s migration shellout timeout in migrate.rs.
|
||||||
GIT_TERMINAL_PROMPT = "0";
|
GIT_TERMINAL_PROMPT = "0";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue