XuqmGroup-PrivateDeploy/scripts/export-offline-bundle.sh

94 行
3.2 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
. "$ROOT_DIR/scripts/lib.sh"
load_env
OUT_DIR="${1:-$ROOT_DIR/dist}"
mkdir -p "$OUT_DIR"
BUNDLE_NAME="xuqm-private-$(cat "$ROOT_DIR/VERSION" | tr -d '[:space:]')-offline"
BUNDLE_DIR="$OUT_DIR/$BUNDLE_NAME"
BUNDLE_ARCHIVE="$OUT_DIR/${BUNDLE_NAME}.tar.gz"
audit "export-offline-bundle" "STARTED" "$OUT_DIR"
progress "export-offline-bundle" "STARTED" "$OUT_DIR"
mkdir -p "$BUNDLE_DIR"
# Copy deploy repo (exclude data, dist, git, secrets)
tar --exclude='data' --exclude='dist' --exclude='.git' \
--exclude='config/secrets.env' --exclude='logs/audit.log' \
-czf "$BUNDLE_DIR/deploy-repo.tar.gz" -C "$ROOT_DIR" .
# Pull and save Docker images
IMAGES_DIR="$BUNDLE_DIR/images"
mkdir -p "$IMAGES_DIR"
REGISTRY="${REGISTRY:-registry.example.com/xuqm}"
TAG="${IMAGE_TAG:-$(cat "$ROOT_DIR/VERSION" | tr -d '[:space:]')}"
PROFILES="${COMPOSE_PROFILES:-base}"
pull_and_save() {
local svc="$1"
local image="${REGISTRY}/${svc}:${TAG}"
local out_file="$IMAGES_DIR/${svc}.tar"
printf 'Pulling %s ...\n' "$image"
if docker pull "$image" 2>/dev/null; then
docker save "$image" -o "$out_file"
printf 'Saved %s → %s\n' "$image" "$out_file"
else
printf 'WARNING: could not pull %s (skip in offline bundle)\n' "$image"
fi
}
# Always include base images
for svc in tenant-service file-service tenant-web ops-web docs-site; do
pull_and_save "$svc"
done
# Optional services
profile_contains() { case ",${PROFILES}," in *","$1","*) return 0;; esac; return 1; }
profile_contains "im" && pull_and_save "im-service"
profile_contains "push" && pull_and_save "push-service"
profile_contains "update" && pull_and_save "update-service"
profile_contains "license" && pull_and_save "license-service"
# Infrastructure images (always include for managed mode)
docker pull nginx:1.27-alpine 2>/dev/null && docker save nginx:1.27-alpine -o "$IMAGES_DIR/nginx.tar" || true
docker pull mysql:8.4 2>/dev/null && docker save mysql:8.4 -o "$IMAGES_DIR/mysql.tar" || true
docker pull redis:7.4-alpine 2>/dev/null && docker save redis:7.4-alpine -o "$IMAGES_DIR/redis.tar" || true
# Generate image load script for offline use
cat > "$BUNDLE_DIR/load-images.sh" <<'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for img in "$SCRIPT_DIR/images/"*.tar; do
[ -f "$img" ] || continue
printf 'Loading %s...\n' "$img"
docker load -i "$img"
done
printf 'All images loaded.\n'
SCRIPT
chmod +x "$BUNDLE_DIR/load-images.sh"
# Copy manifest
cp "$ROOT_DIR/image-manifest.json" "$BUNDLE_DIR/" 2>/dev/null || true
# Checksums for all files in bundle
(cd "$OUT_DIR" && find "$BUNDLE_NAME" -type f -exec sha256sum {} \; > "$BUNDLE_DIR/sha256sums.txt")
# Package
tar -czf "$BUNDLE_ARCHIVE" -C "$OUT_DIR" "$BUNDLE_NAME"
rm -rf "$BUNDLE_DIR"
# Checksum of the final archive
sha256sum "$BUNDLE_ARCHIVE" > "${BUNDLE_ARCHIVE}.sha256"
audit "export-offline-bundle" "DONE" "archive=$BUNDLE_ARCHIVE"
progress "export-offline-bundle" "DONE" "archive=$BUNDLE_ARCHIVE"
printf 'Offline bundle: %s\n' "$BUNDLE_ARCHIVE"
printf 'SHA256: %s\n' "$(cat "${BUNDLE_ARCHIVE}.sha256")"