fix(install): auto-clean stuck OTHER-variant bitcoin container
If bitcoin-core was installed but never started (e.g. port 8332 already bound by bitcoin-knots), the container sticks in `created` state forever. The old conflict check refused EVERY future bitcoin install — including re-install of the running variant — leaving no UI path to recovery. Now the check distinguishes states: - missing → no conflict, continue - running → real conflict, refuse install - created/exited/configured/... → stuck; auto-remove and continue Volumes are untouched; only the dead container record goes away. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d5c1253a7e
commit
8321d093e8
@ -1799,40 +1799,64 @@ async fn check_bitcoin_implementation_conflict(package_id: &str) -> Result<()> {
|
|||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let output = tokio::process::Command::new("podman")
|
// Three cases for the OTHER variant:
|
||||||
.args([
|
// - missing → no conflict, continue
|
||||||
"ps",
|
// - running → real conflict, refuse install
|
||||||
"-a",
|
// - any other state (created/exited/configured/...) → stuck from a
|
||||||
"--format",
|
// prior failed install. Auto-remove so reinstall is reachable
|
||||||
"{{.Names}}",
|
// without a manual `podman rm`. This is what unblocks the .198
|
||||||
"--filter",
|
// "bitcoin-core stuck in created, port 8332 held by bitcoin-knots"
|
||||||
&format!("name=^{}$", other),
|
// deadlock that no UI path could exit.
|
||||||
])
|
let inspect = tokio::process::Command::new("podman")
|
||||||
|
.args(["inspect", other, "--format", "{{.State.Status}}"])
|
||||||
.output()
|
.output()
|
||||||
.await
|
.await
|
||||||
.context("Failed to check existing Bitcoin node containers")?;
|
.context("Failed to inspect conflicting Bitcoin container")?;
|
||||||
|
if !inspect.status.success() {
|
||||||
if String::from_utf8_lossy(&output.stdout).trim().is_empty() {
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
let state = String::from_utf8_lossy(&inspect.stdout).trim().to_string();
|
||||||
|
|
||||||
let current = match other {
|
if state == "running" {
|
||||||
|
let current = pretty_bitcoin_name(other);
|
||||||
|
let requested = pretty_bitcoin_name(package_id);
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"{} is currently running. Stop and uninstall {} before installing {}; both implementations use the same Bitcoin data directory and ports.",
|
||||||
|
current, current, requested
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"Removing stuck {} container (state={}) before installing {}",
|
||||||
|
other, state, package_id
|
||||||
|
);
|
||||||
|
install_log(&format!(
|
||||||
|
"INSTALL UNSTUCK: removing {} (state={}) before installing {}",
|
||||||
|
other, state, package_id
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
let rm = tokio::process::Command::new("podman")
|
||||||
|
.args(["rm", "-f", other])
|
||||||
|
.output()
|
||||||
|
.await
|
||||||
|
.context("Failed to remove stuck Bitcoin container")?;
|
||||||
|
if !rm.status.success() {
|
||||||
|
let stderr = String::from_utf8_lossy(&rm.stderr);
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"Failed to remove stuck {} container: {}",
|
||||||
|
other,
|
||||||
|
stderr.trim()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pretty_bitcoin_name(id: &str) -> &'static str {
|
||||||
|
match id {
|
||||||
"bitcoin-core" => "Bitcoin Core",
|
"bitcoin-core" => "Bitcoin Core",
|
||||||
"bitcoin-knots" => "Bitcoin Knots",
|
"bitcoin-knots" => "Bitcoin Knots",
|
||||||
_ => "another Bitcoin node",
|
_ => "another Bitcoin node",
|
||||||
};
|
}
|
||||||
let requested = match package_id {
|
|
||||||
"bitcoin-core" => "Bitcoin Core",
|
|
||||||
"bitcoin-knots" => "Bitcoin Knots",
|
|
||||||
_ => "the requested Bitcoin node",
|
|
||||||
};
|
|
||||||
|
|
||||||
Err(anyhow::anyhow!(
|
|
||||||
"{} is already installed. Stop and uninstall {} before installing {}; both implementations use the same Bitcoin data directory and ports.",
|
|
||||||
current,
|
|
||||||
current,
|
|
||||||
requested
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn orchestrator_install_app_id(package_id: &str) -> &str {
|
fn orchestrator_install_app_id(package_id: &str) -> &str {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user