diff --git a/hive-c0re/src/migrate.rs b/hive-c0re/src/migrate.rs index 044b572a..9ed28ecc 100644 --- a/hive-c0re/src/migrate.rs +++ b/hive-c0re/src/migrate.rs @@ -187,9 +187,19 @@ async fn rename_manager_container(coord: &Arc) { tracing::info!("migration phase 5: renaming root container to h-root"); let _guard = coord.transient_guard(MANAGER_NAME, crate::coordinator::TransientKind::Rebuilding); - // Stop the old container. - if let Err(e) = Command::new("nixos-container").args(["stop", "root"]).status().await { - tracing::warn!(error = ?e, "migration phase 5: nixos-container stop root failed"); + // Stop the old container. Abort if stop fails — continuing with a + // running `root` and then starting `h-root` risks two manager + // instances racing for the same broker / state files. + match Command::new("nixos-container").args(["stop", "root"]).status().await { + Ok(s) if s.success() => {} + Ok(s) => { + tracing::warn!(status = %s, "migration phase 5: nixos-container stop root failed — aborting"); + return; + } + Err(e) => { + tracing::warn!(error = ?e, "migration phase 5: nixos-container stop root failed — aborting"); + return; + } } // Copy conf file. @@ -220,6 +230,12 @@ async fn rename_manager_container(coord: &Arc) { tracing::info!("migration phase 5: root container renamed to h-root"); let _ = std::fs::write(hroot_rename_marker(), b"done\n"); + // Clean up the old conf file so `nixos-container list` doesn't show + // a stale stopped `root` entry. Best-effort; a failure here is + // harmless — h-root is already running and the marker is written. + if let Err(e) = std::fs::remove_file(&old_conf) { + tracing::warn!(error = ?e, "migration phase 5: remove old root.conf failed (non-fatal)"); + } } async fn enumerate_agents() -> Vec {