diff options
| -rw-r--r-- | CLAUDE.md | 4 | ||||
| -rw-r--r-- | README.md | 12 | ||||
| -rw-r--r-- | skills/test-build-slackbuild/SKILL.md | 3 | ||||
| -rwxr-xr-x | test-build | 27 | ||||
| -rw-r--r-- | test-logic.sh | 30 |
5 files changed, 68 insertions, 8 deletions
@@ -114,7 +114,9 @@ built deps). Only **deps** are cached, never the target. target `.txz` to `<data>/kept/` so it can be installed on the host, e.g. to regenerate post-install artifacts), `--local-deps` (also resolve deps from the target's own repo, its grandparent dir, prepended before the SBo tree, for -packages whose deps are siblings in the same repo and not on SBo), `--no-color`. +packages whose deps are siblings in the same repo and not on SBo), `--pull` +(refresh the image from the registry first; a local image is otherwise pulled +only when missing, so it goes stale), `--no-color`. ## image-builder @@ -50,12 +50,24 @@ cd some-slackbuild-dir && test-build <name> # -current test-build --stable <name> # 15.0 test-build --keep <name> # also keep the built .txz test-build --local-deps <name> # deps live in the same repo +test-build --pull <name> # refresh the image first ``` `--local-deps` also searches the target's own repo (its grandparent dir) for deps, for packages whose deps are siblings in the same repo and not on SBo. The configured SBo tree is still searched after. +A local image is pulled only when missing, so it goes stale when the registry +tag is rebuilt. `test-build --pull <name>` refreshes it for one run. To keep +every machine that runs `test-build` current, add a daily cron entry after +the image chain finishes (~08:00). `docker pull` compares digests itself and +is a no-op when the image is up to date; the prune drops the image a pull +leaves untagged: + +``` +30 9 * * * docker pull -q docker.noland.dnx:5000/sbo-testbuild:current && docker pull -q docker.noland.dnx:5000/sbo-testbuild:15.0 && docker image prune -f +``` + Build the images (on the docker host; see `image-builder/README`): ```bash diff --git a/skills/test-build-slackbuild/SKILL.md b/skills/test-build-slackbuild/SKILL.md index e8b553c..dc23896 100644 --- a/skills/test-build-slackbuild/SKILL.md +++ b/skills/test-build-slackbuild/SKILL.md @@ -73,6 +73,7 @@ The local deps must themselves be valid, buildable SlackBuilds. Without the flag | `--no-cache` | Rebuild all deps this run. | | `--keep` | Copy the built target `.txz` to `kept/` so it can be installed on the host. | | `--local-deps` | Also resolve deps from the target's own repo (grandparent dir), for deps that are siblings in the same repo and not on SBo. | +| `--pull` | Refresh the image from the registry before building (no-op if already current; falls back to the local copy if the registry is down). Use when the image-builder rebuilt the tag since the last pull. | | `--no-color` | Disable ANSI color (auto-off when not a TTY). | | `-V`, `--version` | Print version. | @@ -91,7 +92,7 @@ Lint runs in-container on the target only. Findings are **fail-soft**: `LINT-FIN ## Setup that must exist - `~/.config/sbo-testbuild/config` (from `test-build-config.example`): trees, image tags, `LOG_ROOT`, `PKG_CACHE`. Missing config = hard exit with a copy-the-example message. -- Docker reachable, and the `sbo-testbuild:{current,15.0}` images built by the image-builder (pulled from the LAN registry if not local). A pure `--dry-run` skips the image check. +- Docker reachable, and the `sbo-testbuild:{current,15.0}` images built by the image-builder (pulled from the LAN registry if not local). A local copy is **not** refreshed automatically: it goes stale when the registry tag is rebuilt, unless a daily cron pull is set up (see README) or you pass `--pull`. A pure `--dry-run` skips the image check. - `~/.config/sbo-testbuild/overrides` only if you need override rules. ## Do not @@ -54,6 +54,7 @@ ASSUME_YES=0 # --yes: skip the confirm prompt (still prints the order) USE_CACHE=1 # --no-cache disables the dep cache for one run KEEP_TARGET=0 # --keep: copy the built target package out to KEEP_DIR LOCAL_DEPS=0 # --local-deps: also resolve deps from the target's own repo +PULL_IMAGE=0 # --pull: refresh the image from the registry before building VERSION_ID="current" # "current" | "15.0"; set by --stable TARGET_ARG="" @@ -89,6 +90,10 @@ OPTIONS: --local-deps Also resolve deps from the target's own repo (its grandparent dir), for packages whose deps are siblings in the same repo and not on SBo. The configured SBo tree is still searched after. + --pull Pull the image from the registry before building, so a local + copy older than the registry's tag is refreshed. A no-op when + it is already current. Falls back to the local copy if the + registry is unreachable. --no-color Disable ANSI color (auto-disabled when stdout is not a TTY). EOF } @@ -104,6 +109,7 @@ parse_args() { --no-cache) USE_CACHE=0; shift ;; --keep) KEEP_TARGET=1; shift ;; --local-deps) LOCAL_DEPS=1; shift ;; + --pull) PULL_IMAGE=1; shift ;; --no-color) USE_COLOR=0; shift ;; -*) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;; *) @@ -850,13 +856,22 @@ print_summary() { # Ensure the selected image is available locally. It is built by a separate job # (the image-builder) and pushed to the LAN registry; this script only consumes # it. If it is not already local, pull it once (ACTIVE_IMAGE is a fully-qualified -# registry ref). A stale local tag is not refreshed here. -# ponytail: pull-if-missing only. If the registry's :current is rebuilt, the -# local copy goes stale silently. Add a --pull force-flag if that bites. +# registry ref). A stale local tag is refreshed only with --pull (or by the +# daily cron pull in the README); `docker pull` itself does the digest check, +# so an up-to-date image costs one manifest request. require_image() { - docker image inspect "$ACTIVE_IMAGE" >/dev/null 2>&1 && return 0 - echo "Image not present locally, pulling: $ACTIVE_IMAGE" >&2 - docker pull "$ACTIVE_IMAGE" >&2 && return 0 + if [[ $PULL_IMAGE -eq 1 ]]; then + echo "Pulling: $ACTIVE_IMAGE" >&2 + docker pull "$ACTIVE_IMAGE" >&2 && return 0 + if docker image inspect "$ACTIVE_IMAGE" >/dev/null 2>&1; then + echo "WARN: pull failed; using the local copy, which may be stale." >&2 + return 0 + fi + else + docker image inspect "$ACTIVE_IMAGE" >/dev/null 2>&1 && return 0 + echo "Image not present locally, pulling: $ACTIVE_IMAGE" >&2 + docker pull "$ACTIVE_IMAGE" >&2 && return 0 + fi cat >&2 <<EOF Image not found and pull failed: $ACTIVE_IMAGE It is produced by the image-builder job (full Slackware $VERSION_ID + diff --git a/test-logic.sh b/test-logic.sh index 563eb30..a46b582 100644 --- a/test-logic.sh +++ b/test-logic.sh @@ -234,6 +234,36 @@ if depends_on_failed "$T/cat/a" dead; then bad "a blocked with empty dead"; else dead=("%README%") if depends_on_failed "$T/cat/a" dead; then bad "%README% treated as dep"; else ok "%README% not treated as dep"; fi +# --- require_image / --pull --------------------------------------------------- +# Stub docker: records "pull"/"inspect" calls; STUB_PULL / STUB_LOCAL set outcomes. +echo "require_image:" +docker() { + CALLS+="$1 " + case "$1" in + pull) [[ $STUB_PULL -eq 0 ]] ;; + image) [[ $STUB_LOCAL -eq 1 ]] ;; + esac +} +ACTIVE_IMAGE="reg/img:current" +PULL_IMAGE=0; parse_args --pull pkg >/dev/null 2>&1 +[[ $PULL_IMAGE -eq 1 ]] && ok "--pull sets PULL_IMAGE" || bad "--pull not parsed" +TARGET_ARG="" + +PULL_IMAGE=0; STUB_LOCAL=1; STUB_PULL=0; CALLS="" +require_image 2>/dev/null +[[ $CALLS == "image " ]] && ok "no --pull + local: no pull" || bad "no --pull + local: calls '$CALLS'" + +PULL_IMAGE=1; STUB_LOCAL=1; STUB_PULL=0; CALLS="" +require_image 2>/dev/null +[[ $CALLS == "pull " ]] && ok "--pull: pulls even when local" || bad "--pull: calls '$CALLS'" + +PULL_IMAGE=1; STUB_LOCAL=1; STUB_PULL=1; CALLS="" +( require_image ) 2>/dev/null && ok "--pull fails + local: falls back" || bad "--pull fails + local: exited" + +PULL_IMAGE=1; STUB_LOCAL=0; STUB_PULL=1; CALLS="" +( require_image ) 2>/dev/null && bad "--pull fails + no local: should exit" || ok "--pull fails + no local: exits" +unset -f docker; PULL_IMAGE=0 + echo echo "$pass passed, $fail failed" [[ $fail -eq 0 ]] || exit 1 |
