fix(container-list): report user-stopped apps as stopped despite live UI companion
A user-stopped backend (electrumx, bitcoin, lnd, fedimint) kept reading 'running' in container-list because its UI companion (electrs-ui, …) still serves the launch port, and the state-refresh upgrades any reachable launch port to 'running'. The gate's wait_for_container_status <app> stopped therefore never saw 'stopped'. Fix: load the user_stopped marker in handle_container_list and force 'stopped' for those apps before the launch-port refresh. The reconcile guard keeps the backend down, so the marker is authoritative. package.start clears it first, so a started app reports 'running' normally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
760a32bccf
commit
6e49ce6f88
@ -171,6 +171,13 @@ impl RpcHandler {
|
||||
// than the WebSocket-delivered package_data, which caused apps to flicker
|
||||
// between "installed" and "not-installed" in the UI.
|
||||
let (data, _) = self.state_manager.get_snapshot().await;
|
||||
// Apps the user explicitly stopped must read as "stopped" even though a
|
||||
// UI companion (electrs-ui, bitcoin-ui, …) keeps serving the launch port:
|
||||
// launch_port_reachable() below would otherwise upgrade an exited backend
|
||||
// back to "running". The reconcile guard keeps these backends down, so the
|
||||
// marker is authoritative here.
|
||||
let user_stopped =
|
||||
crate::crash_recovery::load_user_stopped(&self.config.data_dir).await;
|
||||
if data.server_info.status_info.containers_scanned && !data.package_data.is_empty() {
|
||||
let mut containers = Vec::with_capacity(data.package_data.len());
|
||||
for (id, pkg) in &data.package_data {
|
||||
@ -202,7 +209,11 @@ impl RpcHandler {
|
||||
// Scanner backoff preserves cached package_data. Refresh stable
|
||||
// states so callers do not see stale `running`/`exited` after
|
||||
// health-monitor recovery or Quadlet --rm container removal.
|
||||
if state == "running" && requires_launch_port_for_health(id) {
|
||||
if user_stopped.contains(id) {
|
||||
// User stopped it → authoritative "stopped". Do NOT let a
|
||||
// still-running UI companion's launch port mark it running.
|
||||
state = "stopped".to_string();
|
||||
} else if state == "running" && requires_launch_port_for_health(id) {
|
||||
if !self.cached_reachable_health(id).await?.is_some() {
|
||||
state = live_state_for_app(id)
|
||||
.await
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user