#!/usr/bin/env bash # scripts/shutdown.sh # Graceful / safe shutdown helper for tdc114plus development environment # Usage: ./scripts/shutdown.sh [--dry-run] [--auto] set -euo pipefail ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" BARON_DIR="${BARON_SSO_WORKTREE:-/home/ubuntu/workspace/baron-sso-tdc114plus-api}" LOG_BASE_DIR="${TDC114_LOG_BASE:-$ROOT_DIR/logs}" LOG_DIR="$LOG_BASE_DIR/$(date +%F)" LOG_FILE="$LOG_DIR/shutdown.log" DOCKER_BIN="${DOCKER_BIN:-docker}" ADB_BIN="${ADB_BIN:-adb}" ADB_DISCONNECT_ADDRESS="${TDC114_ADB_CONNECT_ADDRESS:-${TDC114_STARTUP_ANDROID_ADDRESS:-}}" ADB_SERVER_SOCKET_VALUE="${ADB_SERVER_SOCKET:-}" PKILL_BIN="${PKILL_BIN:-pkill}" CHMOD_BIN="${CHMOD_BIN:-chmod}" CHOWN_BIN="${CHOWN_BIN:-chown}" AUTH_PORT="${TDC114_AUTH_PORT:-5001}" DRY_RUN=true AUTO=false for arg in "$@"; do case "$arg" in --dry-run) DRY_RUN=true ;; --auto) DRY_RUN=false; AUTO=true ;; --help|-h) cat <&2; exit 2 ;; esac done mkdir -p "$LOG_DIR" log() { echo "$*" | tee -a "$LOG_FILE" } action() { log "+ $*" if [ "$DRY_RUN" = false ]; then set +e bash -lc "$*" 2>&1 | tee -a "$LOG_FILE" local rc=${PIPESTATUS[0]} set -e return "$rc" fi } action_cmd() { log "+ $*" if [ "$DRY_RUN" = false ]; then set +e "$@" 2>&1 | tee -a "$LOG_FILE" local rc=${PIPESTATUS[0]} set -e return "$rc" fi } compose_cmd() { printf "%s compose -f docker-compose.yaml -f compose.infra.yaml -f compose.ory.yaml %s" \ "$DOCKER_BIN" "$1" } log "Shutdown started: $(date)" # 1) Stop only tdc114plus-related helper processes. action_cmd "$PKILL_BIN" -f "$ROOT_DIR/scripts/integration_tests.sh" || true action_cmd "$PKILL_BIN" -f "$ROOT_DIR/scripts/flutter-docker.sh" || true action "lsof -nP -iTCP:$AUTH_PORT -sTCP:LISTEN -t 2>/dev/null | xargs -r kill || true" # 2) Disconnect adb only when the current target address is explicit. if [ -n "$ADB_DISCONNECT_ADDRESS" ]; then action_cmd env TDC114_ADB_CONNECT_ADDRESS="$ADB_DISCONNECT_ADDRESS" "$ADB_BIN" disconnect "$ADB_DISCONNECT_ADDRESS" || true else log "Skipping adb disconnect because TDC114_ADB_CONNECT_ADDRESS is not set." if [ -n "$ADB_SERVER_SOCKET_VALUE" ]; then log "ADB_SERVER_SOCKET is in use; physical USB device remains managed by the shared host ADB server." else log "No explicit Android target connection was provided for disconnect." fi fi # 3) Save compose logs before bringing the stack down. action "cd '$BARON_DIR' && $(compose_cmd "logs --no-color") > '$LOG_DIR/baron-compose.log' 2>&1 || true" # 4) Docker compose down for Baron SSO (safe stop). action "cd '$BARON_DIR' && $(compose_cmd "down")" # 5) Optional: force remove old containers (only when --auto). if [ "$AUTO" = true ]; then action "$DOCKER_BIN ps -a --format '{{.Names}}' | grep -iE 'baron|ory|tdc114' | xargs -r $DOCKER_BIN rm -f || true" else log "(skipping destructive container rm; pass --auto to enable)" fi # 6) Restore generated config ownership and permissions when needed. action "cd '$BARON_DIR' && $CHMOD_BIN -R u+w config/.generated/ 2>/dev/null || true" action "cd '$BARON_DIR' && $CHOWN_BIN -R \$(id -u):\$(id -g) config/.generated/ 2>/dev/null || true" log "Shutdown finished: $(date)" if [ "$DRY_RUN" = true ]; then log "Dry-run mode: no shutdown actions were executed. Use --auto to run for real." fi exit 0