#!/usr/bin/env bash # Import air-gap bundle into isolated environment # Usage: ./import-bundle.sh [registry] # Example: ./import-bundle.sh /media/usb/stellaops-bundle localhost:5000 set -euo pipefail BUNDLE_DIR="${1:?Bundle directory required}" REGISTRY="${2:-localhost:5000}" echo "==> Importing air-gap bundle from ${BUNDLE_DIR}" # Verify bundle structure if [[ ! -f "${BUNDLE_DIR}/manifest.json" ]]; then echo "ERROR: manifest.json not found in bundle" >&2 exit 1 fi # Verify checksums first echo "==> Verifying checksums..." cd "${BUNDLE_DIR}" for sha_file in *.sha256; do if [[ -f "${sha_file}" ]]; then echo " Checking ${sha_file}..." sha256sum -c "${sha_file}" || { echo "CHECKSUM FAILED: ${sha_file}" >&2; exit 1; } fi done # Load container images echo "==> Loading container images..." for tarball in images/*.tar images/*.tar.gz 2>/dev/null; do if [[ -f "${tarball}" ]]; then echo " Loading ${tarball}..." docker load -i "${tarball}" fi done # Re-tag and push to local registry echo "==> Pushing images to ${REGISTRY}..." IMAGES=$(jq -r '.images[]?.name // empty' manifest.json 2>/dev/null || true) for IMAGE in ${IMAGES}; do LOCAL_TAG="${REGISTRY}/${IMAGE##*/}" echo " ${IMAGE} -> ${LOCAL_TAG}" docker tag "${IMAGE}" "${LOCAL_TAG}" 2>/dev/null || true docker push "${LOCAL_TAG}" 2>/dev/null || echo " (push skipped - registry may be unavailable)" done # Import Helm charts echo "==> Importing Helm charts..." if [[ -d "${BUNDLE_DIR}/charts" ]]; then for chart in "${BUNDLE_DIR}"/charts/*.tgz; do if [[ -f "${chart}" ]]; then echo " Installing ${chart}..." helm push "${chart}" "oci://${REGISTRY}/charts" 2>/dev/null || \ echo " (OCI push skipped - copying to local)" fi done fi # Import NuGet packages echo "==> Importing NuGet packages..." if [[ -d "${BUNDLE_DIR}/nugets" ]]; then NUGET_CACHE="${HOME}/.nuget/packages" mkdir -p "${NUGET_CACHE}" for nupkg in "${BUNDLE_DIR}"/nugets/*.nupkg; do if [[ -f "${nupkg}" ]]; then PKG_NAME=$(basename "${nupkg}" .nupkg) echo " Caching ${PKG_NAME}..." # Extract to NuGet cache structure unzip -q -o "${nupkg}" -d "${NUGET_CACHE}/${PKG_NAME,,}" 2>/dev/null || true fi done fi # Import npm packages echo "==> Importing npm packages..." if [[ -d "${BUNDLE_DIR}/npm" ]]; then NPM_CACHE="${HOME}/.npm/_cacache" mkdir -p "${NPM_CACHE}" if [[ -f "${BUNDLE_DIR}/npm/cache.tar.gz" ]]; then tar -xzf "${BUNDLE_DIR}/npm/cache.tar.gz" -C "${HOME}/.npm" 2>/dev/null || true fi fi # Import advisory feeds echo "==> Importing advisory feeds..." if [[ -d "${BUNDLE_DIR}/feeds" ]]; then FEEDS_DIR="/var/lib/stellaops/feeds" sudo mkdir -p "${FEEDS_DIR}" 2>/dev/null || mkdir -p "${FEEDS_DIR}" for feed in "${BUNDLE_DIR}"/feeds/*.ndjson.gz; do if [[ -f "${feed}" ]]; then FEED_NAME=$(basename "${feed}") echo " Installing ${FEED_NAME}..." cp "${feed}" "${FEEDS_DIR}/" 2>/dev/null || sudo cp "${feed}" "${FEEDS_DIR}/" fi done fi # Import symbol bundles echo "==> Importing symbol bundles..." if [[ -d "${BUNDLE_DIR}/symbols" ]]; then SYMBOLS_DIR="/var/lib/stellaops/symbols" sudo mkdir -p "${SYMBOLS_DIR}" 2>/dev/null || mkdir -p "${SYMBOLS_DIR}" for bundle in "${BUNDLE_DIR}"/symbols/*.zip; do if [[ -f "${bundle}" ]]; then echo " Extracting ${bundle}..." unzip -q -o "${bundle}" -d "${SYMBOLS_DIR}" 2>/dev/null || true fi done fi # Generate import report echo "==> Generating import report..." cat > "${BUNDLE_DIR}/import-report.json" < Import complete" echo " Registry: ${REGISTRY}" echo " Report: ${BUNDLE_DIR}/import-report.json" echo "" echo "Next steps:" echo " 1. Update Helm values with registry: ${REGISTRY}" echo " 2. Deploy: helm install stellaops deploy/helm/stellaops -f values-airgap.yaml" echo " 3. Verify: kubectl get pods -n stellaops"