Skip to content

Fix e2e runner missing docker CLI on Debian trixie#20

Open
Copilot wants to merge 13 commits into
masterfrom
copilot/setup-e2e-test
Open

Fix e2e runner missing docker CLI on Debian trixie#20
Copilot wants to merge 13 commits into
masterfrom
copilot/setup-e2e-test

Conversation

Copilot AI commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

The e2e workflow failed because kind could not create its cluster inside the runner container:

ERROR: failed to create cluster: failed to get docker info:
command "docker info --format '{{json .}}'" failed with error:
exec: "docker": executable file not found in $PATH

On Debian trixie (the golang:1.26 base), the docker.io package ships only the daemon; the docker CLI now lives in the separate docker-cli package, which is merely a Recommends. Combined with --no-install-recommends, the CLI was never installed, while kind shells out to it.

Changes

  • e2e/Dockerfile.testrunner: install docker-cli instead of docker.io. The runner needs only the client, as it targets the mounted host /var/run/docker.sock rather than running its own daemon.
-    ... openssh-client curl ca-certificates docker.io ...
+    ... openssh-client curl ca-certificates docker-cli ...

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 16, 2026 18:45
Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
Copilot AI changed the title [WIP] Setup end-to-end testing framework Set up real docker-sshd e2e validation in CI Feb 16, 2026
Copilot AI requested a review from tg123 February 16, 2026 18:48
@tg123

tg123 commented Feb 16, 2026

Copy link
Copy Markdown
Owner

@copilot could you please take a look at https://github.com/tg123/sshpiper/tree/master/e2e
1 create a separate pipeline
2 use docker compose
3 kube still be covered as well

Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>

Copilot AI commented Feb 16, 2026

Copy link
Copy Markdown
Contributor Author

@copilot could you please take a look at https://github.com/tg123/sshpiper/tree/master/e2e
1 create a separate pipeline
2 use docker compose
...

Done in commit 3e740ad. I split e2e into a separate workflow (.github/workflows/e2e.yml), switched docker e2e setup to Docker Compose (.github/e2e/docker-compose.yml), and kept kube coverage in that e2e pipeline via the kube-sshd smoke check.

Copilot AI changed the title Set up real docker-sshd e2e validation in CI Set up dedicated CI e2e pipeline for docker-sshd with Docker Compose Feb 16, 2026
Comment thread e2e/docker-compose.yml
Copilot AI and others added 2 commits February 16, 2026 19:08
Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
Copilot AI changed the title Set up dedicated CI e2e pipeline for docker-sshd with Docker Compose Set up dedicated go test-based CI e2e pipeline for docker-sshd and kube-sshd Feb 16, 2026
Copilot AI requested a review from tg123 February 16, 2026 19:10
Comment thread .github/workflows/e2e.yml Outdated
- name: Build test binaries
run: |
mkdir -p /tmp/bin
go build -o /tmp/bin/docker-sshd ./cmd/docker-sshd

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@copilot move go build and go test into a container of docker compose, so users can test all by themselves

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 6d0c2c1. go build and go test now run inside the docker compose e2e-runner container (e2e/docker-compose.yml), and the workflow now invokes that compose runner after kind setup.

Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>

Copilot AI commented Feb 16, 2026

Copy link
Copy Markdown
Contributor Author

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Copilot AI changed the title Set up dedicated go test-based CI e2e pipeline for docker-sshd and kube-sshd Set up dedicated Docker Compose runner-based CI e2e pipeline for docker-sshd and kube-sshd Feb 16, 2026
Copilot AI requested a review from tg123 February 16, 2026 19:20
@tg123

tg123 commented Feb 16, 2026

Copy link
Copy Markdown
Owner

@copilot fix lint

Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>

Copilot AI commented Feb 16, 2026

Copy link
Copy Markdown
Contributor Author

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>

Copilot AI commented Feb 16, 2026

Copy link
Copy Markdown
Contributor Author

@copilot fix lint

Fixed in commit a5a1d8c. I addressed the lint failure by handling the kubectl cleanup error in e2e/e2e_test.go instead of ignoring the returned error value.

@tg123

tg123 commented Feb 16, 2026

Copy link
Copy Markdown
Owner

Lets setup kind inside docker compose to avoid host network

You can copy sshpiper kind setup @copilot

Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>

