Skip to content

fix(compose): ps_status recognises all daemon-unreachable phrasings & can't hang (#178) - #271

Merged
Xiddoc merged 1 commit into
masterfrom
claude/beetroot-sweep-optimize-jp5vdq
Jul 1, 2026
Merged

fix(compose): ps_status recognises all daemon-unreachable phrasings & can't hang (#178)#271
Xiddoc merged 1 commit into
masterfrom
claude/beetroot-sweep-optimize-jp5vdq

Conversation

@Xiddoc

@Xiddoc Xiddoc commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes #178. compose.ps_status had two defects that defeated its docker-unreachable vs not-created contract:

  1. Narrow daemon-unreachable detection. It scraped stderr for only the exact lowercase substring cannot connect to the docker daemon, so the other CLI phrasing — failed to connect to the docker API at ... (custom/rootless socket via DOCKER_HOST, Docker Desktop stopped) — fell through and was misreported as not-created, telling the user the instance was never created when the real fault was daemon connectivity.
  2. No timeout → hang. The underlying docker compose ps call carried no timeout=, so a wedged-but-reachable daemon or an unresponsive TCP DOCKER_HOST made ls / status / doctor (all of which read Instance.statusps_status) hang forever instead of degrading to docker-unreachable.

Changes

  • ps_status now matches a family of daemon-unreachable stderr markers (_DAEMON_UNREACHABLE_MARKERS: cannot connect to the docker daemon or failed to connect to the docker).
  • The probe runs under a bounded timeout=_PS_STATUS_TIMEOUT (20 s, mirroring builder._DOCKER_INFO_TIMEOUT); subprocess.TimeoutExpired is caught and mapped to docker-unreachable.
  • Scoped strictly to the read-only ps_status probe — lifecycle/streaming verbs (up/down/logs/build) are intentionally left with an unbounded wait.

Tests

New cases in tests/test_compose.py:

  • failed to connect to the docker API at ... stderr → docker-unreachable (pins the misclassification regression).
  • subprocess.TimeoutExpireddocker-unreachable (covers the new timeout branch).
  • Asserts the bounded timeout= is forwarded to docker compose ps.

Existing cannot connect to the docker daemon and not-created paths are unchanged. Full suite green at 100% line+branch coverage locally (ruff, mypy --strict, pytest).

🤖 Generated with Claude Code

https://claude.ai/code/session_01WmChW67jv2BaPk1a8HreHU


Generated by Claude Code

… can't hang (#178)

ps_status previously (1) detected an unreachable daemon by scraping stderr for
only the exact substring "cannot connect to the docker daemon", so the
"failed to connect to the docker API at ..." phrasing (custom/rootless
DOCKER_HOST socket) fell through and was misreported as "not-created"; and
(2) ran `docker compose ps` with no timeout, so a wedged-but-reachable daemon
or an unresponsive TCP DOCKER_HOST hung ls/status/doctor forever.

Now it matches a family of daemon-unreachable stderr markers and runs the probe
under a bounded 20s timeout (mirroring builder._DOCKER_INFO_TIMEOUT), catching
subprocess.TimeoutExpired and degrading to "docker-unreachable". Scoped to the
read-only ps_status probe; lifecycle/streaming verbs are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WmChW67jv2BaPk1a8HreHU
@Xiddoc
Xiddoc merged commit 134f66f into master Jul 1, 2026
17 checks passed
@Xiddoc
Xiddoc deleted the claude/beetroot-sweep-optimize-jp5vdq branch July 1, 2026 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants