actions::destroy syncs meta after lifecycle

once nixos-container destroy lands + per-agent state cleanup is
done, rerender the meta flake from the remaining containers so
the destroyed agent's input + nixosConfiguration drop off and
its flake.lock entry vanishes. log + keep going on meta-sync
failure — the destroy already succeeded at the lifecycle level,
so meta drift here is just bookkeeping. new public
lifecycle::agents_for_meta_listing exposes the agent
enumeration for callers outside the module.
This commit is contained in:
müde 2026-05-16 00:29:26 +02:00
parent 4cb529351e
commit 22f35def8f
2 changed files with 24 additions and 0 deletions

View file

@ -261,6 +261,14 @@ pub async fn destroy(coord: &Coordinator, name: &str, purge: bool) -> Result<()>
}
}
}
// Meta flake: drop the agent's input + nixosConfiguration so a
// future spawn under the same name re-seeds cleanly, and so the
// meta lock doesn't reference a vanished applied repo. Log + keep
// going on failure — destroy already succeeded at the
// nixos-container level, the meta repo is just bookkeeping.
if let Err(e) = sync_meta_after_lifecycle(coord).await {
tracing::warn!(error = ?e, %name, "meta sync after destroy failed");
}
let _ = coord.approvals.fail_pending_for_agent(
name,
if purge {
@ -276,6 +284,14 @@ pub async fn destroy(coord: &Coordinator, name: &str, purge: bool) -> Result<()>
Ok(())
}
/// Rerender the meta flake from whatever containers still exist on
/// disk. Called after lifecycle ops that change the agent set (today:
/// destroy). Idempotent — a no-op when nothing changed.
async fn sync_meta_after_lifecycle(coord: &Coordinator) -> Result<()> {
let agents = lifecycle::agents_for_meta_listing().await?;
crate::meta::sync_agents(&coord.hyperhive_flake, coord.dashboard_port, &agents).await
}
pub async fn deny(coord: &Coordinator, id: i64, note: Option<&str>) -> Result<()> {
let approval = coord.approvals.get(id)?;
coord.approvals.mark_denied(id, note)?;

View file

@ -213,6 +213,14 @@ async fn agents_after_spawn(name: &str) -> Result<Vec<crate::meta::AgentSpec>> {
agents_for_meta(Some(name)).await
}
/// Public enumeration of currently-existing agents (whatever
/// `nixos-container list` says), sorted, no extras. For callers
/// outside this module that need to reseed meta after lifecycle
/// changes — destroy, startup reconciliation, etc.
pub async fn agents_for_meta_listing() -> Result<Vec<crate::meta::AgentSpec>> {
agents_for_meta(None).await
}
pub async fn kill(name: &str) -> Result<()> {
validate(name)?;
let container = container_name(name);