From f2646ee9ab7be7e8ca1814aea5bdad1050fd3b2a Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Jun 2026 11:41:59 +0000 Subject: [PATCH 1/2] Initial commit with task details Adding .gitkeep for PR creation (default mode). This file will be removed when the task is complete. Issue: https://github.com/link-foundation/box/issues/102 --- .gitkeep | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitkeep diff --git a/.gitkeep b/.gitkeep new file mode 100644 index 0000000..e50def4 --- /dev/null +++ b/.gitkeep @@ -0,0 +1 @@ +# .gitkeep file auto-generated at 2026-06-13T11:41:58.991Z for PR creation at branch issue-102-ab755cee4bc5 for issue https://github.com/link-foundation/box/issues/102 \ No newline at end of file From 46209d2e16624842bb859388e5fa6fe47b3ba58c Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Jun 2026 11:45:27 +0000 Subject: [PATCH 2/2] dind-box: warn when host-image passthrough is opted into but no host socket is mounted (issue #102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Running box-dind with passthrough enabled (default `public`) and an explicit allowlist (`DIND_HOST_PASSTHROUGH_IMAGES=...`) but without the host Docker socket bind-mounted was a silent no-op: the entrypoint copied nothing, printed nothing, and the first nested `docker run` re-pulled the full image from the registry with no hint why. Downstream this silently re-pulled a 30+ GB image because of a forgotten `-v` flag (link-assistant/hive-mind#1914). A non-empty `DIND_HOST_PASSTHROUGH_IMAGES` is an unambiguous opt-in signal, so `passthrough_host_images` now emits one actionable warning in exactly that case — enabled passthrough + allowlist set + no socket mounted — naming the missing `-v /var/run/docker.sock:${DIND_HOST_DOCKER_SOCK}:ro` mount. The present-but-unreachable socket path already warned and still wins (its more specific message fires first); plain box-dind containers that never set an allowlist stay silent so the default mode is not spammed. Covered by new unit cases (8b/8c) in experiments/preload-unit-test.sh and an integration case in tests/dind/example-preload-images.sh; documented in docs/dind/USAGE.md. Adds a patch changeset. --- ...-102-passthrough-missing-socket-warning.md | 22 +++++++++++++++ .gitkeep | 1 - docs/dind/USAGE.md | 8 ++++++ experiments/preload-unit-test.sh | 27 +++++++++++++++++++ tests/dind/example-preload-images.sh | 19 +++++++++++++ ubuntu/24.04/dind/dind-entrypoint.sh | 10 +++++-- 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 .changeset/issue-102-passthrough-missing-socket-warning.md delete mode 100644 .gitkeep diff --git a/.changeset/issue-102-passthrough-missing-socket-warning.md b/.changeset/issue-102-passthrough-missing-socket-warning.md new file mode 100644 index 0000000..273ebaa --- /dev/null +++ b/.changeset/issue-102-passthrough-missing-socket-warning.md @@ -0,0 +1,22 @@ +--- +bump: patch +--- + +dind-box: warn when host-image passthrough is opted into but no host socket is +mounted (issue #102). + +Running `box-dind` with passthrough enabled (the default `public` mode) **and** +an explicit allowlist (`DIND_HOST_PASSTHROUGH_IMAGES=...`) but **without** the +host Docker socket bind-mounted used to be a silent no-op: the entrypoint copied +nothing, printed nothing, and the first nested `docker run` re-pulled the full +image from the registry with no hint why. Downstream this re-pulled a 30+ GB +image because of a forgotten `-v` flag (`link-assistant/hive-mind#1914`). + +A non-empty `DIND_HOST_PASSTHROUGH_IMAGES` is an unambiguous opt-in signal, so +`passthrough_host_images` now emits a single actionable warning in exactly that +case — enabled passthrough + allowlist set + no socket mounted — naming the +missing `-v /var/run/docker.sock:${DIND_HOST_DOCKER_SOCK}:ro` mount. The +present-but-unreachable socket already warned and still does; plain `box-dind` +containers that never set an allowlist stay silent so the default mode is not +spammed. Covered by new cases in `experiments/preload-unit-test.sh` and +documented in `docs/dind/USAGE.md`. diff --git a/.gitkeep b/.gitkeep deleted file mode 100644 index e50def4..0000000 --- a/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -# .gitkeep file auto-generated at 2026-06-13T11:41:58.991Z for PR creation at branch issue-102-ab755cee4bc5 for issue https://github.com/link-foundation/box/issues/102 \ No newline at end of file diff --git a/docs/dind/USAGE.md b/docs/dind/USAGE.md index 114a898..c9f4557 100644 --- a/docs/dind/USAGE.md +++ b/docs/dind/USAGE.md @@ -263,6 +263,14 @@ gate, `public` mode still refuses a locally-built or private image even when it matches a pattern — the allowlist only ever *narrows* the eligible set, it never widens it past the security filter. +Setting `DIND_HOST_PASSTHROUGH_IMAGES` is an unambiguous "I expect these images +passed through" signal. So if it is set but **no host socket is mounted**, the +entrypoint no longer stays silent — it emits a single warning naming the +missing `-v /var/run/docker.sock:/var/run/host-docker.sock:ro` mount, because +the nested daemon will otherwise re-pull from the registry on the first +`docker run` with no hint as to why (issue #102). Plain `box-dind` containers +that never set an allowlist still see no extra noise when no socket is mounted. + ## Commit Cycles `DIND_SKIP_DAEMON=1` is useful for setup containers where you want to install or diff --git a/experiments/preload-unit-test.sh b/experiments/preload-unit-test.sh index 8cb700d..b251fc1 100755 --- a/experiments/preload-unit-test.sh +++ b/experiments/preload-unit-test.sh @@ -150,6 +150,33 @@ DIND_HOST_PASSTHROUGH=public DIND_HOST_DOCKER_SOCK="$WORK/absent.sock" \ check "no host save attempted without a socket" bash -c '! test -s "$DOCKER_SAVED"' check "no warning emitted when socket simply absent" bash -c '! test -s "$WORK/err.log"' +echo "== Case 8b: explicit allowlist + absent socket warns about the missing mount (issue #102) ==" +reset_state +# The operator named the images they expect passed through, but forgot the +# host-socket mount. That opt-in signal turns the otherwise-silent no-op into a +# single actionable warning. +DIND_HOST_PASSTHROUGH=public DIND_HOST_DOCKER_SOCK="$WORK/absent.sock" \ + DIND_HOST_PASSTHROUGH_IMAGES="hello-world" \ + DIND_PRELOAD_TARBALL="" DIND_PRELOAD_IMAGES="" DOCKER_INFO_OK=1 \ + preload_into_daemon 2>"$WORK/err.log" +check "no host save attempted without a socket" bash -c '! test -s "$DOCKER_SAVED"' +check "warning names DIND_HOST_PASSTHROUGH_IMAGES" grep -q "DIND_HOST_PASSTHROUGH_IMAGES is set" "$WORK/err.log" +check "warning suggests the -v mount remediation" grep -q -- "-v /var/run/docker.sock:" "$WORK/err.log" + +echo "== Case 8c: present-but-unreachable socket still wins over the allowlist warning ==" +reset_state +# When a socket file exists but is unreachable, the original (more specific) +# "not accessible" warning fires — even with an allowlist set — and the generic +# missing-mount hint does not. +touch "$WORK/dead.sock" +DIND_HOST_PASSTHROUGH=public DIND_HOST_DOCKER_SOCK="$WORK/dead.sock" \ + DIND_HOST_PASSTHROUGH_IMAGES="hello-world" \ + DIND_PRELOAD_TARBALL="" DIND_PRELOAD_IMAGES="" DOCKER_INFO_OK=1 HOST_DOCKER_OK=0 \ + preload_into_daemon 2>"$WORK/err.log" +check "unreachable-socket warning fires" grep -q "is not accessible; skipping passthrough" "$WORK/err.log" +check "missing-mount hint suppressed when a socket file exists" bash -c '! grep -q "DIND_HOST_PASSTHROUGH_IMAGES is set" "$WORK/err.log"' +rm -f "$WORK/dead.sock" + echo "== Case 9: public mode copies a Docker Hub image, skips a local one ==" reset_state # A hub image (has a docker.io RepoDigest) and a locally-built one (no digest): diff --git a/tests/dind/example-preload-images.sh b/tests/dind/example-preload-images.sh index b3c22ac..a1968f5 100755 --- a/tests/dind/example-preload-images.sh +++ b/tests/dind/example-preload-images.sh @@ -228,4 +228,23 @@ if ! docker logs "$images_container" 2>&1 | grep -q "images=${fixture_repo}"; th fi log "images-allowlist passthrough copied only the named repo and skipped the rest" +# --- Opt-in allowlist but no host socket mounted (issue #102) --------------- +# Setting DIND_HOST_PASSTHROUGH_IMAGES is an unambiguous "pass these through" +# signal. If the operator forgets the `-v` socket mount, passthrough used to be +# a silent no-op and the first nested `docker run` re-pulled from the registry +# with no hint why. The entrypoint must now surface a single actionable warning +# naming the missing mount. Note: NO -v host-sock mount here, on purpose. +no_sock_container="${DIND_EXAMPLE_ID}-passthrough-no-sock" +log "starting consumer with DIND_HOST_PASSTHROUGH_IMAGES set but NO host socket mounted" +run_dind_container "$no_sock_container" \ + -e DIND_HOST_PASSTHROUGH=public \ + -e "DIND_HOST_PASSTHROUGH_IMAGES=$fixture_repo" +wait_for_inner_docker "$no_sock_container" +wait_for_preload_complete "$no_sock_container" +if ! docker logs "$no_sock_container" 2>&1 | grep -q "DIND_HOST_PASSTHROUGH_IMAGES is set, but no host docker socket is mounted"; then + docker logs "$no_sock_container" >&2 || true + fail "expected a warning when DIND_HOST_PASSTHROUGH_IMAGES is set but no host socket is mounted" +fi +log "missing-socket warning surfaced the forgotten -v mount instead of failing silently" + log "preload example passed" diff --git a/ubuntu/24.04/dind/dind-entrypoint.sh b/ubuntu/24.04/dind/dind-entrypoint.sh index 3d4987d..44b7907 100644 --- a/ubuntu/24.04/dind/dind-entrypoint.sh +++ b/ubuntu/24.04/dind/dind-entrypoint.sh @@ -399,11 +399,17 @@ passthrough_host_images() { host_passthrough_enabled || return 0 if ! host_docker_available; then - # A socket file exists but is unreachable: surface it. Otherwise the common - # "no host socket mounted" case stays silent so the default mode is free. if [ -n "$DIND_HOST_DOCKER_SOCK" ] && [ -e "$DIND_HOST_DOCKER_SOCK" ]; then + # A socket file exists but is unreachable: surface it. warn "host docker socket at ${DIND_HOST_DOCKER_SOCK} is not accessible; skipping passthrough" + elif [ -n "$DIND_HOST_PASSTHROUGH_IMAGES" ]; then + # Operator opted in via an allowlist but no host socket is mounted: the + # nested daemon will NOT be seeded and the first nested 'docker run' will + # re-pull from the registry. Surface it instead of failing silently. (issue #102) + warn "host-image passthrough is enabled and DIND_HOST_PASSTHROUGH_IMAGES is set, but no host docker socket is mounted at ${DIND_HOST_DOCKER_SOCK}; the nested daemon will NOT be seeded from the host (first 'docker run' will pull from the registry). Mount it with: -v /var/run/docker.sock:${DIND_HOST_DOCKER_SOCK}:ro" fi + # Otherwise (no opt-in signal) the common "no host socket mounted" case stays + # silent so plain box-dind containers are not spammed. return 0 fi