diff --git a/hive-priv/src/main.rs b/hive-priv/src/main.rs index cdeac79b..571a7976 100644 --- a/hive-priv/src/main.rs +++ b/hive-priv/src/main.rs @@ -513,7 +513,7 @@ async fn exec( /// this itself). Best-effort — if the unit doesn't exist yet (first-time /// create), `reset-failed` is a no-op and the start proceeds regardless. async fn start_container(name: &str) -> Result<(String, String)> { - validate_container_name(name)?; + validate_agent_name(name)?; let machine = container_system_name(name); let _ = Command::new("systemctl") .args(["reset-failed", &format!("container@{machine}.service")]) @@ -587,7 +587,7 @@ fn write_extra_forge_account( /// `StopContainer`. async fn stop_container(name: &str) -> Result<(String, String)> { - validate_container_name(name)?; + validate_agent_name(name)?; stop_and_release(&container_system_name(name)).await } @@ -596,14 +596,14 @@ async fn stop_container(name: &str) -> Result<(String, String)> { /// right semantics for a forced shutdown after a graceful stop has already /// been attempted. async fn kill_container(name: &str) -> Result<(String, String)> { - validate_container_name(name)?; + validate_agent_name(name)?; let machine = container_system_name(name); machinectl_run(&["kill", &machine, "--signal=SIGKILL"]).await } /// `DestroyContainer`. async fn destroy_container(name: &str) -> Result<(String, String)> { - validate_container_name(name)?; + validate_agent_name(name)?; container_run(&["destroy", &container_system_name(name)]).await } @@ -765,7 +765,7 @@ async fn container_flake_action( stream: bool, writer: &mut OwnedWriteHalf, ) -> Result<(String, String)> { - validate_container_name(name)?; + validate_agent_name(name)?; // The build is the multi-minute phase of this operation — give it the // same live-line treatment `container_run_streaming` gives // `nixos-container` itself when the caller asked for it. Without @@ -2722,6 +2722,13 @@ async fn sync_gateway_nginx() -> Result<(String, String)> { /// Return the system container name for a logical agent name. /// All agents (including the manager) use the `h-` prefix. +/// +/// **This prefix is what confines the lifecycle verbs to agent containers** — +/// not their name validation, which only checks characters. A caller cannot +/// name `hive-forge` and reach it: it becomes `h-hive-forge`. Infra containers +/// are reached through [`PrivRequest::ControlInfraContainer`] and the +/// [`InfraContainer`] enum instead, which is why no lifecycle verb here takes +/// a sibling name. fn container_system_name(name: &str) -> String { format!("{AGENT_PREFIX}{name}") } @@ -2733,15 +2740,6 @@ fn validate_agent_name(name: &str) -> Result<()> { Ok(()) } -/// Validate a logical agent name and check it maps to a hive-managed container. -fn validate_container_name(name: &str) -> Result<()> { - if SIBLING_CONTAINERS.contains(&name) { - return Ok(()); - } - validate_name_chars(name)?; - Ok(()) -} - /// Validate a system-level container name (already has `h-` prefix for /// all agents including the manager, or is a sibling service name). fn validate_container_system_name(name: &str) -> Result<()> {