#!/usr/bin/env bash ############################################################################### # [폐쇄망 밖에서 실행] 배포 번들의 images/ 를 채운다. # # ./bin/export-images.sh # # 어떤 이미지가 필요한지는 compose.yml 에서 읽는다 — 목록을 두 곳에 적지 않는다. # 앱(pi-continuum)과 alpha-processing 은 CI 가 빌드해 올린 tar 을 그대로 쓰므로, # images/ 에 미리 두면 이 스크립트가 태그만 확인한다. 나머지는 레지스트리에서 받아 저장한다. ############################################################################### . "$(dirname -- "${BASH_SOURCE[0]}")/lib.sh" resolve_engine "${1:-docker}" # 폐쇄망 반입 대상 아키텍처. 배포 서버와 다르면 이미지가 아예 뜨지 않는다. PLATFORM="${PLATFORM:-linux/amd64}" [ -f "${ENV_FILE}" ] && load_env mkdir -p "${IMAGES_DIR}" log "compose 에서 이미지 목록을 읽는다" IMAGES=() while IFS= read -r tag; do [ -n "${tag}" ] && IMAGES+=("${tag}"); done < <( python3 "${DEPLOY_DIR}/bin/_compose_to_plan.py" "${DEPLOY_DIR}/compose.yml" "${DEPLOY_DIR}" \ | python3 -c ' import json, sys plan = json.load(sys.stdin) seen = [] for name in plan["order"]: tag = plan["services"][name]["image"] if tag not in seen: seen.append(tag) print("\n".join(seen)) ') [ "${#IMAGES[@]}" -gt 0 ] || die "compose 에서 이미지를 하나도 읽지 못했다." tar_name_for() { # 이미지 태그 → tar 파일명 (레지스트리 호스트·슬래시·콜론 제거) printf '%s.tar\n' "$1" | sed -e 's#^[^/]*\.[^/]*/##' -e 's#/#-#g' -e 's#:#-#g' } log "대상 플랫폼: ${PLATFORM}" rows=() for tag in "${IMAGES[@]}"; do file="$(tar_name_for "${tag}")" path="${IMAGES_DIR}/${file}" if [ -f "${path}" ]; then # CI 산출물처럼 이미 놓아 둔 tar — 태그만 맞는지 본다. 다르면 pull_policy: never 로 뜨지 않는다. got="$(tar -xOf "${path}" manifest.json 2>/dev/null \ | python3 -c 'import json,sys; print(",".join(t for m in json.load(sys.stdin) for t in (m.get("RepoTags") or [])))' 2>/dev/null || true)" case ",${got}," in *",${tag},"*) log "확인: ${file} → ${tag}"; rows+=("${file} ${tag}"); continue ;; *) warn "${file} 의 태그가 '${got}' 라 기대값 '${tag}' 와 다르다. 새로 만든다." ;; esac fi log "pull: ${tag}" if ! engine pull --platform "${PLATFORM}" "${tag}" >/dev/null 2>&1; then # 레지스트리에서 태그가 내려가는 일이 실제로 있다 (Docker Hub 의 minio/mc). engine image inspect "${tag}" >/dev/null 2>&1 \ || die "pull 실패이고 로컬에도 없다: ${tag} CI 산출물이라면 tar 을 ${IMAGES_DIR}/${file} 로 두고 다시 실행한다. 레지스트리에서 내려간 이미지라면 compose 의 태그를 대체 사본으로 고친다." warn "pull 실패 — 로컬에 있는 ${tag} 를 그대로 쓴다 (digest 를 직접 확인할 것)." fi log "save: ${file}" engine save -o "${path}" "${tag}" # docker save 는 0600 으로 만든다. 매체로 옮겨 다른 계정이 읽을 수 있게 완화한다. chmod 0644 "${path}" rows+=("${file} ${tag}") done log "완료. 반입 대상:" ( cd "${IMAGES_DIR}" && du -ch ./*.tar | tail -1 ) for row in "${rows[@]}"; do printf ' %-52s %s\n' "${row%% *}" "${row##* }" done