#!/usr/bin/env bash # deploy-box-web.sh — Atomically package and deploy Box Web Console assets to the Google Cloud VM # # Assets: web/box/www/{index.html, box.js, box.css} # Destination: /srv/box/www/ on 34.139.37.135 (box.muse-dev.online) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" SRC_DIR="$REPO_ROOT/web/box/www" # Default configuration DEST_HOST="${BOX_WEB_HOST:-34.139.37.135}" DEST_USER="${BOX_WEB_USER:-super}" DEST_DIR="${BOX_WEB_DEST:-/srv/box/www}" DRY_RUN=0 BUNDLE_ONLY=0 # Parse arguments while [[ $# -gt 0 ]]; do case "$1" in --dry-run) DRY_RUN=1 shift ;; --bundle-only) BUNDLE_ONLY=1 shift ;; --host) DEST_HOST="$2" shift 2 ;; --user) DEST_USER="$2" shift 2 ;; --dest) DEST_DIR="$2" shift 2 ;; -h|--help) echo "Usage: $0 [options]" echo "" echo "Options:" echo " --dry-run Preview assets, hashes, and destination without deploying" echo " --bundle-only Package the atomic tarball into /tmp and exit" echo " --host Target host (default: 34.139.37.135)" echo " --user SSH user on target (default: super)" echo " --dest Remote directory path (default: /srv/box/www)" exit 0 ;; *) echo "Unknown option: $1" >&2 exit 1 ;; esac done # Pre-flight asset verification if [[ ! -d "$SRC_DIR" ]]; then echo "Error: Source directory missing at $SRC_DIR" >&2 exit 1 fi REQUIRED_FILES=("index.html" "box.js" "box.css") for f in "${REQUIRED_FILES[@]}"; do if [[ ! -f "$SRC_DIR/$f" ]]; then echo "Error: Missing required asset: $SRC_DIR/$f" >&2 exit 1 fi done echo "=== Box Web Console Deployment Plan ===" echo "Source: $SRC_DIR" echo "Target: $DEST_USER@$DEST_HOST:$DEST_DIR" echo "Mode: $([ "$DRY_RUN" -eq 1 ] && echo "DRY-RUN (no changes)" || echo "LIVE")" echo "" echo "Asset Manifest & SHA256 Checksums:" for f in "${REQUIRED_FILES[@]}"; do csum=$(sha256sum "$SRC_DIR/$f" | cut -d' ' -f1) size=$(wc -c < "$SRC_DIR/$f" | tr -d ' ') printf " • %-12s %6s bytes sha256:%s\n" "$f" "$size" "$csum" done echo "" # Dry-run exit if [[ "$DRY_RUN" -eq 1 ]]; then echo "[dry-run] Validation complete. No files transferred." exit 0 fi # Create atomic bundle in temp directory BUNDLE_PATH="/tmp/box-web-bundle-$(date +%s).tar.gz" echo "Creating atomic archive: $BUNDLE_PATH..." tar -czf "$BUNDLE_PATH" -C "$SRC_DIR" index.html box.js box.css echo "Archive created ($(wc -c < "$BUNDLE_PATH" | tr -d ' ') bytes)." if [[ "$BUNDLE_ONLY" -eq 1 ]]; then echo "Bundle generated at $BUNDLE_PATH. Skipping network deployment." exit 0 fi # Deploy to remote target echo "Deploying to $DEST_USER@$DEST_HOST:$DEST_DIR..." REMOTE_TMP="/tmp/box-web-bundle-$$.tar.gz" scp -o ConnectTimeout=10 -o BatchMode=yes "$BUNDLE_PATH" "$DEST_USER@$DEST_HOST:$REMOTE_TMP" ssh -o ConnectTimeout=10 -o BatchMode=yes "$DEST_USER@$DEST_HOST" " mkdir -p '$DEST_DIR' && tar -xzf '$REMOTE_TMP' -C '$DEST_DIR' && rm -f '$REMOTE_TMP' " rm -f "$BUNDLE_PATH" echo "✓ Deployment succeeded! Assets live at https://box.muse-dev.online/"