From 666e595dfc85ab3eec6e124c24a7e11b12e68ae8 Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Fri, 6 Nov 2026 04:26:53 +0100 Subject: [PATCH] fix: the Docker daemon preflight fires on CLI 24 through 27 (release review) `docker info --format` exits 0 with the daemon unreachable on those clients, so a user outside the docker group got a raw Compose error and a "network hiccup" hint after docker/.env and the data folder had already been written. `docker version --format` exits 1 on every release and keeps the same stderr text, so the permission branch still matches. The test stub now answers `info` the way those clients do. Co-Authored-By: Claude Opus 5.5 --- docker/Start-Codeman.sh | 8 +++++--- test/docker-start-setup.test.ts | 13 ++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/docker/Start-Codeman.sh b/docker/Start-Codeman.sh index 4e8b7351..d74eb49f 100644 --- a/docker/Start-Codeman.sh +++ b/docker/Start-Codeman.sh @@ -111,8 +111,10 @@ if version_older_than "$compose_version" "$min_compose_version"; then exit 1 fi -if ! docker_info_error=$(docker info --format '{{.ServerVersion}}' 2>&1 >/dev/null); then - case "$docker_info_error" in +# `docker version`, not `docker info`: on CLI 24 through 27 `info --format` exits +# 0 with the daemon unreachable (measured on 27.5.1), so this check never fired. +if ! docker_error=$(docker version --format '{{.Server.Version}}' 2>&1 >/dev/null); then + case "$docker_error" in *[Pp]ermission\ denied*) account=$(id -un 2>/dev/null || printf 'your account') printf 'Error: %s is not allowed to use Docker yet.\n' "$account" >&2 @@ -124,7 +126,7 @@ if ! docker_info_error=$(docker info --format '{{.ServerVersion}}' 2>&1 >/dev/nu *) printf 'Error: the Docker daemon is not reachable. Start it (Linux: sudo systemctl start\n' >&2 printf 'docker; macOS and Windows: open Docker Desktop), then rerun this script.\n' >&2 - printf 'Docker said: %s\n' "$docker_info_error" >&2 + printf 'Docker said: %s\n' "$docker_error" >&2 ;; esac exit 1 diff --git a/test/docker-start-setup.test.ts b/test/docker-start-setup.test.ts index 8faa7ddb..a5981f32 100644 --- a/test/docker-start-setup.test.ts +++ b/test/docker-start-setup.test.ts @@ -60,8 +60,15 @@ const REWRITTEN_KEYS = ['TZ', 'CODEMAN_APPDATA_PATH', 'CODEMAN_CASES_PATH', 'COD const STUB = [ '#!/usr/bin/env bash', 'echo "docker $*" >> "$CMDLOG"', + // Docker CLI 24 to 27 answer `info --format` with exit 0 and the error on + // stderr when the daemon is unreachable (measured on 27.5.1); `version --format` + // exits 1 on every release. 'if [[ "$1" == "info" ]]; then', - ' if [[ -n "${STUB_INFO_ERR:-}" ]]; then echo "$STUB_INFO_ERR" >&2; exit 1; fi', + ' if [[ -n "${STUB_DAEMON_ERR:-}" ]]; then echo "$STUB_DAEMON_ERR" >&2; exit 0; fi', + ' echo 27.0.0; exit 0', + 'fi', + 'if [[ "$1" == "version" ]]; then', + ' if [[ -n "${STUB_DAEMON_ERR:-}" ]]; then echo "$STUB_DAEMON_ERR" >&2; exit 1; fi', ' echo 27.0.0; exit 0', 'fi', 'if [[ "$1" == "compose" ]]; then', @@ -310,7 +317,7 @@ describe('Start-Codeman.sh preflight', () => { it('names the docker group (not sudo) when the account cannot reach the daemon', () => { const r = runStart(['--setup-only'], { env: { - STUB_INFO_ERR: 'permission denied while trying to connect to the docker API at unix:///var/run/docker.sock', + STUB_DAEMON_ERR: 'permission denied while trying to connect to the docker API at unix:///var/run/docker.sock', }, }); expect(r.status).toBe(1); @@ -321,7 +328,7 @@ describe('Start-Codeman.sh preflight', () => { it('says to start Docker when the daemon is not running, quoting what Docker said', () => { const r = runStart(['--setup-only'], { - env: { STUB_INFO_ERR: 'failed to connect to the docker API at unix:///var/run/docker.sock' }, + env: { STUB_DAEMON_ERR: 'failed to connect to the docker API at unix:///var/run/docker.sock' }, }); expect(r.status).toBe(1); expect(r.stderr).toMatch(/daemon is not reachable/);