#!/usr/bin/env bash # GPS-Denied Onboard — pull Docker images from the parent-suite registry. # # Cycle-1 images: # * ${REGISTRY_HOST}/azaion/gps-denied-onboard-companion-tier1:- # * ${REGISTRY_HOST}/azaion/gps-denied-onboard-operator-orchestrator:- # # Cycle-2 (when docker/companion-jetson.Dockerfile lands): # * ${REGISTRY_HOST}/azaion/gps-denied-onboard:- (airborne) # # Reads REGISTRY_HOST / REGISTRY_USER / REGISTRY_TOKEN from environment # or .env at the project root. Supports remote execution via SSH when # DEPLOY_HOST is set (delegates to the remote host's local docker pull). # # Usage: # scripts/pull-images.sh [--branch ] [--arch ] # [--target dev|airborne|operator-workstation] # [--verify] [--help] # # Defaults: # branch = main # arch = arm (Jetson + suite arm64 build agent) # target = operator-workstation # # Exit codes: # 0 all images pulled (or already up-to-date) # 64 missing prerequisite (REGISTRY_HOST, docker on PATH) # 65 SSH unreachable when DEPLOY_HOST is set # 66 registry login failed # 67 image pull failed set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" usage() { cat <<'EOF' GPS-Denied Onboard — pull Docker images from the parent-suite registry. Cycle-1 images: * ${REGISTRY_HOST}/azaion/gps-denied-onboard-companion-tier1:- * ${REGISTRY_HOST}/azaion/gps-denied-onboard-operator-orchestrator:- Cycle-2 (when docker/companion-jetson.Dockerfile lands): * ${REGISTRY_HOST}/azaion/gps-denied-onboard:- (airborne) Reads REGISTRY_HOST / REGISTRY_USER / REGISTRY_TOKEN from environment or .env at the project root. Supports remote execution via SSH when DEPLOY_HOST is set (delegates to the remote host's local docker pull). Usage: scripts/pull-images.sh [--branch ] [--arch ] [--target dev|airborne|operator-workstation] [--verify] [--help] Defaults: branch = main arch = arm (Jetson + suite arm64 build agent) target = operator-workstation Exit codes: 0 all images pulled (or already up-to-date) 64 missing prerequisite (REGISTRY_HOST, docker on PATH) 65 SSH unreachable when DEPLOY_HOST is set 66 registry login failed 67 image pull failed EOF exit 0 } BRANCH="${BRANCH:-main}" ARCH="${ARCH:-arm}" TARGET="operator-workstation" VERIFY=0 while [ $# -gt 0 ]; do case "$1" in --branch) BRANCH="$2"; shift 2 ;; --arch) ARCH="$2"; shift 2 ;; --target) TARGET="$2"; shift 2 ;; --verify) VERIFY=1; shift ;; --help|-h) usage ;; *) echo "ERROR: unknown argument: $1" >&2; usage ;; esac done if [ -f "${REPO_ROOT}/.env" ]; then set -a # shellcheck disable=SC1091 . "${REPO_ROOT}/.env" set +a fi if [ -z "${REGISTRY_HOST:-}" ]; then echo "ERROR: REGISTRY_HOST not set (e.g. git.azaion.com)" >&2 echo " Set in .env or export before invoking." >&2 exit 64 fi remote_exec="" if [ -n "${DEPLOY_HOST:-}" ]; then if ! ssh -o BatchMode=yes -o ConnectTimeout=5 "${DEPLOY_HOST}" true 2>/dev/null; then echo "ERROR: cannot reach 'ssh ${DEPLOY_HOST}' non-interactively." >&2 exit 65 fi remote_exec="ssh ${DEPLOY_HOST}" fi case "${TARGET}" in dev) IMAGES=( "${REGISTRY_HOST}/azaion/gps-denied-onboard-companion-tier1:${BRANCH}-${ARCH}" "${REGISTRY_HOST}/azaion/gps-denied-onboard-operator-orchestrator:${BRANCH}-${ARCH}" ) ;; airborne) IMAGES=( "${REGISTRY_HOST}/azaion/gps-denied-onboard:${BRANCH}-${ARCH}" ) ;; operator-workstation) IMAGES=( "${REGISTRY_HOST}/azaion/gps-denied-onboard-operator-orchestrator:${BRANCH}-${ARCH}" ) ;; *) echo "ERROR: invalid --target: ${TARGET}" >&2 echo " Must be one of: dev, airborne, operator-workstation" >&2 exit 64 ;; esac echo "[pull-images] registry: ${REGISTRY_HOST}" echo "[pull-images] branch: ${BRANCH}" echo "[pull-images] arch: ${ARCH}" echo "[pull-images] target: ${TARGET}" if [ -n "${remote_exec}" ]; then echo "[pull-images] remote: ${DEPLOY_HOST}" fi if [ -n "${REGISTRY_USER:-}" ] && [ -n "${REGISTRY_TOKEN:-}" ]; then echo "[pull-images] docker login → ${REGISTRY_HOST}" if ! echo "${REGISTRY_TOKEN}" \ | ${remote_exec} docker login "${REGISTRY_HOST}" \ --username "${REGISTRY_USER}" --password-stdin >/dev/null; then echo "ERROR: docker login failed against ${REGISTRY_HOST}" >&2 exit 66 fi else echo "[pull-images] REGISTRY_USER / REGISTRY_TOKEN not set — assuming" echo " the registry is reachable anonymously or the local" echo " docker config is already authenticated." fi for image in "${IMAGES[@]}"; do echo "[pull-images] pulling ${image}" if ! ${remote_exec} docker pull "${image}"; then echo "ERROR: failed to pull ${image}" >&2 exit 67 fi done if [ "${VERIFY}" = "1" ]; then echo "[pull-images] verifying image digests + AZAION_REVISION env" for image in "${IMAGES[@]}"; do digest=$(${remote_exec} docker image inspect \ --format '{{(index .RepoDigests 0)}}' "${image}" 2>/dev/null || echo "") revision=$(${remote_exec} docker image inspect \ --format '{{range .Config.Env}}{{println .}}{{end}}' "${image}" 2>/dev/null \ | grep '^AZAION_REVISION=' | head -n1 | cut -d= -f2 || echo "") echo " ${image}" echo " digest: ${digest:-}" echo " revision: ${revision:-}" done fi echo "[pull-images] OK"