From 5b1987466d1d074460343f57318fd09e7657233e Mon Sep 17 00:00:00 2001 From: Kaniska Date: Wed, 27 May 2026 15:42:51 +0000 Subject: [PATCH 01/11] Check the tests --- test/docker-in-docker/docker_with_iptables.sh | 20 +++++++++++ .../docker_with_iptables_ubuntu.sh | 20 +++++++++++ .../docker_without_iptables.sh | 20 +++++++++++ .../docker_without_iptables_ubuntu.sh | 20 +++++++++++ test/docker-in-docker/scenarios.json | 36 +++++++++++++++++++ 5 files changed, 116 insertions(+) create mode 100644 test/docker-in-docker/docker_with_iptables.sh create mode 100644 test/docker-in-docker/docker_with_iptables_ubuntu.sh create mode 100644 test/docker-in-docker/docker_without_iptables.sh create mode 100644 test/docker-in-docker/docker_without_iptables_ubuntu.sh diff --git a/test/docker-in-docker/docker_with_iptables.sh b/test/docker-in-docker/docker_with_iptables.sh new file mode 100644 index 000000000..e29e10146 --- /dev/null +++ b/test/docker-in-docker/docker_with_iptables.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Feature specific tests +check "iptables works" sudo iptables -L +check "iptables uses legacy" bash -c "iptables --version | grep legacy" + +check "version" docker --version +check "docker-ps" bash -c "docker ps" +check "log-exists" bash -c "ls /tmp/dockerd.log" +check "log-for-completion" bash -c "cat /tmp/dockerd.log | grep 'Daemon has completed initialization'" +check "log-contents" bash -c "cat /tmp/dockerd.log | grep 'API listen on /var/run/docker.sock'" + +# Report result +reportResults + diff --git a/test/docker-in-docker/docker_with_iptables_ubuntu.sh b/test/docker-in-docker/docker_with_iptables_ubuntu.sh new file mode 100644 index 000000000..e29e10146 --- /dev/null +++ b/test/docker-in-docker/docker_with_iptables_ubuntu.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Feature specific tests +check "iptables works" sudo iptables -L +check "iptables uses legacy" bash -c "iptables --version | grep legacy" + +check "version" docker --version +check "docker-ps" bash -c "docker ps" +check "log-exists" bash -c "ls /tmp/dockerd.log" +check "log-for-completion" bash -c "cat /tmp/dockerd.log | grep 'Daemon has completed initialization'" +check "log-contents" bash -c "cat /tmp/dockerd.log | grep 'API listen on /var/run/docker.sock'" + +# Report result +reportResults + diff --git a/test/docker-in-docker/docker_without_iptables.sh b/test/docker-in-docker/docker_without_iptables.sh new file mode 100644 index 000000000..6d2dab04c --- /dev/null +++ b/test/docker-in-docker/docker_without_iptables.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Feature specific tests +check "iptables works" sudo iptables -L +check "iptables uses nf_tables" bash -c "iptables --version | grep nf_tables" + +check "version" docker --version +check "docker-ps" bash -c "docker ps" +check "log-exists" bash -c "ls /tmp/dockerd.log" +check "log-for-completion" bash -c "cat /tmp/dockerd.log | grep 'Daemon has completed initialization'" +check "log-contents" bash -c "cat /tmp/dockerd.log | grep 'API listen on /var/run/docker.sock'" + +# Report result +reportResults + diff --git a/test/docker-in-docker/docker_without_iptables_ubuntu.sh b/test/docker-in-docker/docker_without_iptables_ubuntu.sh new file mode 100644 index 000000000..6d2dab04c --- /dev/null +++ b/test/docker-in-docker/docker_without_iptables_ubuntu.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Feature specific tests +check "iptables works" sudo iptables -L +check "iptables uses nf_tables" bash -c "iptables --version | grep nf_tables" + +check "version" docker --version +check "docker-ps" bash -c "docker ps" +check "log-exists" bash -c "ls /tmp/dockerd.log" +check "log-for-completion" bash -c "cat /tmp/dockerd.log | grep 'Daemon has completed initialization'" +check "log-contents" bash -c "cat /tmp/dockerd.log | grep 'API listen on /var/run/docker.sock'" + +# Report result +reportResults + diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index 2f9df3958..497708f26 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -1,4 +1,40 @@ { + "docker_without_iptables": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "docker-in-docker": { + "moby": "false" + } + }, + "initializeCommand": "sudo modprobe --remove --remove-holders --wait 1000 ip_tables" + }, + "docker_with_iptables": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "docker-in-docker": { + "moby": "false" + } + }, + "initializeCommand": "sudo modprobe ip_tables" + }, + "docker_without_iptables_ubuntu": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "docker-in-docker": { + "moby": "false" + } + }, + "initializeCommand": "sudo modprobe --remove --remove-holders --wait 1000 ip_tables" + }, + "docker_with_iptables_ubuntu": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "docker-in-docker": { + "moby": "false" + } + }, + "initializeCommand": "sudo modprobe ip_tables" + }, "overlayfs_containerd_root": { "image": "mcr.microsoft.com/devcontainers/base:noble", "features": { From 4cad3da0237d854d7b0df43cdba2fdae46aefac0 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Wed, 27 May 2026 16:52:21 +0000 Subject: [PATCH 02/11] check the log --- test/docker-in-docker/docker_without_iptables.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/docker-in-docker/docker_without_iptables.sh b/test/docker-in-docker/docker_without_iptables.sh index 6d2dab04c..6ecaddc8d 100644 --- a/test/docker-in-docker/docker_without_iptables.sh +++ b/test/docker-in-docker/docker_without_iptables.sh @@ -6,6 +6,20 @@ set -e source dev-container-features-test-lib # Feature specific tests +check "docker-ps" bash -c "docker ps" +# Fail loudly if dockerd never finished initializing, printing the real error +check "dockerd-started-successfully" bash -c ' + if ! grep -q "Daemon has completed initialization" /tmp/dockerd.log; then + echo "❌ Docker daemon failed to start. Last errors from /tmp/dockerd.log:" + echo "----- dockerd.log (tail) -----" + tail -n 100 /tmp/dockerd.log + echo "----- error/fatal lines -----" + grep -iE "error|fatal|failed|panic" /tmp/dockerd.log || true + exit 1 + fi +' +check "log-for-completion" bash -c "cat /tmp/dockerd.log | grep 'Daemon has completed initialization'" + check "iptables works" sudo iptables -L check "iptables uses nf_tables" bash -c "iptables --version | grep nf_tables" From 43e9b833262b8b6745a1f73d3188bb7bfa0349c5 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Mon, 1 Jun 2026 15:18:35 +0000 Subject: [PATCH 03/11] Adding debug statements --- src/docker-in-docker/install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index e9740efc5..bd045eac5 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -323,12 +323,15 @@ if [ "${ADJUSTED_ID}" = "debian" ]; then esac if [ "${use_nft}" = "true" ] && type iptables-nft > /dev/null 2>&1; then + echo "(*) Setting iptables alternatives to nft for better compatibility with newer kernels" update-alternatives --set iptables /usr/sbin/iptables-nft || true update-alternatives --set ip6tables /usr/sbin/ip6tables-nft || true elif type iptables-legacy > /dev/null 2>&1; then + echo "(*) Setting iptables alternatives to legacy for better compatibility with Docker and older kernels" update-alternatives --set iptables /usr/sbin/iptables-legacy || true update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy || true elif type iptables-nft > /dev/null 2>&1; then + echo "(*) Setting iptables alternatives to nft for better compatibility with newer kernels for non resolute" update-alternatives --set iptables /usr/sbin/iptables-nft || true update-alternatives --set ip6tables /usr/sbin/ip6tables-nft || true fi From 6349dd24cb2f4d61f046e287230f0e2a4fe9bbe4 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Mon, 1 Jun 2026 16:11:51 +0000 Subject: [PATCH 04/11] Another change --- src/docker-in-docker/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index bd045eac5..94f574d1e 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -326,7 +326,7 @@ if [ "${ADJUSTED_ID}" = "debian" ]; then echo "(*) Setting iptables alternatives to nft for better compatibility with newer kernels" update-alternatives --set iptables /usr/sbin/iptables-nft || true update-alternatives --set ip6tables /usr/sbin/ip6tables-nft || true - elif type iptables-legacy > /dev/null 2>&1; then + elif type iptables-legacy > /dev/null 2>&1 && iptables-legacy -L > /dev/null 2>&1; then echo "(*) Setting iptables alternatives to legacy for better compatibility with Docker and older kernels" update-alternatives --set iptables /usr/sbin/iptables-legacy || true update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy || true From 3d7b7f081910df30d10bd325838ca9f8ebeab3d6 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Mon, 1 Jun 2026 17:05:58 +0000 Subject: [PATCH 05/11] Check in docker-init.sh --- src/docker-in-docker/install.sh | 56 +++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 94f574d1e..96c7586a9 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -314,28 +314,28 @@ if [ "${ADJUSTED_ID}" = "debian" ] && command -v update-ca-certificates > /dev/n fi # Swap to legacy iptables for compatibility (Debian only) -if [ "${ADJUSTED_ID}" = "debian" ]; then +#if [ "${ADJUSTED_ID}" = "debian" ]; then # On distros where legacy iptables is no longer kernel-supported (e.g. Ubuntu 26.04 / resolute), # prefer iptables-nft. Otherwise prefer legacy for backward compatibility. - use_nft=false - case "${VERSION_CODENAME}" in - resolute) use_nft=true ;; - esac - - if [ "${use_nft}" = "true" ] && type iptables-nft > /dev/null 2>&1; then - echo "(*) Setting iptables alternatives to nft for better compatibility with newer kernels" - update-alternatives --set iptables /usr/sbin/iptables-nft || true - update-alternatives --set ip6tables /usr/sbin/ip6tables-nft || true - elif type iptables-legacy > /dev/null 2>&1 && iptables-legacy -L > /dev/null 2>&1; then - echo "(*) Setting iptables alternatives to legacy for better compatibility with Docker and older kernels" - update-alternatives --set iptables /usr/sbin/iptables-legacy || true - update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy || true - elif type iptables-nft > /dev/null 2>&1; then - echo "(*) Setting iptables alternatives to nft for better compatibility with newer kernels for non resolute" - update-alternatives --set iptables /usr/sbin/iptables-nft || true - update-alternatives --set ip6tables /usr/sbin/ip6tables-nft || true - fi -fi +# use_nft=false +# case "${VERSION_CODENAME}" in +# resolute) use_nft=true ;; +# esac + +# if [ "${use_nft}" = "true" ] && type iptables-nft > /dev/null 2>&1; then +# echo "(*) Setting iptables alternatives to nft for better compatibility with newer kernels" +# update-alternatives --set iptables /usr/sbin/iptables-nft || true +# update-alternatives --set ip6tables /usr/sbin/ip6tables-nft || true +# elif type iptables-legacy > /dev/null 2>&1 && iptables-legacy -L > /dev/null 2>&1; then +# echo "(*) Setting iptables alternatives to legacy for better compatibility with Docker and older kernels" +# update-alternatives --set iptables /usr/sbin/iptables-legacy || true +# update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy || true +# elif type iptables-nft > /dev/null 2>&1; then +# echo "(*) Setting iptables alternatives to nft for better compatibility with newer kernels for non resolute" +# update-alternatives --set iptables /usr/sbin/iptables-nft || true +# update-alternatives --set ip6tables /usr/sbin/ip6tables-nft || true +# fi +#fi # Set up the necessary repositories if [ "${USE_MOBY}" = "true" ]; then @@ -973,6 +973,22 @@ DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} DOCKER_DEFAULT_IP6_TABLES=${DOCKER_DEFAULT_IP6_TABLES} EOF +# On Debian-based images, re-assert the iptables alternative at container start. +# The base image may have switched it after this feature ran, so we re-apply +# the preferred backend (legacy if functional, otherwise nft) before dockerd starts. +if [ "${ADJUSTED_ID}" = "debian" ]; then + tee -a /usr/local/share/docker-init.sh > /dev/null \ +<< 'EOF' +if type iptables-legacy > /dev/null 2>&1 && iptables-legacy -nL > /dev/null 2>&1; then + update-alternatives --set iptables /usr/sbin/iptables-legacy + update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy +elif type iptables-nft > /dev/null 2>&1; then + update-alternatives --set iptables /usr/sbin/iptables-nft + update-alternatives --set ip6tables /usr/sbin/ip6tables-nft +fi +EOF +fi + tee -a /usr/local/share/docker-init.sh > /dev/null \ << 'EOF' dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} DOCKER_DEFAULT_IP6_TABLES=${DOCKER_DEFAULT_IP6_TABLES} $(cat << 'INNEREOF' From 08c8731bee1ab6b75a65fb923ad6a5a674a598b8 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Tue, 2 Jun 2026 06:02:23 +0000 Subject: [PATCH 06/11] Change test order --- test/docker-in-docker/scenarios.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index 497708f26..982df5983 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -1,6 +1,6 @@ { - "docker_without_iptables": { - "image": "mcr.microsoft.com/devcontainers/base:debian", + "docker_without_iptables_ubuntu": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "features": { "docker-in-docker": { "moby": "false" @@ -8,17 +8,17 @@ }, "initializeCommand": "sudo modprobe --remove --remove-holders --wait 1000 ip_tables" }, - "docker_with_iptables": { - "image": "mcr.microsoft.com/devcontainers/base:debian", + "docker_with_iptables_ubuntu": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "features": { "docker-in-docker": { "moby": "false" } }, "initializeCommand": "sudo modprobe ip_tables" - }, - "docker_without_iptables_ubuntu": { - "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + }, + "docker_without_iptables": { + "image": "mcr.microsoft.com/devcontainers/base:debian", "features": { "docker-in-docker": { "moby": "false" @@ -26,15 +26,15 @@ }, "initializeCommand": "sudo modprobe --remove --remove-holders --wait 1000 ip_tables" }, - "docker_with_iptables_ubuntu": { - "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "docker_with_iptables": { + "image": "mcr.microsoft.com/devcontainers/base:debian", "features": { "docker-in-docker": { "moby": "false" } }, "initializeCommand": "sudo modprobe ip_tables" - }, + }, "overlayfs_containerd_root": { "image": "mcr.microsoft.com/devcontainers/base:noble", "features": { From a5838b2c005ba0a8e8ca82545b6a929943c48fd0 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Tue, 2 Jun 2026 06:51:32 +0000 Subject: [PATCH 07/11] Check the presence of the kernel module --- src/docker-in-docker/install.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 96c7586a9..ba6bb2bf7 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -974,16 +974,19 @@ DOCKER_DEFAULT_IP6_TABLES=${DOCKER_DEFAULT_IP6_TABLES} EOF # On Debian-based images, re-assert the iptables alternative at container start. -# The base image may have switched it after this feature ran, so we re-apply -# the preferred backend (legacy if functional, otherwise nft) before dockerd starts. if [ "${ADJUSTED_ID}" = "debian" ]; then tee -a /usr/local/share/docker-init.sh > /dev/null \ << 'EOF' -if type iptables-legacy > /dev/null 2>&1 && iptables-legacy -nL > /dev/null 2>&1; then - update-alternatives --set iptables /usr/sbin/iptables-legacy +# Prefer legacy only when the ip_tables kernel module is actually present. +# (Do NOT call `iptables-legacy -L/-nL` to test this — it auto-modprobes ip_tables +# and would defeat hosts/scenarios where the module is intentionally absent.) +if type iptables-legacy > /dev/null 2>&1 \ + && { grep -qE '^(ip_tables)\b' /proc/modules \ + || [ -d /sys/module/ip_tables ]; }; then + update-alternatives --set iptables /usr/sbin/iptables-legacy update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy elif type iptables-nft > /dev/null 2>&1; then - update-alternatives --set iptables /usr/sbin/iptables-nft + update-alternatives --set iptables /usr/sbin/iptables-nft update-alternatives --set ip6tables /usr/sbin/ip6tables-nft fi EOF From ef0ba8eb705cefa75378d74c31497aabfb85952d Mon Sep 17 00:00:00 2001 From: Kaniska Date: Tue, 2 Jun 2026 07:40:32 +0000 Subject: [PATCH 08/11] change the test execution order --- test/docker-in-docker/scenarios.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index 982df5983..497708f26 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -1,6 +1,6 @@ { - "docker_without_iptables_ubuntu": { - "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "docker_without_iptables": { + "image": "mcr.microsoft.com/devcontainers/base:debian", "features": { "docker-in-docker": { "moby": "false" @@ -8,17 +8,17 @@ }, "initializeCommand": "sudo modprobe --remove --remove-holders --wait 1000 ip_tables" }, - "docker_with_iptables_ubuntu": { - "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "docker_with_iptables": { + "image": "mcr.microsoft.com/devcontainers/base:debian", "features": { "docker-in-docker": { "moby": "false" } }, "initializeCommand": "sudo modprobe ip_tables" - }, - "docker_without_iptables": { - "image": "mcr.microsoft.com/devcontainers/base:debian", + }, + "docker_without_iptables_ubuntu": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "features": { "docker-in-docker": { "moby": "false" @@ -26,15 +26,15 @@ }, "initializeCommand": "sudo modprobe --remove --remove-holders --wait 1000 ip_tables" }, - "docker_with_iptables": { - "image": "mcr.microsoft.com/devcontainers/base:debian", + "docker_with_iptables_ubuntu": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "features": { "docker-in-docker": { "moby": "false" } }, "initializeCommand": "sudo modprobe ip_tables" - }, + }, "overlayfs_containerd_root": { "image": "mcr.microsoft.com/devcontainers/base:noble", "features": { From f0a10b4adfe688eaeea638a43cd83b0cea2964e4 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Tue, 2 Jun 2026 08:40:31 +0000 Subject: [PATCH 09/11] Changes in workflows --- .github/workflows/test-pr-arm64.yaml | 9 +++++++++ .github/workflows/test-pr.yaml | 29 ++++++++++++++++++++++++++++ src/docker-in-docker/install.sh | 14 ++++++++------ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test-pr-arm64.yaml b/.github/workflows/test-pr-arm64.yaml index e5855ced2..4e48da3e3 100644 --- a/.github/workflows/test-pr-arm64.yaml +++ b/.github/workflows/test-pr-arm64.yaml @@ -75,5 +75,14 @@ jobs: - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli + - name: "Exclude iptables-isolation scenarios from docker-in-docker" + if: matrix.features == 'docker-in-docker' + run: | + sudo apt-get update && sudo apt-get install -y jq + sed 's://.*$::' test/docker-in-docker/scenarios.json \ + | jq 'del(.docker_without_iptables, .docker_without_iptables_ubuntu)' \ + > test/docker-in-docker/scenarios.json.tmp + mv test/docker-in-docker/scenarios.json.tmp test/docker-in-docker/scenarios.json + - name: "Testing '${{ matrix.features }}' scenarios" run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated . diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index e00c50876..d74a5c3e5 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -92,5 +92,34 @@ jobs: - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli + - name: "Exclude iptables-isolation scenarios from docker-in-docker" + if: matrix.features == 'docker-in-docker' + run: | + sudo apt-get update && sudo apt-get install -y jq + sed 's://.*$::' test/docker-in-docker/scenarios.json \ + | jq 'del(.docker_without_iptables, .docker_without_iptables_ubuntu)' \ + > test/docker-in-docker/scenarios.json.tmp + mv test/docker-in-docker/scenarios.json.tmp test/docker-in-docker/scenarios.json + - name: "Testing '${{ matrix.features }}' scenarios" run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated . + + iptables-isolation: + needs: [detect-changes] + if: contains(fromJSON(needs.detect-changes.outputs.features), 'docker-in-docker') + runs-on: ubuntu-latest + continue-on-error: true + strategy: + fail-fast: false + matrix: + scenario: + - docker_without_iptables + - docker_without_iptables_ubuntu + steps: + - uses: actions/checkout@v6 + + - name: "Install latest devcontainer CLI" + run: npm install -g @devcontainers/cli + + - name: "Testing docker-in-docker scenario '${{ matrix.scenario }}'" + run: devcontainer features test --features docker-in-docker --filter ${{ matrix.scenario }} . diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index ba6bb2bf7..543e90055 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -982,12 +982,14 @@ if [ "${ADJUSTED_ID}" = "debian" ]; then # and would defeat hosts/scenarios where the module is intentionally absent.) if type iptables-legacy > /dev/null 2>&1 \ && { grep -qE '^(ip_tables)\b' /proc/modules \ - || [ -d /sys/module/ip_tables ]; }; then - update-alternatives --set iptables /usr/sbin/iptables-legacy - update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy -elif type iptables-nft > /dev/null 2>&1; then - update-alternatives --set iptables /usr/sbin/iptables-nft - update-alternatives --set ip6tables /usr/sbin/ip6tables-nft + || [ -d /sys/module/ip_tables ]; } \ + && update-alternatives --list iptables 2>/dev/null | grep -q '/usr/sbin/iptables-legacy'; then + update-alternatives --set iptables /usr/sbin/iptables-legacy || true + update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy || true +elif type iptables-nft > /dev/null 2>&1 \ + && update-alternatives --list iptables 2>/dev/null | grep -q '/usr/sbin/iptables-nft'; then + update-alternatives --set iptables /usr/sbin/iptables-nft || true + update-alternatives --set ip6tables /usr/sbin/ip6tables-nft || true fi EOF fi From c6a12a6e7ea61f751c6564958a7c08f88f92c2e1 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Tue, 2 Jun 2026 08:50:57 +0000 Subject: [PATCH 10/11] Change the test --- .github/workflows/test-pr.yaml | 2 +- src/docker-in-docker/devcontainer-feature.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index d74a5c3e5..c7ca51bd1 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -122,4 +122,4 @@ jobs: run: npm install -g @devcontainers/cli - name: "Testing docker-in-docker scenario '${{ matrix.scenario }}'" - run: devcontainer features test --features docker-in-docker --filter ${{ matrix.scenario }} . + run: devcontainer features test --features docker-in-docker --filter ${{ matrix.scenario }} --skip-autogenerated . diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 0af78923e..0c5259ac2 100644 --- a/src/docker-in-docker/devcontainer-feature.json +++ b/src/docker-in-docker/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "docker-in-docker", - "version": "3.0.1", + "version": "4.0.0", "name": "Docker (Docker-in-Docker)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-in-docker", "description": "Create child containers *inside* a container, independent from the host's docker instance. Installs Docker extension in the container along with needed CLIs.", From b8312b46d07c9fe0ca0d266afb88fa76ebb8dd30 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Tue, 2 Jun 2026 09:02:43 +0000 Subject: [PATCH 11/11] Further isolation --- .github/workflows/test-pr.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index c7ca51bd1..9a7edf13d 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -121,5 +121,13 @@ jobs: - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli + - name: "Isolate scenario '${{ matrix.scenario }}'" + run: | + sudo apt-get update && sudo apt-get install -y jq + sed 's://.*$::' test/docker-in-docker/scenarios.json \ + | jq '{ "${{ matrix.scenario }}": .["${{ matrix.scenario }}"] }' \ + > test/docker-in-docker/scenarios.json.tmp + mv test/docker-in-docker/scenarios.json.tmp test/docker-in-docker/scenarios.json + - name: "Testing docker-in-docker scenario '${{ matrix.scenario }}'" run: devcontainer features test --features docker-in-docker --filter ${{ matrix.scenario }} --skip-autogenerated .