#!/usr/bin/env bash # CI entrypoint for the source-install Docker/OpenSSH E2E matrix # (work package 5, docs/source-installation.md). # # Runs `make test-ssh` (Alpine/Ubuntu/Arch real OpenSSH fixtures over the # public network) inside a Docker-capable CI job. It: # - fails fast with a clear message when Docker is unreachable, because the # harness dials fixture SSH ports published on the daemon's loopback; # - runs the full fixture matrix with make's 60m go-test timeout; # - cleans up every leftover test container/network/fixture-image tag on # success AND failure, so an aborted job never leaks test material on the # runner. # # It never deletes a shared base image: only rsmon-worker-test-* resources and # the per-instance rsmon-worker-test/-:local tags the harness # owns are removed. set -euo pipefail # cleanup removes only resources the harness owns. Runs on every exit path. cleanup() { # Containers, then networks (which need no attached containers). Filters # are anchored to the harness's own prefix so a resource that merely # contains the substring is never touched. docker ps -aq --filter "name=^rsmon-worker-test-" 2>/dev/null \ | xargs -r docker rm -f >/dev/null 2>&1 || true docker network ls -q --filter "name=^rsmon-worker-test-" 2>/dev/null \ | xargs -r docker network rm >/dev/null 2>&1 || true # Per-instance fixture image tags only; never a shared base image. docker images -q --filter "reference=rsmon-worker-test/*" 2>/dev/null \ | xargs -r docker image rm -f >/dev/null 2>&1 || true } trap cleanup EXIT if ! command -v docker >/dev/null 2>&1; then echo "test-ssh CI: docker CLI not found; this job needs a Docker-capable runner" >&2 exit 1 fi if ! docker info >/dev/null 2>&1; then echo "test-ssh CI: Docker daemon is not reachable; this job needs a working Docker daemon" >&2 exit 1 fi echo "test-ssh CI: Docker $(docker version --format '{{.Server.Version}}' 2>/dev/null || echo n/a) ready" # The harness publishes fixture SSH ports to the daemon's 127.0.0.1 and # dials them from the test process, so the job must share the daemon's # loopback. Probe that cheaply (no Go, no fixture build) before the heavy # matrix so a misconfigured runner fails fast instead of after 60m. cid="$(docker run -d --name rsmon-worker-test-preflight \ -p 127.0.0.1::22 reg.rsxx.ru/library/alpine:3 sleep 300)" port="$(docker port "$cid" 22/tcp 2>/dev/null | sed -n 's#.*:##p' | head -n1)" if [ -z "$port" ] || ! (exec 3<>"/dev/tcp/127.0.0.1/${port}") 2>/dev/null; then cat >&2 < from the test process, so the job and the Docker daemon must share a loopback network namespace. Fix (pick one): 1. Run this workflow on a host-mode runner (act_runner job executing on the host with the local Docker daemon), OR 2. Give the job container host networking with the Docker socket mounted (e.g. container options: --network host plus /var/run/docker.sock), OR 3. Run \`make test-ssh\` directly on a machine with a local Docker daemon. Diagnostics: docker server: $(docker version --format '{{.Server.Version}}' 2>/dev/null || echo unknown) published port: ${port:-none} EOF exit 1 fi exec 3>&- 2>/dev/null || true echo "test-ssh CI: loopback port publishing verified; running the Alpine/Ubuntu/Arch matrix" make test-ssh