fix(#1201): prevent sync_agents from dropping all agents on list() failure
This commit is contained in:
parent
4d1ce6f313
commit
cff3b6ff85
2 changed files with 23 additions and 1 deletions
|
|
@ -276,8 +276,15 @@ pub async fn spawn(
|
||||||
/// where the new agent's container doesn't exist yet). Pass empty
|
/// where the new agent's container doesn't exist yet). Pass empty
|
||||||
/// `name_to_add` from rebuild paths where the agent is already in the
|
/// `name_to_add` from rebuild paths where the agent is already in the
|
||||||
/// container list.
|
/// container list.
|
||||||
|
///
|
||||||
|
/// Propagates errors from `list()` rather than swallowing them.
|
||||||
|
/// Using `.unwrap_or_default()` here would silently produce an empty
|
||||||
|
/// agent list when `nixos-container list` fails (priv helper down, race),
|
||||||
|
/// which `sync_agents` would then commit to meta — dropping every agent
|
||||||
|
/// from `flake.nix`. Callers that can tolerate failures (e.g. migration)
|
||||||
|
/// handle the `Err` themselves with `.unwrap_or_default()`.
|
||||||
async fn agents_for_meta(name_to_add: Option<&str>) -> Result<Vec<crate::meta::AgentSpec>> {
|
async fn agents_for_meta(name_to_add: Option<&str>) -> Result<Vec<crate::meta::AgentSpec>> {
|
||||||
let containers = list().await.unwrap_or_default();
|
let containers = list().await?;
|
||||||
let mut out: Vec<crate::meta::AgentSpec> = containers
|
let mut out: Vec<crate::meta::AgentSpec> = containers
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|c| {
|
.filter_map(|c| {
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,21 @@ pub async fn sync_agents(
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Safety guard: refuse to write an empty agent list over a non-empty
|
||||||
|
// on-disk flake. An empty `agents` slice is never intentional — it
|
||||||
|
// means `nixos-container list` failed and the caller got an empty
|
||||||
|
// fallback. Overwriting here would drop every agent from the meta
|
||||||
|
// flake and trigger unnecessary (and potentially destructive) cascade
|
||||||
|
// rebuilds. Callers that genuinely need to clear the agent list
|
||||||
|
// (there are none today) must handle this case explicitly.
|
||||||
|
if agents.is_empty() && !initial && !on_disk.is_empty() {
|
||||||
|
tracing::warn!(
|
||||||
|
"sync_agents: refusing to overwrite non-empty meta flake with empty agent list \
|
||||||
|
(nixos-container list may have failed)"
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
std::fs::write(&flake_path, &new_flake)
|
std::fs::write(&flake_path, &new_flake)
|
||||||
.with_context(|| format!("write {}", flake_path.display()))?;
|
.with_context(|| format!("write {}", flake_path.display()))?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue