#!/usr/bin/env bash set -euo pipefail APPFACTORY_ROOT="/opt/appfactory" BACKUP_FILE="${1:-}" TARGET_USER="${2:-${SUDO_USER:-$USER}}" fail() { echo "[restore][FAIL] $*" >&2 exit 1 } ok() { echo "[restore][OK] $*" } log() { echo "[restore] $*" } usage() { cat </dev/null 2>&1; then fail "Target user does not exist: $TARGET_USER" fi command -v tar >/dev/null 2>&1 || fail "tar missing" command -v docker >/dev/null 2>&1 || fail "docker missing" APPFACTORY_UID="$(id -u "$TARGET_USER")" APPFACTORY_GID="$(id -g "$TARGET_USER")" [ -S /var/run/docker.sock ] || fail "Docker socket missing: /var/run/docker.sock" APPFACTORY_DOCKER_GID="$(stat -c '%g' /var/run/docker.sock)" log "Backup: $BACKUP_FILE" log "Target user: $TARGET_USER" log "APPFACTORY_UID=$APPFACTORY_UID" log "APPFACTORY_GID=$APPFACTORY_GID" log "APPFACTORY_DOCKER_GID=$APPFACTORY_DOCKER_GID" log "Stopping existing AppFactory containers if present" mapfile -t APPFACTORY_CONTAINERS < <( docker ps -a --format '{{.Names}}' \ | grep -E '^(appfactory-|.*-service$|test-|microsoft-365-service)' \ || true ) if [ "${#APPFACTORY_CONTAINERS[@]}" -eq 0 ]; then ok "No existing AppFactory containers found" else for container in "${APPFACTORY_CONTAINERS[@]}"; do [ -n "$container" ] || continue docker rm -f "$container" >/dev/null 2>&1 || true ok "Removed container: $container" done fi log "Removing existing AppFactory root" rm -rf "$APPFACTORY_ROOT" log "Recreating AppFactory root" mkdir -p "$APPFACTORY_ROOT" log "Extracting backup" cd / tar -xzf "$BACKUP_FILE" [ -d "$APPFACTORY_ROOT" ] || fail "Backup did not create $APPFACTORY_ROOT" log "Ensuring required directories" mkdir -p \ "$APPFACTORY_ROOT/apps" \ "$APPFACTORY_ROOT/backups" \ "$APPFACTORY_ROOT/config" \ "$APPFACTORY_ROOT/data" \ "$APPFACTORY_ROOT/deploy" \ "$APPFACTORY_ROOT/gateway" \ "$APPFACTORY_ROOT/services" \ "$APPFACTORY_ROOT/templates" \ "$APPFACTORY_ROOT/tools" \ "$APPFACTORY_ROOT/workspace" ENV_FILE="$APPFACTORY_ROOT/config/appfactory.env" [ -f "$ENV_FILE" ] || fail "Missing env file after restore: $ENV_FILE" log "Updating runtime ids in appfactory.env" set_env_value() { local key="$1" local value="$2" if grep -q "^${key}=" "$ENV_FILE"; then sed -i "s|^${key}=.*|${key}=${value}|" "$ENV_FILE" else echo "${key}=${value}" >> "$ENV_FILE" fi } set_env_value "APPFACTORY_UID" "$APPFACTORY_UID" set_env_value "APPFACTORY_GID" "$APPFACTORY_GID" set_env_value "APPFACTORY_DOCKER_GID" "$APPFACTORY_DOCKER_GID" grep -q '^APPFACTORY_ENABLE_HTTPS=' "$ENV_FILE" || echo 'APPFACTORY_ENABLE_HTTPS=false' >> "$ENV_FILE" grep -q '^APPFACTORY_DOMAIN=' "$ENV_FILE" || echo 'APPFACTORY_DOMAIN=' >> "$ENV_FILE" grep -q '^APPFACTORY_PORTAL_DOMAIN=' "$ENV_FILE" || echo 'APPFACTORY_PORTAL_DOMAIN=' >> "$ENV_FILE" grep -q '^APPFACTORY_GITEA_DOMAIN=' "$ENV_FILE" || echo 'APPFACTORY_GITEA_DOMAIN=' >> "$ENV_FILE" grep -q '^APPFACTORY_REGISTRY_DOMAIN=' "$ENV_FILE" || echo 'APPFACTORY_REGISTRY_DOMAIN=' >> "$ENV_FILE" grep -q '^GOOGLE_CLIENT_ID=' "$ENV_FILE" || echo 'GOOGLE_CLIENT_ID=' >> "$ENV_FILE" grep -q '^GOOGLE_CLIENT_SECRET=' "$ENV_FILE" || echo 'GOOGLE_CLIENT_SECRET=' >> "$ENV_FILE" grep -q '^GOOGLE_REDIRECT_URI=' "$ENV_FILE" || echo 'GOOGLE_REDIRECT_URI=' >> "$ENV_FILE" log "Fixing ownership" chown -R "$APPFACTORY_UID:$APPFACTORY_GID" "$APPFACTORY_ROOT" log "Fixing script permissions" find "$APPFACTORY_ROOT/workspace/appfactory-tools" -type f -name '*.sh' -exec chmod +x {} \; 2>/dev/null || true BOOTSTRAP="$APPFACTORY_ROOT/workspace/appfactory-tools/maintenance/bootstrap-v2.sh" PREFLIGHT="$APPFACTORY_ROOT/workspace/appfactory-tools/maintenance/preflight-check.sh" GENERATE_CADDY="$APPFACTORY_ROOT/workspace/appfactory-tools/scripts/generate-caddyfile.sh" [ -f "$BOOTSTRAP" ] || fail "Missing bootstrap script: $BOOTSTRAP" [ -f "$PREFLIGHT" ] || fail "Missing preflight script: $PREFLIGHT" chmod +x "$BOOTSTRAP" "$PREFLIGHT" [ -f "$GENERATE_CADDY" ] && chmod +x "$GENERATE_CADDY" log "Running bootstrap repair" sudo -u "$TARGET_USER" "$BOOTSTRAP" repair if [ -f "$GENERATE_CADDY" ]; then log "Generating Caddyfile" sudo -u "$TARGET_USER" "$GENERATE_CADDY" || true fi log "Running bootstrap deploy" sudo -u "$TARGET_USER" "$BOOTSTRAP" deploy log "Running final preflight" sudo -u "$TARGET_USER" "$PREFLIGHT" echo echo "APPFACTORY RESTORE: READY"