#!/bin/bash # Rollback procedures for fetch_ml deployments set -e REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) DEPLOYMENTS_DIR="${REPO_ROOT}/deployments" # Colors GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' print_success() { echo -e "${GREEN}[OK]${NC} $1"; } print_error() { echo -e "${RED}[ERROR]${NC} $1"; } print_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } print_info() { echo -e "[INFO] $1"; } show_usage() { echo "Usage: $0 [ENVIRONMENT]" echo "" echo "Environments:" echo " staging Rollback staging environment" echo " prod Rollback production environment" echo "" echo "Examples:" echo " $0 staging # Rollback staging" echo " $0 prod # Rollback production (requires confirmation)" } rollback_environment() { local env=$1 local compose_file case $env in staging) compose_file="${DEPLOYMENTS_DIR}/docker compose.staging.yml" ;; prod) compose_file="${DEPLOYMENTS_DIR}/docker compose.prod.yml" ;; *) print_error "Unknown environment: $env" show_usage exit 1 ;; esac if [ ! -f "$compose_file" ]; then print_error "Compose file not found: $compose_file" exit 1 fi print_warn "Rolling back ${env} environment..." print_warn "⚠ This rolls back the image only - queue state and audit log are NOT rolled back" if [ "$env" = "prod" ]; then print_warn "⚠ CRITICAL: Production rollback" print_warn "⚠ Queue state is NOT rolled back" print_warn "⚠ Audit log chain is NOT rolled back (must never break chain)" print_warn "⚠ New artifacts remain in storage" read -p "CONFIRM PRODUCTION ROLLBACK? [yes/N] " confirm if [ "$confirm" != "yes" ]; then print_error "Rollback cancelled" exit 1 fi else read -p "Continue with rollback? [y/N] " confirm if [ "$confirm" != "y" ]; then print_error "Rollback cancelled" exit 1 fi fi # Get previous deployment info from audit log local log_file="${DEPLOYMENTS_DIR}/.${env}-audit.log" local previous_sha="" if [ -f "$log_file" ]; then previous_sha=$(tail -2 "$log_file" | head -1 | grep -o 'sha-[a-f0-9]*' || echo "") if [ -n "$previous_sha" ]; then print_info "Previous deployment: $previous_sha" fi fi # Perform rollback print_info "Stopping ${env} environment..." docker compose -f "$compose_file" down print_info "Starting ${env} environment..." docker compose -f "$compose_file" up -d # Log the rollback echo "$(date -Iseconds) | rollback | ${env} | actor=$(whoami)" >> "$log_file" 2>/dev/null || true print_success "${env} rollback complete!" print_info "Verify health with: ./scripts/deploy/health-check.sh ${env}" } main() { if [ $# -ne 1 ]; then show_usage exit 1 fi rollback_environment "$1" } main "$@"