hive-c0re: fail a nixos-container destroy that leaves the container in place
lifecycle::destroy logged a failed `nixos-container destroy` and returned Ok, so the DestroyContainer node went green, the agent was unregistered, and with purge the after_ok PurgeState deleted its state while the container config and root still existed. Propagate the error unless the container list, read after the failure, no longer names the container. An unreadable list fails too.
This commit is contained in:
parent
5b54b6ddc8
commit
18bd8dd2c7
3 changed files with 85 additions and 3 deletions
|
|
@ -326,3 +326,54 @@ fn passwd_parse_rejects_unusable_ids() {
|
|||
Some((1000, 994))
|
||||
);
|
||||
}
|
||||
|
||||
/// A failed `nixos-container destroy` whose container is still listed fails,
|
||||
/// and keeps hive-priv's error in the chain. The destroy DAG gates the state
|
||||
/// purge on this call, so this is the case that must not read as success.
|
||||
#[test]
|
||||
fn failed_destroy_with_the_container_still_listed_fails() {
|
||||
let err = confirm_gone_after_failed_destroy(
|
||||
anyhow::anyhow!("nixos-container destroy h-doomed failed (exit status: 1)"),
|
||||
"h-doomed",
|
||||
Ok(vec!["h-other".to_owned(), "h-doomed".to_owned()]),
|
||||
)
|
||||
.expect_err("a surviving container must fail the destroy");
|
||||
let chain = format!("{err:#}");
|
||||
assert!(chain.contains("h-doomed still exists"), "{chain}");
|
||||
assert!(chain.contains("exit status: 1"), "{chain}");
|
||||
}
|
||||
|
||||
/// A container missing from the list is gone, whatever the destroy exit code
|
||||
/// said, so the destroy succeeds.
|
||||
#[test]
|
||||
fn failed_destroy_with_the_container_gone_succeeds() {
|
||||
confirm_gone_after_failed_destroy(
|
||||
anyhow::anyhow!("nixos-container destroy h-doomed failed"),
|
||||
"h-doomed",
|
||||
Ok(vec!["h-other".to_owned()]),
|
||||
)
|
||||
.expect("an absent container is a completed destroy");
|
||||
// Control: the same list with the container in it fails, so the pass
|
||||
// above comes from the absence, not from the helper accepting anything.
|
||||
assert!(
|
||||
confirm_gone_after_failed_destroy(
|
||||
anyhow::anyhow!("nixos-container destroy h-doomed failed"),
|
||||
"h-doomed",
|
||||
Ok(vec!["h-other".to_owned(), "h-doomed".to_owned()]),
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
/// An unreadable list proves nothing about the container, so the destroy
|
||||
/// fails rather than guessing it is gone.
|
||||
#[test]
|
||||
fn failed_destroy_with_an_unreadable_list_fails() {
|
||||
let err = confirm_gone_after_failed_destroy(
|
||||
anyhow::anyhow!("nixos-container destroy h-doomed failed"),
|
||||
"h-doomed",
|
||||
Err(anyhow::anyhow!("connect to hive-priv socket")),
|
||||
)
|
||||
.expect_err("an unreadable list must not pass for an absent container");
|
||||
assert!(format!("{err:#}").contains("cannot confirm"), "{err:#}");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue