From 48420890e052f4ce2bff9c5e96417b1792a17cc9 Mon Sep 17 00:00:00 2001 From: damocles Date: Sun, 24 May 2026 12:08:41 +0200 Subject: [PATCH] lifecycle: preserve stopped state across rebuild (closes #371) --- hive-c0re/src/lifecycle.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/hive-c0re/src/lifecycle.rs b/hive-c0re/src/lifecycle.rs index fd3986a..472867f 100644 --- a/hive-c0re/src/lifecycle.rs +++ b/hive-c0re/src/lifecycle.rs @@ -336,14 +336,25 @@ pub async fn rebuild_no_meta( let container = container_name(name); let flake_ref = format!("{}#{name}", crate::meta::meta_dir().display()); if container_exists(name).await { - // Existing container: update nspawn flags, then rebuild + restart - // so any bind-mount / networking changes take effect. + // Existing container: preserve the prior running state across + // rebuild (closes #371). If it was running, cycle stop+start so + // any bind-mount / networking changes in the nspawn conf take + // effect. If it was stopped, leave it stopped — even if + // `nixos-container update` brought it up to run the in-container + // switch, the operator's explicit "stopped" intent wins. + let was_running = is_running(name).await; set_nspawn_flags(&container, agent_dir, claude_dir, notes_dir)?; set_resource_limits(&container)?; systemd_daemon_reload().await?; run(&["update", &container, "--flake", &flake_ref]).await?; - run(&["stop", &container]).await?; - run(&["start", &container]).await + if was_running { + run(&["stop", &container]).await?; + run(&["start", &container]).await + } else if is_running(name).await { + run(&["stop", &container]).await + } else { + Ok(()) + } } else { // First spawn: create the container first (which writes the nspawn // conf file), then overwrite with our flags and start.