Copilot AI commented Feb 16, 2026

Copy link
Copy Markdown
Contributor Author

Lets setup kind inside docker compose to avoid host network

You can copy sshpiper kind setup @copilot

Implemented in commit 68cb597. I moved kind create/export/delete into the compose runner flow (based on the sshpiper approach), so e2e runs without host network dependency.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • kind.sigs.k8s.io
    • Triggering command: /usr/bin/curl curl -fsSL REDACTED -o /usr/local/bin/kind (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Set up dedicated Docker Compose runner-based CI e2e pipeline for docker-sshd and kube-sshd Set up dedicated Docker Compose runner-based CI e2e pipeline for docker-sshd and kube-sshd (with in-compose Kind) Feb 16, 2026
@tg123 tg123 marked this pull request as ready for review April 25, 2026 08:30
Copilot AI review requested due to automatic review settings April 25, 2026 08:30
@tg123

tg123 commented Apr 25, 2026

Copy link
Copy Markdown
Owner

@copilot fix e2e

Copilot AI 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.

Pull request overview

Sets up a dedicated, Docker Compose runner-based CI E2E pipeline for docker-sshd and kube-sshd, including spinning up a Kind Kubernetes cluster inside the compose runner.

Changes:

  • Added a new GitHub Actions workflow to run E2E via Docker Compose (.github/workflows/e2e.yml) and removed the previous E2E smoke checks from tests.yml.
  • Introduced compose-driven E2E orchestration under e2e/, including a dedicated test runner image and services.
  • Added Go-based E2E tests covering both the Docker and Kubernetes execution paths.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
e2e/e2e_test.go Adds Docker/Kubernetes E2E tests that start the binaries and verify SSH execution behavior.
e2e/docker-compose.yml Defines the compose services for an E2E target container and a privileged runner that builds binaries, creates Kind, and runs tests.
e2e/Dockerfile.testrunner Creates the runner image with Go, SSH client, Docker CLI, kubectl, and Kind.
.github/workflows/tests.yml Removes prior E2E smoke job, leaving unit tests only.
.github/workflows/e2e.yml Adds dedicated E2E workflow that runs compose-based E2E in CI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread e2e/e2e_test.go
Comment on lines +29 to +41
cmd := exec.Command(bin, "--address", "127.0.0.1", "--port", "2232", "--server-key", key)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
t.Fatalf("start docker-sshd: %v", err)
}
defer func() {
_ = cmd.Process.Kill()
_, _ = cmd.Process.Wait()
}()

