From 1107152fe071ededafd5377302b42bb9a9614794 Mon Sep 17 00:00:00 2001 From: mrL <1417558386@qq.com> Date: Fri, 14 Aug 2026 00:51:52 +0800 Subject: [PATCH 1/3] ci: add GPU runner overlay2 smoke test and CPU runner sample config - gpu-runner-overlay2-smoke.yml: workflow_dispatch probe validating Docker storage driver (overlay2), cold/warm image pull timings, and nvidia-smi GPU visibility inside ghcr.io/deepmodeling/abacus-cuda image - cpu-runner-overlay2-sample.yaml: K8s RunnerDeployment sample (ACK/ECI) switching docker daemon storage driver from vfs to overlay2 Note: smoke workflow expects overlay2; on the current vfs runner it will fail at the storage-driver check by design. --- .../workflows/cpu-runner-overlay2-sample.yaml | 60 +++++++++ .../workflows/gpu-runner-overlay2-smoke.yml | 118 ++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 .github/workflows/cpu-runner-overlay2-sample.yaml create mode 100644 .github/workflows/gpu-runner-overlay2-smoke.yml diff --git a/.github/workflows/cpu-runner-overlay2-sample.yaml b/.github/workflows/cpu-runner-overlay2-sample.yaml new file mode 100644 index 0000000000..b64d39e138 --- /dev/null +++ b/.github/workflows/cpu-runner-overlay2-sample.yaml @@ -0,0 +1,60 @@ +# CPU GitHub Actions Runner sample for ACK/ECI. +apiVersion: v1 +kind: ConfigMap +metadata: + name: docker-daemon-cpu-overlay2 + namespace: actions-runner-system +data: + daemon.json: | + { + "storage-driver": "overlay2", + "log-driver": "json-file", + "log-opts": { + "max-size": "10m", + "max-file": "3" + } + } +--- +apiVersion: actions.summerwind.dev/v1alpha1 +kind: RunnerDeployment +metadata: + name: cpu-runner + namespace: actions-runner-system +spec: + template: + metadata: + annotations: + k8s.aliyun.com/eci-auto-imc: "true" + k8s.aliyun.com/imc-perfect-match: "true" + k8s.aliyun.com/eci-extra-ephemeral-storage: "120Gi" + k8s.aliyun.com/eci-schedule-strategy: VSwitchOrdered + k8s.aliyun.com/eci-use-specs: ecs.c6.2xlarge + spec: + organization: deepmodeling + labels: + - cpu + - self-hosted + - linux-x64 + ephemeral: true + image: summerwind/actions-runner@sha256:ac52790f2737b2ef1be90a6708280cf2f0b2cf838f421ee7cce42d7511951976 + imagePullPolicy: IfNotPresent + dockerEnabled: true + dockerVolumeMounts: + - name: docker-config + mountPath: /etc/docker/daemon.json + subPath: daemon.json + - name: docker-storage + mountPath: /var/lib/docker + volumes: + - name: docker-config + configMap: + name: docker-daemon-cpu-overlay2 + - name: docker-storage + emptyDir: {} + nodeSelector: + type: virtual-kubelet + tolerations: + - key: virtual-kubelet.io/provider + operator: Equal + value: alibabacloud + effect: NoSchedule diff --git a/.github/workflows/gpu-runner-overlay2-smoke.yml b/.github/workflows/gpu-runner-overlay2-smoke.yml new file mode 100644 index 0000000000..574c17c268 --- /dev/null +++ b/.github/workflows/gpu-runner-overlay2-smoke.yml @@ -0,0 +1,118 @@ +name: GPU Runner overlay2 smoke test + +on: + workflow_dispatch: + inputs: + image: + description: Container image used for the pull and GPU test + required: true + default: ghcr.io/deepmodeling/abacus-cuda:latest + type: string + +permissions: + contents: read + +concurrency: + group: gpu-runner-overlay2-smoke + cancel-in-progress: false + +jobs: + gpu-runner-smoke: + name: Validate overlay2, image pull, and GPU + runs-on: + - self-hosted + - gpu + - linux-x64 + timeout-minutes: 30 + env: + TEST_IMAGE: ${{ inputs.image }} + + steps: + - name: Verify Docker storage driver + shell: bash + run: | + set -euo pipefail + + driver="$(docker info --format '{{.Driver}}')" + docker_root="$(docker info --format '{{.DockerRootDir}}')" + driver_status="$(docker info --format '{{json .DriverStatus}}')" + + echo "Docker storage driver: ${driver}" + echo "Docker root: ${docker_root}" + echo "Driver status: ${driver_status}" + + { + echo "## GPU Runner smoke test" + echo + echo "- Runner: \`${RUNNER_NAME}\`" + echo "- Docker driver: \`${driver}\`" + echo "- Docker root: \`${docker_root}\`" + echo "- Test image: \`${TEST_IMAGE}\`" + } >> "${GITHUB_STEP_SUMMARY}" + + if [[ "${driver}" != "overlay2" ]]; then + echo "Expected Docker storage driver overlay2, got ${driver}." >&2 + exit 1 + fi + + - name: Pull test image and measure cold-pull time + id: cold_pull + shell: bash + run: | + set -euo pipefail + + started_at="$(date +%s)" + docker pull "${TEST_IMAGE}" + finished_at="$(date +%s)" + pull_seconds="$((finished_at - started_at))" + + image_size_bytes="$(docker image inspect "${TEST_IMAGE}" --format '{{.Size}}')" + image_size_gib="$(awk -v bytes="${image_size_bytes}" 'BEGIN { printf "%.2f", bytes / 1024 / 1024 / 1024 }')" + + echo "seconds=${pull_seconds}" >> "${GITHUB_OUTPUT}" + echo "size_gib=${image_size_gib}" >> "${GITHUB_OUTPUT}" + + { + echo "- Cold pull: \`${pull_seconds}s\`" + echo "- Image size: \`${image_size_gib} GiB\`" + } >> "${GITHUB_STEP_SUMMARY}" + + - name: Validate warm-cache pull + id: warm_pull + shell: bash + run: | + set -euo pipefail + + started_at="$(date +%s)" + docker pull "${TEST_IMAGE}" + finished_at="$(date +%s)" + pull_seconds="$((finished_at - started_at))" + + echo "seconds=${pull_seconds}" >> "${GITHUB_OUTPUT}" + echo "- Warm pull: \`${pull_seconds}s\`" >> "${GITHUB_STEP_SUMMARY}" + + - name: Run GPU smoke test inside the image + shell: bash + run: | + set -euo pipefail + + docker run --rm --gpus all "${TEST_IMAGE}" nvidia-smi + echo "- GPU container test: **passed**" >> "${GITHUB_STEP_SUMMARY}" + + - name: Report Docker disk usage + if: always() + shell: bash + run: | + docker system df || true + df -h /runner/_work || true + + { + echo + echo "### Timings" + echo + echo "| Check | Result |" + echo "|---|---:|" + echo "| Cold pull | ${{ steps.cold_pull.outputs.seconds || 'failed' }}s |" + echo "| Warm pull | ${{ steps.warm_pull.outputs.seconds || 'failed' }}s |" + echo "| Image size | ${{ steps.cold_pull.outputs.size_gib || 'unknown' }} GiB |" + } >> "${GITHUB_STEP_SUMMARY}" From 07326d0ba530a63bc390f862978d6551ebbb3e93 Mon Sep 17 00:00:00 2001 From: mrL <1417558386@qq.com> Date: Fri, 14 Aug 2026 00:57:14 +0800 Subject: [PATCH 2/3] ci: move K8s overlay2 sample out of .github/workflows/ The previous commit placed both the smoke workflow and the K8s RunnerDeployment sample under .github/workflows/. GitHub Actions parses every YAML in that directory as a workflow, which caused the K8s sample to be interpreted as a broken workflow (run #1 failed at parse step, shadowing the real smoke workflow in the Actions UI). Move the K8s sample to docs/community/cicd/overlay2-runner-sample.yaml where it belongs as CI documentation, not as an Actions workflow. --- .../community/cicd/overlay2-runner-sample.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/cpu-runner-overlay2-sample.yaml => docs/community/cicd/overlay2-runner-sample.yaml (100%) diff --git a/.github/workflows/cpu-runner-overlay2-sample.yaml b/docs/community/cicd/overlay2-runner-sample.yaml similarity index 100% rename from .github/workflows/cpu-runner-overlay2-sample.yaml rename to docs/community/cicd/overlay2-runner-sample.yaml From 8c459988be003ae1b6f35c393052f147255a1ed1 Mon Sep 17 00:00:00 2001 From: mrL <1417558386@qq.com> Date: Fri, 14 Aug 2026 14:30:45 +0800 Subject: [PATCH 3/3] ci: trigger smoke workflow on PRs that modify it Add pull_request trigger scoped to the smoke workflow file itself, so updates to the workflow (e.g. validating changes to the runner probe) are automatically validated instead of requiring a manual dispatch. Keeps workflow_dispatch for on-demand runs. --- .github/workflows/gpu-runner-overlay2-smoke.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/gpu-runner-overlay2-smoke.yml b/.github/workflows/gpu-runner-overlay2-smoke.yml index 574c17c268..7b6131688e 100644 --- a/.github/workflows/gpu-runner-overlay2-smoke.yml +++ b/.github/workflows/gpu-runner-overlay2-smoke.yml @@ -8,6 +8,9 @@ on: required: true default: ghcr.io/deepmodeling/abacus-cuda:latest type: string + pull_request: + paths: + - '.github/workflows/gpu-runner-overlay2-smoke.yml' permissions: contents: read