Skip to content

fix(sandbox): try Docker socket before CLI binary check - #2467

Merged
ymcrcat merged 6 commits into
nearai:stagingfrom
ymcrcat:fix/sandbox-check
Apr 14, 2026
Merged

ymcrcat merged 6 commits into
nearai:stagingfrom
ymcrcat:fix/sandbox-check

Conversation

@ymcrcat

@ymcrcat ymcrcat commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Problem

The sandbox detection in check_docker() called which docker first and returned NotInstalled if the CLI binary was absent — even when the Docker daemon was reachable via a bind-mounted socket. This broke container-in-container deployments (e.g., Nomad shards with /var/run/docker.sock mounted) where bollard can talk to the daemon but no CLI is installed in the slim image.

Solution

Reorder check_docker() to call connect_docker() (bollard socket ping) first. If the daemon responds, return Available immediately. The which docker CLI check is now used only as a fallback for error-message quality when the socket connection fails.

Detection order (new):

  1. Try bollard socket ping → if OK, return Available
  2. Check CLI binary on PATH → if absent, return NotInstalled; otherwise return NotRunning

Files Changed

  • src/sandbox/detect.rs — reordered checks, updated doc comments

Generated with Warp

Co-Authored-By: Oz oz-agent@warp.dev

ymcrcat and others added 2 commits April 14, 2026 02:02
The sandbox detection checked `which docker` first and returned
NotInstalled if the CLI binary was absent — even when the Docker
daemon was reachable via a bind-mounted socket. This broke
container-in-container deployments (e.g., Nomad shards with
/var/run/docker.sock mounted) where bollard can talk to the daemon
but no CLI is installed in the slim image.

Reorder check_docker() to try connect_docker() (bollard socket ping)
first. If the daemon responds, return Available immediately. The CLI
check is now only used as a fallback for error-message quality when
the socket connection fails.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added scope: sandbox Docker sandbox size: S 10-49 changed lines risk: medium Business logic, config, or moderate-risk modules contributor: new First-time contributor labels Apr 14, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Docker detection mechanism to attempt a direct socket connection before checking for the CLI binary, which improves compatibility with container-in-container setups. A review comment correctly identified that the implementation lacks an actual ping to verify the daemon's responsiveness, suggesting the addition of a .ping() call to match the intended behavior and documentation.

Comment thread src/sandbox/detect.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d79e2e3e0a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/sandbox/detect.rs Outdated
check_docker() called connect_docker() before checking whether Docker
was even present, causing a 120s bollard timeout on hosts with an
unreachable DOCKER_HOST and no Docker installation. Add a fast-path
that checks for the docker binary, DOCKER_HOST env var, and socket
files on disk before attempting the daemon ping. This preserves DinD
support (bind-mounted socket, no CLI binary) while avoiding the
latency regression for non-Docker hosts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size: M 50-199 changed lines and removed size: S 10-49 changed lines labels Apr 14, 2026
ymcrcat and others added 3 commits April 14, 2026 16:11
Extract should_skip_daemon_ping() predicate from check_docker() and
add unit tests covering all combinations: skip when no binary, no
DOCKER_HOST, and no socket (the bug scenario); no skip when any of
the three signals is present (DinD socket, DOCKER_HOST, CLI binary).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ymcrcat
ymcrcat enabled auto-merge (squash) April 14, 2026 20:30

@henrypark133 henrypark133 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Docker detection reorder for DinD support (Risk: medium)

Good fix — the three-tier detection (fast-path → bollard ping → binary fallback) is well-structured, and connect_docker() does actually ping the daemon (container.rs:651-652), so Gemini's prior concern is resolved. The fast-path correctly avoids the 120s bollard timeout on hosts with no Docker at all. Comments and documentation are clear.

Positives:

  • Correctly solves the DinD use case (socket bind-mounted, no CLI binary)
  • Fast-path avoids unnecessary bollard timeout on non-Docker hosts
  • Well-documented rationale in both module and function doc comments

Suggestion: Extract decision logic for testability [Testing]

File: src/sandbox/detect.rs

The new branching logic in check_docker() would benefit from a small refactor to make it testable without Docker. Extract the decision into a pure function:

fn resolve_status(
    binary_found: bool,
    docker_host_set: bool,
    socket_exists: bool,
    daemon_reachable: bool,
) -> DockerStatus {
    if !binary_found && !docker_host_set && !socket_exists {
        return DockerStatus::NotInstalled;
    }
    if daemon_reachable {
        return DockerStatus::Available;
    }
    if !binary_found {
        return DockerStatus::NotInstalled;
    }
    DockerStatus::NotRunning
}

Then check_docker() gathers the booleans and delegates. This lets you test the decision table with zero I/O:

#[test]
fn test_resolve_status_dind() {
    // Socket exists, no binary, daemon up → Available (the DinD fix)
    assert_eq!(resolve_status(false, false, true, true), DockerStatus::Available);
}

#[test]
fn test_resolve_status_nothing_installed() {
    // No socket, no binary, no DOCKER_HOST → NotInstalled (fast path)
    assert_eq!(resolve_status(false, false, false, false), DockerStatus::NotInstalled);
}

#[test]
fn test_resolve_status_daemon_down() {
    // Binary exists, daemon unreachable → NotRunning
    assert_eq!(resolve_status(true, false, false, false), DockerStatus::NotRunning);
}

Non-blocking — the code is correct as-is, but this would give good regression coverage for the new logic with minimal effort.

This was referenced Apr 16, 2026
@henrypark133 henrypark133 mentioned this pull request Apr 21, 2026
theredspoon pushed a commit to theredspoon/ironclaw that referenced this pull request Jun 21, 2026
* fix(sandbox): try Docker socket before CLI binary check

The sandbox detection checked `which docker` first and returned
NotInstalled if the CLI binary was absent — even when the Docker
daemon was reachable via a bind-mounted socket. This broke
container-in-container deployments (e.g., Nomad shards with
/var/run/docker.sock mounted) where bollard can talk to the daemon
but no CLI is installed in the slim image.

Reorder check_docker() to try connect_docker() (bollard socket ping)
first. If the daemon responds, return Available immediately. The CLI
check is now only used as a fallback for error-message quality when
the socket connection fails.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(sandbox): skip slow daemon ping when Docker is clearly absent

check_docker() called connect_docker() before checking whether Docker
was even present, causing a 120s bollard timeout on hosts with an
unreachable DOCKER_HOST and no Docker installation. Add a fast-path
that checks for the docker binary, DOCKER_HOST env var, and socket
files on disk before attempting the daemon ping. This preserves DinD
support (bind-mounted socket, no CLI binary) while avoiding the
latency regression for non-Docker hosts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test(sandbox): add regression tests for check_docker fast-path

Extract should_skip_daemon_ping() predicate from check_docker() and
add unit tests covering all combinations: skip when no binary, no
DOCKER_HOST, and no socket (the bug scenario); no skip when any of
the three signals is present (DinD socket, DOCKER_HOST, CLI binary).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: new First-time contributor risk: medium Business logic, config, or moderate-risk modules scope: sandbox Docker sandbox size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants