a20a50df77
git-apply of the staged unification recorded the new canonical entries as 100644; workflows execute them directly (run: scripts/ci/...), so a fresh CI checkout would fail at ci-ok/shard-union/soak/package steps with permission denied — the same class the parity worktree's own preflight just tripped over locally. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
106 lines
4.5 KiB
Bash
Executable File
106 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Bring the container venue to the shape a GitHub runner would hand us, before
|
|
# any docker-backed test/smoke run.
|
|
#
|
|
# A GitHub-hosted runner is ephemeral: fresh image, known-free disk, no leftover
|
|
# containers or volumes from a previous job. Colima is long-lived, so exited
|
|
# containers and orphaned volumes accumulate and the disk drifts down. That
|
|
# drift is not cosmetic — a disk that fills mid-run fails deep inside the
|
|
# install path and reads as a product bug rather than an environment one.
|
|
#
|
|
# Default sweep is the state a runner would never have carried in: stopped
|
|
# containers, dangling images, unused volumes. The build cache is KEPT by
|
|
# default — a runner restores an equivalent cache via actions/cache, so wiping
|
|
# it locally would diverge from CI, not converge with it. --deep drops it too.
|
|
#
|
|
# Usage: preflight-docker.sh [--deep] [--min-free-gb N] [--skip-gate]
|
|
set -euo pipefail
|
|
|
|
# A German (or any comma-decimal) locale makes awk print "76,38" and then parse
|
|
# it back as 76, so the free-space gate would silently compare the wrong number.
|
|
# Pin the numeric locale for every awk/df in this script.
|
|
export LC_ALL=C
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: scripts/ci/preflight-docker.sh [--deep] [--min-free-gb N] [--skip-gate]
|
|
|
|
Bring the Colima/docker venue to the shape a GitHub runner would hand us,
|
|
before any container-backed test/smoke/soak run (test-infrastructure/run.sh
|
|
calls this automatically; CBM_SKIP_PREFLIGHT=1 opts out for a quick re-run).
|
|
|
|
Sweeps stopped containers, dangling images and unused anonymous volumes, then
|
|
asserts free space on the filesystem backing the docker data root. The build
|
|
cache and NAMED compose volumes are KEPT by default — they are this venue's
|
|
analogue of actions/cache, so wiping them would diverge from CI, not converge.
|
|
|
|
Options:
|
|
--deep Also drop the build cache, named volumes and every unused
|
|
image (full cold start).
|
|
--min-free-gb N Free-space floor (default 14 — the runner's SSD size).
|
|
Below it the script BLOCKS with exit 1: a disk that fills
|
|
mid-run fails deep inside the install path and reads as a
|
|
product bug, so refusing to start is the correct outcome.
|
|
--skip-gate Sweep and report, but never block (inspection only).
|
|
-h, --help This text.
|
|
EOF
|
|
}
|
|
|
|
DEEP=0
|
|
MIN_FREE_GB=14
|
|
SKIP_GATE=0
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--deep) DEEP=1 ;;
|
|
--min-free-gb) MIN_FREE_GB="${2:?--min-free-gb needs a value}"; shift ;;
|
|
--skip-gate) SKIP_GATE=1 ;;
|
|
-h | --help) usage; exit 0 ;;
|
|
*) echo "preflight-docker: unknown argument '$1'. Please consult --help." >&2; exit 2 ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if ! docker info >/dev/null 2>&1; then
|
|
echo "preflight-docker: docker is not reachable — start Colima first" >&2
|
|
echo " (Docker Desktop is broken on this machine; Colima is the runtime)" >&2
|
|
exit 2
|
|
fi
|
|
|
|
free_gb() {
|
|
# Measure the filesystem that actually backs the docker data root, not the
|
|
# VM's `/`: on Colima they are different mounts, and `/` reported 18 GB free
|
|
# while 12.5 GB of images lived elsewhere. The host's own free space is
|
|
# irrelevant to a container that fills the VM's disk.
|
|
local root
|
|
root="$(docker info --format '{{.DockerRootDir}}' 2>/dev/null || echo /var/lib/docker)"
|
|
docker run --rm -v /:/hostroot alpine:3 \
|
|
df -P "/hostroot${root}" 2>/dev/null |
|
|
awk 'NR==2 {printf "%.2f", $4/1048576}'
|
|
}
|
|
|
|
before="$(free_gb || echo 0)"
|
|
echo "=== preflight-docker: sweeping runner-unlike residue ==="
|
|
# Anonymous volumes only: the NAMED compose volumes are this venue's warm cache
|
|
# (the local analogue of actions/cache), so dropping them would diverge from CI
|
|
# rather than converge with it. --deep takes them too.
|
|
docker container prune -f
|
|
docker volume prune -f
|
|
docker image prune -f
|
|
if [ "$DEEP" -eq 1 ]; then
|
|
echo "--- deep: dropping build cache, named volumes and every unused image ---"
|
|
docker builder prune -af
|
|
docker volume prune -af
|
|
docker image prune -af
|
|
fi
|
|
after="$(free_gb || echo 0)"
|
|
echo "preflight-docker: free-gb-before=${before} free-gb-after=${after}"
|
|
docker system df
|
|
|
|
if [ "$SKIP_GATE" -eq 0 ] &&
|
|
awk -v a="$after" -v m="$MIN_FREE_GB" 'BEGIN {exit !(a < m)}'; then
|
|
echo "BLOCKED: ${after} GB free, need ${MIN_FREE_GB} GB. A GitHub runner never" >&2
|
|
echo " starts this low, so this run would not be comparable. Re-run with" >&2
|
|
echo " --deep to reclaim the build cache, or free space on the Colima VM." >&2
|
|
exit 1
|
|
fi
|