fix(#636): fall back to kill+start when container start fails after rebuild

This commit is contained in:
damocles 2026-05-31 20:25:52 +02:00
commit b3fde40ac8

View file

@ -438,7 +438,38 @@ pub async fn rebuild_no_meta(
}
run(&["update", &container, "--flake", &flake_ref]).await?;
if was_running {
run(&["start", &container]).await
// Normal path: start into the new generation. The activation
// script runs inside the container to transition old → new.
// This can fail when packages are removed between generations —
// the old-generation activation references units that no longer
// exist in the new closure, causing systemd to exit non-zero.
//
// Fallback: kill + start (cold-start). `kill` SIGKILLs any
// lingering container processes so the next `start` enters a
// clean state without a generation transition, letting the
// activation succeed.
if let Err(start_err) = run(&["start", &container]).await {
tracing::warn!(
container = %container,
error = %start_err,
"start after rebuild failed (possible activation error); \
retrying via kill + start"
);
run(&["kill", &container]).await.unwrap_or_else(|e| {
tracing::warn!(
container = %container,
error = %e,
"kill before cold-start retry failed (ignored)"
);
});
run(&["start", &container]).await
.map_err(|e| anyhow::anyhow!(
"cold-start fallback also failed: {e:#} \
(original start error: {start_err:#})"
))
} else {
Ok(())
}
} else {
Ok(())
}