fold hive-c0re module tree into the daemon binary + drop dead pub items surfaced by bin-only (#2513)

This commit is contained in:
damocles 2026-07-15 23:54:43 +02:00 committed by mara
commit 673aea4e50
15 changed files with 95 additions and 250 deletions

View file

@ -22,13 +22,7 @@ use super::{
pub async fn write_dropins(name: &str, hive: &HiveEnv, paths: &AgentPaths) -> Result<()> {
validate(name)?;
let container = container_name(name);
set_nspawn_flags(
&container,
&paths.agent_dir,
&paths.claude_dir,
&paths.notes_dir,
)
.await?;
set_nspawn_flags(&container, &paths.agent, &paths.claude, &paths.notes).await?;
set_resource_limits(&container, &hive.agent_cpu_quota, &hive.agent_memory_max).await?;
systemd_daemon_reload().await
}
@ -44,16 +38,6 @@ async fn systemd_daemon_reload() -> Result<()> {
crate::priv_client::daemon_reload().await
}
/// Idempotently rewrite the lines in `/etc/nixos-containers/<container>.conf`
/// that hive-c0re owns: `PRIVATE_NETWORK` (forced 0 so the agent's web UI port
/// is reachable on the host) and `EXTRA_NSPAWN_FLAGS` (the runtime-dir bind).
/// The start script expands `$EXTRA_NSPAWN_FLAGS` unquoted into the
/// `systemd-nspawn` command.
/// Where in the container's filesystem the manager sees its agents tree.
/// Matches the `/agents` path that pre-Phase-8 hosts declared via
/// `containers.root.bindMounts."/agents"`.
pub const CONTAINER_MANAGER_AGENTS_MOUNT: &str = "/agents";
/// Where the manager sees the applied trees of every agent, read-only.
/// Manager runs `git fetch /applied/<n>/.git refs/tags/*:refs/tags/applied/*`
/// to learn what hive-c0re deployed (or rejected, or failed to
@ -115,6 +99,11 @@ fn hive_load_credentials() -> Vec<CredentialMount> {
out
}
/// Idempotently rewrite the lines in `/etc/nixos-containers/<container>.conf`
/// that hive-c0re owns: `PRIVATE_NETWORK` (forced 0 so the agent's web UI port
/// is reachable on the host) and `EXTRA_NSPAWN_FLAGS` (the runtime-dir bind).
/// The start script expands `$EXTRA_NSPAWN_FLAGS` unquoted into the
/// `systemd-nspawn` command.
#[allow(
clippy::too_many_lines,
reason = "one contiguous nspawn-flag assembly block; the length is the flag \

View file

@ -10,16 +10,12 @@ pub use git::{
git, git_command, git_read_tree_reset, git_rev_parse, git_tag, git_tag_annotated,
git_update_ref,
};
pub use host_config::{
CONTAINER_MANAGER_AGENTS_MOUNT, CONTAINER_MANAGER_APPLIED_MOUNT, write_dropins,
};
pub use host_config::write_dropins;
pub use setup::{
ensure_agent_state_subvolume, ensure_claude_dir, ensure_state_dir, initial_flake_nix,
setup_applied, setup_proposed,
};
use std::path::Path;
use anyhow::{Context, Result, bail};
use tokio::process::Command;
@ -164,23 +160,6 @@ pub fn agent_uid_gid(agent_name: &str) -> Option<(u32, u32)> {
None
}
/// Best-effort `chown(path, agent_uid, agent_gid)`. Resolves the agent's
/// uid/gid via [`agent_uid_gid`] and shells out to `std::os::unix::fs::chown`.
/// Silently no-ops when the container isn't built yet (`None` from
/// [`agent_uid_gid`]) and logs at debug on chown syscall failure — the
/// activation script in the harness user module is the steady-state safety
/// net. Used by per-agent state writers in `forge` + `matrix` so the
/// agent can read the file without waiting for the next container
/// rebuild.
pub fn chown_to_agent(name: &str, path: &Path, subsystem: &str) {
let Some((uid, gid)) = agent_uid_gid(name) else {
return;
};
if let Err(e) = std::os::unix::fs::chown(path, Some(uid), Some(gid)) {
tracing::debug!(%name, %subsystem, path = %path.display(), error = %e, "chown to agent failed");
}
}
fn validate(name: &str) -> Result<()> {
if name.is_empty() {
bail!("agent name must not be empty");
@ -239,11 +218,11 @@ pub async fn provision_container(name: &str, hive: &HiveEnv, paths: &AgentPaths)
agent_web_port(name)
);
}
setup_proposed(&paths.proposed_dir, name).await?;
setup_applied(&paths.applied_dir, Some(&paths.proposed_dir), name).await?;
setup_proposed(&paths.proposed, name).await?;
setup_applied(&paths.applied, Some(&paths.proposed), name).await?;
ensure_agent_state_subvolume(name).await?;
ensure_claude_dir(&paths.claude_dir)?;
ensure_state_dir(&paths.notes_dir)?;
ensure_claude_dir(&paths.claude)?;
ensure_state_dir(&paths.notes)?;
// Meta flake gets the new agent's input + nixosConfiguration
// before `nixos-container create` so the `--flake meta#<name>`
// ref resolves.
@ -278,10 +257,10 @@ pub async fn prepare_rebuild_dirs(name: &str, paths: &AgentPaths) -> Result<()>
agent_web_port(name)
);
}
setup_applied(&paths.applied_dir, None, name).await?;
setup_applied(&paths.applied, None, name).await?;
ensure_agent_state_subvolume(name).await?;
ensure_claude_dir(&paths.claude_dir)?;
ensure_state_dir(&paths.notes_dir)?;
ensure_claude_dir(&paths.claude)?;
ensure_state_dir(&paths.notes)?;
Ok(())
}
@ -515,13 +494,6 @@ async fn start_with_fallback_inner(name: &str) -> Result<()> {
.with_context(|| format!("cold-start fallback also failed for {name}"))
}
/// Stop + start without regenerating any config. For "kick the container"
/// without touching the flake or nspawn flags.
pub async fn restart(name: &str) -> Result<()> {
kill(name).await?;
start(name).await
}
/// True when the container's systemd unit is active. Used by the dashboard
/// to gate stop/restart buttons.
pub async fn is_running(name: &str) -> bool {