#!/usr/bin/env bash # Run integration tests against the latest docker-ce dind set -eu -o pipefail source ./scripts/build/.variables container_ip() { local cid=$1 local network=$2 docker inspect \ -f "{{.NetworkSettings.Networks.${network}.IPAddress}}" "$cid" } fetch_images() { ./scripts/test/e2e/load-image fetch-only } setup() { local project=$1 local file=$2 if [ "${TEST_CONNHELPER:-}" = "ssh" ];then test ! -f "${HOME}/.ssh/id_rsa" && ssh-keygen -t rsa -C docker-e2e-dummy -N "" -f "${HOME}/.ssh/id_rsa" -q grep "^StrictHostKeyChecking no" "${HOME}/.ssh/config" > /dev/null 2>&1 || echo "StrictHostKeyChecking no" > "${HOME}/.ssh/config" TEST_CONNHELPER_SSH_ID_RSA_PUB=$(cat "${HOME}/.ssh/id_rsa.pub") export TEST_CONNHELPER_SSH_ID_RSA_PUB file="${file}:./e2e/compose-env.connhelper-ssh.yaml" fi # Generate TLS certificates for the TLS-enabled private registry. # The certs are baked into the tlsregistry and engine container images, # so they must exist on disk before docker compose up --build. # gen-certs.sh handles its own directory navigation. certdir=e2e/testdata/registry/certs missing=0 for f in ca.crt ca.key tlsregistry.crt tlsregistry.key; do if [ ! -f "${certdir}/${f}" ]; then missing=1 break fi done if [ "$missing" -eq 1 ]; then sh e2e/testdata/registry/certs/gen-certs.sh fi COMPOSE_PROJECT_NAME=$project COMPOSE_FILE=$file docker compose up --build -d >&2 # Ensure supporting services exist before running tests. If one fails to start, # fail fast and surface logs instead of waiting on downstream DNS timeouts. local deadline=$((SECONDS + 120)) while [ $SECONDS -lt $deadline ]; do local ok=1 for svc in registry privateregistry tlsregistry engine; do cid="$(COMPOSE_PROJECT_NAME=$project COMPOSE_FILE=$file docker compose ps -q "$svc" 2>/dev/null || true)" if [ -z "$cid" ]; then ok=0 break fi if ! docker inspect -f '{{.State.Running}}' "$cid" 2>/dev/null | grep -q true; then ok=0 break fi done if [ "$ok" -eq 1 ]; then break fi sleep 1 done if [ $SECONDS -ge $deadline ]; then echo "Timed out waiting for e2e services to start" >&2 COMPOSE_PROJECT_NAME=$project COMPOSE_FILE=$file docker compose ps >&2 || true for svc in registry privateregistry tlsregistry engine; do echo "--- logs: $svc ---" >&2 COMPOSE_PROJECT_NAME=$project COMPOSE_FILE=$file docker compose logs --no-color --tail=200 "$svc" >&2 || true done exit 1 fi local network="${project}_default" # TODO: only run if inside a container docker network connect "$network" "$(hostname)" engine_ip="$(container_ip "${project}-engine-1" "$network")" engine_host="tcp://$engine_ip:2375" if [ "${TEST_CONNHELPER:-}" = "ssh" ];then engine_host="ssh://penguin@${engine_ip}" fi ( export DOCKER_HOST="$engine_host" timeout 200 ./scripts/test/e2e/wait-on-daemon ./scripts/test/e2e/load-image is_swarm_enabled || docker swarm init ) >&2 echo "$engine_host" } is_swarm_enabled() { docker info 2> /dev/null | grep -q 'Swarm: active' } cleanup() { local project=$1 local network="${project}_default" docker network disconnect "$network" "$(hostname)" COMPOSE_PROJECT_NAME=$1 COMPOSE_FILE=$2 docker compose down -v --rmi local >&2 } runtests() { local engine_host=$1 # shellcheck disable=SC2086 env -i \ TEST_DOCKER_HOST="$engine_host" \ TEST_DOCKER_CERT_PATH="${DOCKER_CERT_PATH-}" \ TEST_REMOTE_DAEMON="${REMOTE_DAEMON-}" \ TEST_SKIP_PLUGIN_TESTS="${SKIP_PLUGIN_TESTS-}" \ GOPATH="$GOPATH" \ PATH="$PWD/build/:/usr/bin:/usr/local/bin:/usr/local/go/bin" \ HOME="$HOME" \ DOCKER_CLI_E2E_PLUGINS_EXTRA_DIRS="$PWD/build/plugins-linux-${GOARCH}" \ GO111MODULE=auto \ "$(command -v gotestsum)" -- ${TESTDIRS:-./e2e/...} ${TESTFLAGS-} } export unique_id="${E2E_UNIQUE_ID:-cliendtoendsuite}" compose_env_file=./e2e/compose-env.yaml cmd=${1-} case "$cmd" in setup) setup "$unique_id" "$compose_env_file" exit ;; cleanup) cleanup "$unique_id" "$compose_env_file" exit ;; fetch-images) fetch_images exit ;; test) engine_host=${2-} if [ -z "${engine_host}" ]; then echo "missing parameter docker engine host" echo "Usage: $0 test ENGINE_HOST" exit 3 fi runtests "$engine_host" ;; run|"") engine_host="$(setup "$unique_id" "$compose_env_file")" testexit=0 runtests "$engine_host" || testexit=$? cleanup "$unique_id" "$compose_env_file" exit $testexit ;; shell) $SHELL ;; *) echo "Unknown command: $cmd" echo "Usage: " echo " $0 [setup | cleanup | test | run] [engine_host]" exit 1 ;; esac