aboutsummaryrefslogtreecommitdiffstats
path: root/image-builder/build-sbo-testbuild.sh
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-07-14 16:59:44 +0200
committerDanilo M. <danix@danix.xyz>2026-07-14 16:59:44 +0200
commit3cd610c212076d438f2d1103e0fc584a310011d5 (patch)
treeb82bd71ff139408dc84f685345862f944653966b /image-builder/build-sbo-testbuild.sh
downloadsbo-dockerbuild-3cd610c212076d438f2d1103e0fc584a310011d5.tar.gz
sbo-dockerbuild-3cd610c212076d438f2d1103e0fc584a310011d5.zip
initial commit: docker test-build toolchain
Extracted from the .extras/ dir of the sbo-slackbuilds package repo, where it grew from a throwaway helper into a standalone tool. Git history starts fresh; the original 41-commit development log is preserved in HISTORY.md. Contents: the test-build CLI (resolves a local SlackBuild's deps from a configured SBo tree and builds it in a throwaway container, lints, caches deps), the image-builder chain that produces the images it consumes, their pure-logic self-checks, design specs/plans, an install.sh for ~/bin, and docs. Licensed GPLv2-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'image-builder/build-sbo-testbuild.sh')
-rwxr-xr-ximage-builder/build-sbo-testbuild.sh143
1 files changed, 143 insertions, 0 deletions
diff --git a/image-builder/build-sbo-testbuild.sh b/image-builder/build-sbo-testbuild.sh
new file mode 100755
index 0000000..a246b79
--- /dev/null
+++ b/image-builder/build-sbo-testbuild.sh
@@ -0,0 +1,143 @@
+#!/bin/bash
+#
+# Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# build-sbo-testbuild.sh — sbo-testbuild:{ver} FROM sbo-full:{ver}.
+# Adds sbopkg + sbo-maintainer-tools from prebuilt .txz in PKGDIR.
+# Rebuilds when the full image OR the .txz set changes.
+set -euo pipefail
+HERE="$(cd "$(dirname "$0")" && pwd)"
+source "${HERE}/config"
+LOG_TAG=testbuild
+source "${HERE}/lib.sh"
+
+FULL_IMAGE="${REGISTRY}/sbo-full"
+TB_IMAGE="${REGISTRY}/sbo-testbuild"
+DIGEST_LABEL="sbo.testbuild.full-digest"
+PKGS_LABEL="sbo.testbuild.pkgs-hash"
+
+FORCE=false
+OPT_VERSION=""
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --version) OPT_VERSION="$2"; shift 2 ;;
+ --force) FORCE=true; shift ;;
+ *) _err "unknown argument: $1" ;;
+ esac
+done
+if [[ -n "${OPT_VERSION}" ]]; then
+ BUILD_VARIANTS=("${OPT_VERSION}")
+else
+ BUILD_VARIANTS=("${VARIANTS[@]}")
+fi
+
+# Verify the required packages (*.t?z) are present before doing anything.
+require_pkgs() {
+ [[ -d "${PKGDIR}" ]] || _err "PKGDIR missing: ${PKGDIR}"
+ compgen -G "${PKGDIR}/sbopkg-*.t?z" >/dev/null \
+ || _err "no sbopkg-*.t?z in ${PKGDIR}"
+ compgen -G "${PKGDIR}/sbo-maintainer-tools-*.t?z" >/dev/null \
+ || _err "no sbo-maintainer-tools-*.t?z in ${PKGDIR}"
+}
+
+# needs_rebuild FULL_TAG TB_TAG PKGS_HASH -> 0 if rebuild needed
+needs_rebuild() {
+ local full_tag="$1" tb_tag="$2" pkgs_hash="$3"
+ [[ "${FORCE}" == "true" ]] && { _log " --force."; return 0; }
+
+ local full_digest
+ full_digest=$(docker inspect --format '{{index .RepoDigests 0}}' \
+ "${full_tag}" 2>/dev/null || echo "")
+ [[ -n "${full_digest}" ]] || { _warn " no full digest; rebuilding."; return 0; }
+
+ local rec_digest rec_pkgs
+ rec_digest=$(docker inspect \
+ --format "{{index .Config.Labels \"${DIGEST_LABEL}\"}}" \
+ "${tb_tag}" 2>/dev/null || echo "")
+ rec_pkgs=$(docker inspect \
+ --format "{{index .Config.Labels \"${PKGS_LABEL}\"}}" \
+ "${tb_tag}" 2>/dev/null || echo "")
+
+ if [[ "${full_digest}" == "${rec_digest}" && "${pkgs_hash}" == "${rec_pkgs}" ]]; then
+ _log " full image and .txz set unchanged; skipping."
+ return 1
+ fi
+ _log " full image or .txz set changed; rebuilding."
+ return 0
+}
+
+build_variant() {
+ local VERSION="$1"
+ local FULL_TAG="${FULL_IMAGE}:${VERSION}"
+ local TB_TAG="${TB_IMAGE}:${VERSION}"
+ _log "=== ${TB_TAG} ==="
+
+ _log " Pulling ${FULL_TAG}..."
+ docker pull "${FULL_TAG}"
+
+ local PKGS_HASH; PKGS_HASH="$(txz_hash "${PKGDIR}")"
+
+ if ! needs_rebuild "${FULL_TAG}" "${TB_TAG}" "${PKGS_HASH}"; then
+ return 0
+ fi
+
+ local FULL_DIGEST
+ FULL_DIGEST=$(docker inspect --format '{{index .RepoDigests 0}}' "${FULL_TAG}" 2>/dev/null || echo "")
+
+ local WORKDIR; WORKDIR="$(mktemp -d /tmp/sbo-testbuild.XXXXXX)"
+ # shellcheck disable=SC2064
+ trap "rm -rf '${WORKDIR}'" EXIT
+ mkdir -p "${WORKDIR}/pkgs"
+ cp "${PKGDIR}"/sbopkg-*.t?z "${PKGDIR}"/sbo-maintainer-tools-*.t?z "${WORKDIR}/pkgs/"
+
+ cat > "${WORKDIR}/Dockerfile" <<DOCKERFILE
+FROM ${FULL_TAG}
+LABEL maintainer="danix <danix@danix.xyz>"
+COPY pkgs/ /tmp/pkgs/
+RUN installpkg /tmp/pkgs/* && rm -rf /tmp/pkgs
+RUN /sbin/ldconfig
+LABEL org.opencontainers.image.created="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
+LABEL org.opencontainers.image.title="SBo test-build env ${VERSION} (x86_64)"
+LABEL org.opencontainers.image.description="Slackware ${VERSION} full + sbopkg + sbo-maintainer-tools"
+LABEL slackware.version="${VERSION}"
+LABEL ${DIGEST_LABEL}="${FULL_DIGEST}"
+LABEL ${PKGS_LABEL}="${PKGS_HASH}"
+CMD ["/bin/bash"]
+DOCKERFILE
+
+ local BUILD_FLAGS=()
+ [[ "${FORCE}" == "true" ]] && BUILD_FLAGS+=(--no-cache)
+ # Explicit exit checks: build_variant runs in an `if ! (...)` condition
+ # (see Main), which suppresses `set -e` in this subshell, so a failed build
+ # would otherwise push a nonexistent tag and log "Done".
+ _log " Building ${TB_TAG}..."
+ if ! docker build "${BUILD_FLAGS[@]}" -t "${TB_TAG}" "${WORKDIR}"; then
+ _warn " build failed for ${TB_TAG}; not pushing."
+ return 1
+ fi
+ _log " Pushing ${TB_TAG}..."
+ if ! docker push "${TB_TAG}"; then
+ _warn " push failed for ${TB_TAG}."
+ return 1
+ fi
+ _log "=== Done: ${TB_TAG} ==="
+}
+
+require_pkgs
+rc=0
+for VERSION in "${BUILD_VARIANTS[@]}"; do
+ if ! ( build_variant "${VERSION}" ); then
+ _warn "variant ${VERSION} failed; continuing."
+ rc=1
+ fi
+done
+exit "${rc}"