fix: harden container reconcile and launch behavior

This commit is contained in:
Dorian
2026-05-13 22:59:55 -04:00
parent 835c525218
commit 2ff47f88a7
9 changed files with 259 additions and 11 deletions
@@ -62,6 +62,19 @@ fn is_required_baseline_app(app_id: &str) -> bool {
)
}
fn is_restart_sensitive_app(app_id: &str) -> bool {
matches!(
app_id,
"bitcoin-knots"
| "bitcoin-core"
| "bitcoin"
| "lnd"
| "btcpay-server"
| "fedimint"
| "fedimint-gateway"
)
}
fn requires_archival_bitcoin(app_id: &str) -> bool {
matches!(
app_id,
@@ -713,6 +726,17 @@ impl ProdContainerOrchestrator {
return Ok(ReconcileAction::Started);
}
if self.container_env_drifted(&name, &resolved_manifest).await {
if mode == ReconcileMode::ExistingOnly
&& is_restart_sensitive_app(&app_id)
{
tracing::info!(
app_id = %app_id,
container = %name,
"container drift detected during boot reconcile; leaving running restart-sensitive app untouched"
);
self.run_post_start_hooks(&app_id).await?;
return Ok(ReconcileAction::NoOp);
}
tracing::info!(app_id = %app_id, container = %name, "container env drift detected — recreating");
let _ = self.runtime.stop_container(&name).await;
let _ = self.runtime.remove_container(&name).await;
@@ -2252,6 +2276,7 @@ mod tests {
runtime,
PathBuf::from("/nonexistent-for-tests"),
);
orch.set_data_dir(PathBuf::from("/nonexistent-for-tests"));
// Redirect the bitcoin-ui pre-start hook to a test-scoped
// tmpdir, seeded with a fake password file. Shared across
// every test in this module (OnceLock), so the hook can run
@@ -2259,6 +2284,7 @@ mod tests {
// this redirection, any test that installs the bitcoin-ui
// fixture would try to write under /var/lib/archipelago.
orch.set_bitcoin_ui_paths(test_bitcoin_ui_paths());
orch.set_filebrowser_paths(test_filebrowser_paths());
orch
}
@@ -2339,6 +2365,17 @@ app:
}
}
fn test_filebrowser_paths() -> filebrowser::EnsurePaths {
use std::sync::OnceLock;
static DIR: OnceLock<tempfile::TempDir> = OnceLock::new();
let dir = DIR.get_or_init(|| tempfile::TempDir::new().expect("test tmpdir"));
filebrowser::EnsurePaths {
srv_root: dir.path().join("filebrowser"),
data_dir: dir.path().join("filebrowser-data"),
config_path: dir.path().join("filebrowser-data/.filebrowser.json"),
}
}
#[tokio::test]
async fn install_fresh_pull() {
let rt = Arc::new(MockRuntime::default());