#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) ROOT_DIR=$(cd -- "${SCRIPT_DIR}/.." && pwd) CONFIG_FILE="${ROOT_DIR}/config/mesa-opt.conf" DIST_DIR="${ROOT_DIR}/dist" APT_DIR="${DIST_DIR}/aptrepo" DIST_ENV="${DIST_DIR}/package-info.env" CHECK_REMOTE=0 usage() { cat <<'EOF' Usage: verify-apt-repo.sh [--remote] Checks that the generated apt repository is internally consistent. With --remote, also verifies that the configured public HTTP base URL serves the Release file, Packages index, and referenced package anonymously. EOF } while [[ $# -gt 0 ]]; do case "$1" in --remote) CHECK_REMOTE=1 shift ;; -h|--help) usage exit 0 ;; *) echo "unknown argument: $1" >&2 usage >&2 exit 1 ;; esac done if [[ -f "${CONFIG_FILE}" ]]; then # shellcheck disable=SC1090 source "${CONFIG_FILE}" fi if [[ ! -f "${DIST_ENV}" ]]; then echo "missing dist metadata: ${DIST_ENV}" >&2 exit 1 fi # shellcheck disable=SC1090 source "${DIST_ENV}" APT_SUITE="${APT_SUITE:-stable}" APT_COMPONENT="${APT_COMPONENT:-main}" APT_ARCH="${APT_ARCH:-${PACKAGE_ARCH:-amd64}}" PACKAGES_FILE="${APT_DIR}/dists/${APT_SUITE}/${APT_COMPONENT}/binary-${APT_ARCH}/Packages" RELEASE_FILE="${APT_DIR}/dists/${APT_SUITE}/Release" require_cmd() { local cmd for cmd in "$@"; do command -v "${cmd}" >/dev/null 2>&1 || { echo "missing command: ${cmd}" >&2 exit 1 } done } require_cmd awk curl grep gzip [[ -f "${RELEASE_FILE}" ]] || { echo "missing Release file: ${RELEASE_FILE}" >&2 exit 1 } [[ -f "${PACKAGES_FILE}" ]] || { echo "missing Packages file: ${PACKAGES_FILE}" >&2 exit 1 } [[ -f "${PACKAGES_FILE}.gz" ]] || { echo "missing Packages.gz file: ${PACKAGES_FILE}.gz" >&2 exit 1 } PACKAGE_RELATIVE_PATH="$(awk -F': ' '$1=="Filename" { print $2; exit }' "${PACKAGES_FILE}")" [[ -n "${PACKAGE_RELATIVE_PATH}" ]] || { echo "missing Filename entry in ${PACKAGES_FILE}" >&2 exit 1 } [[ -f "${APT_DIR}/${PACKAGE_RELATIVE_PATH}" ]] || { echo "referenced package is missing: ${APT_DIR}/${PACKAGE_RELATIVE_PATH}" >&2 exit 1 } grep -q " ${APT_COMPONENT}/binary-${APT_ARCH}/Packages\$" "${RELEASE_FILE}" || { echo "Release file does not reference Packages index" >&2 exit 1 } grep -q " ${APT_COMPONENT}/binary-${APT_ARCH}/Packages.gz\$" "${RELEASE_FILE}" || { echo "Release file does not reference Packages.gz index" >&2 exit 1 } gzip -t "${PACKAGES_FILE}.gz" echo "local apt repository structure looks valid" if [[ "${CHECK_REMOTE}" -eq 0 ]]; then exit 0 fi if [[ -z "${APT_PUBLIC_BASE_URL:-}" ]]; then echo "APT_PUBLIC_BASE_URL is empty; skipping remote verification" exit 0 fi BASE_URL="${APT_PUBLIC_BASE_URL%/}" RELEASE_URL="${BASE_URL}/dists/${APT_SUITE}/Release" PACKAGES_URL="${BASE_URL}/dists/${APT_SUITE}/${APT_COMPONENT}/binary-${APT_ARCH}/Packages" PACKAGE_URL="${BASE_URL}/${PACKAGE_RELATIVE_PATH}" curl -fsSL "${RELEASE_URL}" >/dev/null curl -fsSL "${PACKAGES_URL}" >/dev/null curl -fsSLI "${PACKAGE_URL}" >/dev/null echo "remote apt repository is reachable anonymously via ${BASE_URL}"