fix(#977): add MANAGER_CONTAINER=h-root, migrate root container name
This commit is contained in:
parent
286a7c8fd3
commit
68cc433ac9
5 changed files with 115 additions and 29 deletions
|
|
@ -1,5 +1,5 @@
|
|||
//! Startup auto-migration from the pre-meta layout. Four idempotent
|
||||
//! phases: applied repo, proposed repo, meta repo, container repoint.
|
||||
//! Startup auto-migration. Five idempotent phases: applied repo,
|
||||
//! proposed repo, meta repo, container repoint, root→h-root rename.
|
||||
//! Kill-switch: `HIVE_SKIP_META_MIGRATION=1`. Full migration sequence
|
||||
//! and phase details: `docs/approvals.md::Migration from the pre-tag`.
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ use anyhow::{Context, Result};
|
|||
use tokio::process::Command;
|
||||
|
||||
use crate::coordinator::Coordinator;
|
||||
use crate::lifecycle::{self, AGENT_PREFIX, MANAGER_NAME};
|
||||
use crate::lifecycle::{self, AGENT_PREFIX, MANAGER_CONTAINER, MANAGER_NAME};
|
||||
use crate::meta;
|
||||
|
||||
const KILL_SWITCH: &str = "HIVE_SKIP_META_MIGRATION";
|
||||
|
|
@ -21,6 +21,12 @@ fn repoint_marker() -> PathBuf {
|
|||
PathBuf::from("/var/lib/hyperhive/.meta-migration-done")
|
||||
}
|
||||
|
||||
/// Marker for phase 5. Once present, root→h-root container rename is
|
||||
/// skipped on future restarts.
|
||||
fn hroot_rename_marker() -> PathBuf {
|
||||
PathBuf::from("/var/lib/hyperhive/.hroot-rename-done")
|
||||
}
|
||||
|
||||
/// Substring that identifies the *current* agent flake boilerplate.
|
||||
/// Bumped whenever the template changes so the startup migration
|
||||
/// re-renders existing agents onto the new shape. Today the marker
|
||||
|
|
@ -108,6 +114,12 @@ pub async fn run(coord: &Arc<Coordinator>) -> Result<()> {
|
|||
{
|
||||
tracing::warn!(error = ?e, "migration: write repoint marker failed");
|
||||
}
|
||||
|
||||
// Phase 5: rename `root` nixos-container to `h-root` for naming
|
||||
// consistency with sub-agents. Guarded by marker; skipped on
|
||||
// fresh installs (conf file absent) and after first successful run.
|
||||
rename_manager_container(coord).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -140,12 +152,82 @@ fn migrate_harness_files(name: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Phase 5: rename the `root` nixos-container to `h-root` so the
|
||||
/// manager container name is consistent with the `h-` prefix used by
|
||||
/// all sub-agents. Idempotent and marker-guarded. Steps:
|
||||
///
|
||||
/// 1. Check `/etc/nixos-containers/root.conf` exists (old name present).
|
||||
/// 2. Stop the `root` container.
|
||||
/// 3. Copy `root.conf` → `h-root.conf`.
|
||||
/// 4. Move `/var/lib/nixos-containers/root/` → `h-root/` (if present).
|
||||
/// 5. `systemctl daemon-reload` so systemd sees the new unit name.
|
||||
/// 6. `nixos-container start h-root`.
|
||||
/// 7. Write the done marker.
|
||||
///
|
||||
/// Best-effort: logs warnings on failure. A failed rename leaves both
|
||||
/// conf files present; on the next hive-c0re start the marker is
|
||||
/// absent so the phase retries.
|
||||
async fn rename_manager_container(coord: &Arc<Coordinator>) {
|
||||
if hroot_rename_marker().exists() {
|
||||
return;
|
||||
}
|
||||
let old_conf = std::path::PathBuf::from("/etc/nixos-containers/root.conf");
|
||||
let new_conf = std::path::PathBuf::from("/etc/nixos-containers/h-root.conf");
|
||||
if !old_conf.exists() {
|
||||
// Fresh install — root container was never created under the old name.
|
||||
let _ = std::fs::write(hroot_rename_marker(), b"done\n");
|
||||
return;
|
||||
}
|
||||
if new_conf.exists() {
|
||||
// Already renamed (but marker was lost — write it and return).
|
||||
tracing::info!("migration phase 5: h-root.conf already present, marking done");
|
||||
let _ = std::fs::write(hroot_rename_marker(), b"done\n");
|
||||
return;
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
// Copy conf file.
|
||||
if let Err(e) = std::fs::copy(&old_conf, &new_conf) {
|
||||
tracing::warn!(error = ?e, "migration phase 5: copy root.conf failed — aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
// Move rootfs if it exists (may be absent for ephemeral containers).
|
||||
let old_rootfs = std::path::PathBuf::from("/var/lib/nixos-containers/root");
|
||||
let new_rootfs = std::path::PathBuf::from("/var/lib/nixos-containers/h-root");
|
||||
if old_rootfs.exists() && !new_rootfs.exists() {
|
||||
if let Err(e) = std::fs::rename(&old_rootfs, &new_rootfs) {
|
||||
tracing::warn!(error = ?e, "migration phase 5: rename rootfs failed (non-fatal)");
|
||||
}
|
||||
}
|
||||
|
||||
// Daemon reload so systemd picks up the new container@h-root unit.
|
||||
if let Err(e) = Command::new("systemctl").args(["daemon-reload"]).status().await {
|
||||
tracing::warn!(error = ?e, "migration phase 5: systemctl daemon-reload failed");
|
||||
}
|
||||
|
||||
// Start the renamed container.
|
||||
if let Err(e) = Command::new("nixos-container").args(["start", "h-root"]).status().await {
|
||||
tracing::warn!(error = ?e, "migration phase 5: nixos-container start h-root failed");
|
||||
return;
|
||||
}
|
||||
|
||||
tracing::info!("migration phase 5: root container renamed to h-root");
|
||||
let _ = std::fs::write(hroot_rename_marker(), b"done\n");
|
||||
}
|
||||
|
||||
async fn enumerate_agents() -> Vec<String> {
|
||||
let containers = lifecycle::list().await.unwrap_or_default();
|
||||
containers
|
||||
.into_iter()
|
||||
.filter_map(|c| {
|
||||
if c == MANAGER_NAME {
|
||||
if c == MANAGER_CONTAINER {
|
||||
Some(MANAGER_NAME.to_owned())
|
||||
} else {
|
||||
c.strip_prefix(AGENT_PREFIX).map(str::to_owned)
|
||||
|
|
|
|||
Loading…
Reference in a new issue