Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/lib/preflight.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,37 @@ describe("planHostRemediation", () => {
expect(actions[0].commands).toContain("sudo systemctl start docker");
});

it("flags socket permission instead of 'start docker' when daemon is active but unreachable (#1574)", () => {
const actions = planHostRemediation({
platform: "linux",
isWsl: false,
runtime: "unknown",
packageManager: "apt",
systemctlAvailable: true,
dockerServiceActive: true,
dockerServiceEnabled: true,
dockerInstalled: true,
dockerRunning: false,
dockerReachable: false,
nodeInstalled: true,
openshellInstalled: true,
dockerCgroupVersion: "unknown",
dockerDefaultCgroupnsMode: "unknown",
requiresHostCgroupnsFix: false,
isUnsupportedRuntime: false,
isHeadlessLikely: false,
hasNvidiaGpu: false,
notes: [],
});

expect(actions[0].id).toBe("fix_docker_socket_permission");
expect(actions[0].blocking).toBe(true);
expect(actions[0].commands).toContain("sudo usermod -aG docker $USER");
// Must NOT suggest starting docker — that's the misleading message #1574 calls out.
expect(actions[0].commands).not.toContain("sudo systemctl start docker");
expect(actions[0].reason).toMatch(/socket/i);
});

it("warns that podman is unsupported on macOS without blocking onboarding", () => {
const actions = planHostRemediation({
platform: "darwin",
Expand Down
49 changes: 36 additions & 13 deletions src/lib/preflight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,19 +352,42 @@ export function planHostRemediation(assessment: HostAssessment): RemediationActi
blocking: true,
});
} else if (!assessment.dockerReachable) {
actions.push({
id: "start_docker",
title: "Start Docker",
kind: "manual",
reason: "Docker is installed but NemoClaw could not talk to the Docker daemon.",
commands:
assessment.platform === "darwin"
? ["Start Docker Desktop or Colima, then rerun `nemoclaw onboard`."]
: assessment.systemctlAvailable
? ["sudo systemctl start docker", "nemoclaw onboard"]
: ["Start the Docker daemon, then rerun `nemoclaw onboard`."],
blocking: true,
});
// Distinguish "daemon not running" from "daemon running but the current
// user can't reach the socket". When systemd reports docker.service is
// active but `docker info` still fails, asking the user to start docker
// is misleading — the real fix is to grant socket access (typically by
// adding the user to the docker group). See issue #1574.
if (assessment.platform === "linux" && assessment.dockerServiceActive === true) {
actions.push({
id: "fix_docker_socket_permission",
title: "Grant Docker socket access",
kind: "manual",
reason:
"Docker daemon is running but NemoClaw could not talk to the Docker socket. " +
"This usually means your user does not have permission to access /var/run/docker.sock.",
commands: [
"sudo usermod -aG docker $USER",
"newgrp docker # or log out and back in",
"docker info # confirm the socket is reachable",
"nemoclaw onboard",
],
blocking: true,
});
} else {
actions.push({
id: "start_docker",
title: "Start Docker",
kind: "manual",
reason: "Docker is installed but NemoClaw could not talk to the Docker daemon.",
commands:
assessment.platform === "darwin"
? ["Start Docker Desktop or Colima, then rerun `nemoclaw onboard`."]
: assessment.systemctlAvailable
? ["sudo systemctl start docker", "nemoclaw onboard"]
: ["Start the Docker daemon, then rerun `nemoclaw onboard`."],
blocking: true,
});
}
}

if (assessment.isUnsupportedRuntime) {
Expand Down
Loading