fix(ci): support digest-verified runner mirrors
ci / verify (pull_request) Failing after 7m54s

This commit is contained in:
2026-07-17 14:50:38 +08:00
parent 6ba46514c1
commit 1f8c5a3d03
3 changed files with 47 additions and 12 deletions
+34 -9
View File
@@ -25,6 +25,8 @@ COMPOSE_SHA256=f9ebc6ebdb19d769b793c245a736caaeb198c62587f13b25c660c13b4987f959
PNPM_VERSION=10.18.1
RUNNER_IMAGE='docker.io/gitea/runner:2.0.0-dind-rootless@sha256:5b7b625ff773d0ee761788c47582503ec1b241fa5b81edebad48a57e663f4f3a'
JOB_IMAGE='docker.io/library/node:24.16.0-bookworm@sha256:40ad9f3064e67d6860b4bc3fe1880b2953934fd6320ada990e45fe0efa6badd7'
RUNNER_IMAGE_SOURCE=${CI_RUNNER_IMAGE_SOURCE:-$RUNNER_IMAGE}
NESTED_DOCKER_REGISTRY_MIRROR=${CI_NESTED_DOCKER_REGISTRY_MIRROR:-}
RUNNER_LABEL="easyai-gateway-ci-unprivileged-v2:docker://$JOB_IMAGE"
fail() {
@@ -47,6 +49,16 @@ case $RUNNER_IMAGE in
*"/runner:${GITEA_RUNNER_VERSION}-dind-rootless@sha256:"*) ;;
*) fail "RUNNER_IMAGE does not match GITEA_RUNNER_VERSION" ;;
esac
runner_manifest_digest=${RUNNER_IMAGE##*@}
case $RUNNER_IMAGE_SOURCE in
*@"$runner_manifest_digest") ;;
*) fail "CI_RUNNER_IMAGE_SOURCE must use the pinned runner manifest digest" ;;
esac
if [ -n "$NESTED_DOCKER_REGISTRY_MIRROR" ] && \
! printf '%s\n' "$NESTED_DOCKER_REGISTRY_MIRROR" | \
grep -Eq '^https://[A-Za-z0-9.-]+(:[0-9]+)?$'; then
fail "CI_NESTED_DOCKER_REGISTRY_MIRROR must be an HTTPS registry origin"
fi
command -v docker >/dev/null 2>&1 || fail "Docker Engine is required"
docker info >/dev/null 2>&1 || fail "Docker Engine is not reachable"
grep -Fq "\"$RUNNER_LABEL\"" "$ROOT/deploy/ci/act-runner-v2-config.yaml" || \
@@ -176,10 +188,22 @@ chown -R root:root "$PREFIX"
chmod -R go-w "$PREFIX"
require_free_space "$MIN_FREE_GIB" "runner image pull"
docker pull "$RUNNER_IMAGE"
docker pull "$RUNNER_IMAGE_SOURCE"
runner_runtime_image=$(docker image inspect --format '{{.Id}}' "$RUNNER_IMAGE_SOURCE")
printf '%s\n' "$runner_runtime_image" | grep -Eq '^sha256:[0-9a-f]{64}$' || \
fail "pinned runner image did not resolve to an immutable local image ID"
require_free_space "$MIN_POST_INSTALL_FREE_GIB" "completed runner image pull"
docker volume create "$RUNNER_VOLUME" >/dev/null
install -d -m 0755 /etc/easyai-gateway-ci-v2
if [ -n "$NESTED_DOCKER_REGISTRY_MIRROR" ]; then
printf '{"registry-mirrors":["%s"]}\n' "$NESTED_DOCKER_REGISTRY_MIRROR" \
> /etc/easyai-gateway-ci-v2/daemon.json
else
printf '{}\n' > /etc/easyai-gateway-ci-v2/daemon.json
fi
chmod 0644 /etc/easyai-gateway-ci-v2/daemon.json
# Docker's official rootless DinD baseline is --privileged. Gitea's example
# additionally names an AppArmor profile, but Docker does not create that host
# profile. Enable it only when this daemon proves it can start the pinned image
@@ -187,7 +211,7 @@ docker volume create "$RUNNER_VOLUME" >/dev/null
RUNNER_SECURITY_OPTIONS=
if docker run --rm --pull=never --privileged \
--security-opt apparmor=rootlesskit \
--entrypoint /bin/true "$RUNNER_IMAGE" >/dev/null 2>&1; then
--entrypoint /bin/true "$runner_runtime_image" >/dev/null 2>&1; then
RUNNER_SECURITY_OPTIONS="--security-opt=apparmor=rootlesskit"
elif [ -r /proc/sys/kernel/apparmor_restrict_unprivileged_userns ] && \
[ "$(cat /proc/sys/kernel/apparmor_restrict_unprivileged_userns)" = "1" ]; then
@@ -211,10 +235,11 @@ else
fi
docker run --detach --rm --pull=never \
--name "$PROBE_CONTAINER" --privileged --pids-limit 4096 "$@" \
--volume /etc/easyai-gateway-ci-v2/daemon.json:/home/rootless/.config/docker/daemon.json:ro \
--env DOCKERD_ROOTLESS_ROOTLESSKIT_NET=slirp4netns \
--env DOCKERD_ROOTLESS_ROOTLESSKIT_MTU=65520 \
--env DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=--pidns \
--entrypoint dockerd-entrypoint.sh "$RUNNER_IMAGE" >/dev/null
--entrypoint dockerd-entrypoint.sh "$runner_runtime_image" >/dev/null
attempt=0
until docker exec "$PROBE_CONTAINER" docker info >/dev/null 2>&1; do
attempt=$((attempt + 1))
@@ -232,10 +257,10 @@ docker exec "$PROBE_CONTAINER" docker info --format '{{range .SecurityOptions}}{
cleanup_probe
trap - EXIT HUP INT TERM
install -d -m 0755 /etc/easyai-gateway-ci-v2
install -m 0644 "$ROOT/deploy/ci/act-runner-v2-config.yaml" /etc/easyai-gateway-ci-v2/config.yaml
umask 077
printf 'RUNNER_SECURITY_OPTIONS="%s"\n' "$RUNNER_SECURITY_OPTIONS" \
printf 'RUNNER_SECURITY_OPTIONS="%s"\nRUNNER_IMAGE_REF="%s"\n' \
"$RUNNER_SECURITY_OPTIONS" "$runner_runtime_image" \
> /etc/easyai-gateway-ci-v2/runner.env
install -m 0644 "$ROOT/deploy/ci/easyai-gateway-ci-v2-runner.service" \
/etc/systemd/system/easyai-gateway-ci-v2-runner.service
@@ -244,13 +269,13 @@ install -m 0644 "$ROOT/deploy/ci/easyai-gateway-ci-v2-runner.service" \
# root, then register and operate the runner as that image's rootless user.
docker run --rm --pull=never --user 0:0 \
--volume "$RUNNER_VOLUME:/data" \
--entrypoint /bin/sh "$RUNNER_IMAGE" \
--entrypoint /bin/sh "$runner_runtime_image" \
-ec 'chown 1000:1000 /data && chmod 0700 /data'
runner_is_registered() {
docker run --rm --pull=never \
--volume "$RUNNER_VOLUME:/data" \
--entrypoint /bin/sh "$RUNNER_IMAGE" \
--entrypoint /bin/sh "$runner_runtime_image" \
-ec 'test -s /data/.runner'
}
@@ -265,12 +290,12 @@ if ! runner_is_registered; then
--volume /etc/easyai-gateway-ci-v2/config.yaml:/config.yaml:ro \
--env HOME=/data \
--entrypoint /usr/local/bin/gitea-runner \
"$RUNNER_IMAGE" --config /config.yaml register
"$runner_runtime_image" --config /config.yaml register
fi
unset RUNNER_REGISTRATION_TOKEN
docker run --rm --pull=never \
--volume "$RUNNER_VOLUME:/data" \
--entrypoint /bin/sh "$RUNNER_IMAGE" \
--entrypoint /bin/sh "$runner_runtime_image" \
-ec 'test -s /data/.runner && chmod 0600 /data/.runner'
RUNNER_VALIDATED=0