out := retrySSH(t, "2232", container+"@127.0.0.1")
if !hasOKLine(out) {

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

The tests bind docker-sshd/kube-sshd to fixed ports 2232 and 2233. If those ports are already in use on the runner (or if tests ever run concurrently), the tests will fail even when the code is correct. Consider selecting an ephemeral free port (e.g., by binding a listener to 127.0.0.1:0, reading the chosen port, then starting the process with that port).

Copilot uses AI. Check for mistakes.
Comment thread e2e/docker-compose.yml
Comment on lines +14 to +31
environment:
- KUBECONFIG=/root/.kube/config
volumes:
- ..:/src
- /var/run/docker.sock:/var/run/docker.sock
- ${KUBECONFIG:-/tmp/invalid-kubeconfig-path}:/root/.kube/config:ro
command:
- /bin/sh
- -ec
- |
export GOFLAGS=-buildvcs=false
mkdir -p /tmp/bin
go build -o /tmp/bin/docker-sshd ./cmd/docker-sshd
go build -o /tmp/bin/kube-sshd ./cmd/kube-sshd
if [ "$${KUBE_SSHD_E2E:-1}" = "1" ]; then
kind get clusters | grep -qx docker-sshd-e2e || kind create cluster --name docker-sshd-e2e
kind export kubeconfig --name docker-sshd-e2e --internal
kubectl wait --for=condition=Ready pod -n kube-system --all --timeout=2m

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

kind export kubeconfig writes to $KUBECONFIG (set to /root/.kube/config), but that path is bind-mounted read-only from the host (:ro). On CI where KUBECONFIG is typically unset, Docker will also create /tmp/invalid-kubeconfig-path as a directory and mount it onto /root/.kube/config, which will cause kind export kubeconfig/kubectl to fail. Consider removing this volume mount by default (let the runner generate its own kubeconfig), or mount a writable file path and only override it via a separate compose override/profile for local runs.

Copilot uses AI. Check for mistakes.
Comment thread e2e/docker-compose.yml
Comment on lines +20 to +40
command:
- /bin/sh
- -ec
- |
export GOFLAGS=-buildvcs=false
mkdir -p /tmp/bin
go build -o /tmp/bin/docker-sshd ./cmd/docker-sshd
go build -o /tmp/bin/kube-sshd ./cmd/kube-sshd
if [ "$${KUBE_SSHD_E2E:-1}" = "1" ]; then
kind get clusters | grep -qx docker-sshd-e2e || kind create cluster --name docker-sshd-e2e
kind export kubeconfig --name docker-sshd-e2e --internal
kubectl wait --for=condition=Ready pod -n kube-system --all --timeout=2m
fi
DOCKER_SSHD_E2E=$${DOCKER_SSHD_E2E:-1} \
KUBE_SSHD_E2E=$${KUBE_SSHD_E2E:-1} \
DOCKER_SSHD_BIN=/tmp/bin/docker-sshd \
KUBE_SSHD_BIN=/tmp/bin/kube-sshd \
go test ./e2e -v
if [ "$${KUBE_SSHD_E2E:-1}" = "1" ]; then
kind delete cluster --name docker-sshd-e2e || true
fi

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

Because the shell runs with -e, if go test ./e2e fails the script will exit before the kind delete cluster block runs, leaving Kind containers/networks behind (especially noticeable on self-hosted/local runners). Use a trap inside this script to always delete the cluster on EXIT, or temporarily disable -e around go test and ensure cleanup runs in all cases.

Copilot uses AI. Check for mistakes.
Comment thread e2e/Dockerfile.testrunner
Comment on lines +2 to +6

RUN apt-get update && apt-get install -y --no-install-recommends openssh-client curl ca-certificates docker.io && rm -rf /var/lib/apt/lists/* \
&& curl -fsSL https://dl.k8s.io/release/v1.34.1/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl \
&& GOBIN=/usr/local/bin go install sigs.k8s.io/kind@v0.30.0 \
&& chmod +x /usr/local/bin/kubectl

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

The Dockerfile hardcodes downloading kubectl for linux/amd64, which will break the runner image build on ARM64 hosts (e.g., Apple Silicon) and any non-amd64 CI. Also, the direct curl download is not integrity-verified. Consider using ARG TARGETARCH (BuildKit) to select the correct kubectl binary, and verify the download via the published SHA256 (or install via a trusted package source).

Suggested change
RUN apt-get update && apt-get install -y --no-install-recommends openssh-client curl ca-certificates docker.io && rm -rf /var/lib/apt/lists/* \
&& curl -fsSL https://dl.k8s.io/release/v1.34.1/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl \
&& GOBIN=/usr/local/bin go install sigs.k8s.io/kind@v0.30.0 \
&& chmod +x /usr/local/bin/kubectl
ARG TARGETARCH
RUN apt-get update && apt-get install -y --no-install-recommends openssh-client curl ca-certificates docker.io && rm -rf /var/lib/apt/lists/* \
&& KUBECTL_VERSION=v1.34.1 \
&& KUBECTL_ARCH="${TARGETARCH:-amd64}" \
&& curl -fsSL "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${KUBECTL_ARCH}/kubectl" -o /tmp/kubectl \
&& curl -fsSL "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${KUBECTL_ARCH}/kubectl.sha256" -o /tmp/kubectl.sha256 \
&& echo "$(cat /tmp/kubectl.sha256) /tmp/kubectl" | sha256sum -c - \
&& install -m 0755 /tmp/kubectl /usr/local/bin/kubectl \
&& rm -f /tmp/kubectl /tmp/kubectl.sha256 \
&& GOBIN=/usr/local/bin go install sigs.k8s.io/kind@v0.30.0

Copilot uses AI. Check for mistakes.
Copilot AI changed the title Set up dedicated Docker Compose runner-based CI e2e pipeline for docker-sshd and kube-sshd (with in-compose Kind) Fix e2e runner missing docker CLI on Debian trixie Jun 13, 2026
Copilot finished work on behalf of tg123 June 13, 2026 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants