172 lines
5.1 KiB
Bash
Executable File
172 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Emergency Rollback Script
|
|
# Purpose: Fast rollback with minimal user interaction
|
|
#
|
|
# Usage:
|
|
# ./scripts/emergency-rollback.sh # Interactive mode
|
|
# ./scripts/emergency-rollback.sh <image-tag> # Direct rollback
|
|
# ./scripts/emergency-rollback.sh list # List available tags
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
|
ANSIBLE_DIR="${PROJECT_ROOT}/deployment/ansible"
|
|
INVENTORY="${ANSIBLE_DIR}/inventory/production.yml"
|
|
|
|
PRODUCTION_SERVER="94.16.110.151"
|
|
REGISTRY="git.michaelschiemer.de:5000"
|
|
IMAGE="framework"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1" >&2
|
|
}
|
|
|
|
log_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
}
|
|
|
|
log_info() {
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|
}
|
|
|
|
# List available image tags
|
|
list_tags() {
|
|
log_info "Fetching available image tags from production..."
|
|
|
|
ssh -i ~/.ssh/production deploy@"${PRODUCTION_SERVER}" \
|
|
"docker images ${REGISTRY}/${IMAGE} --format '{{.Tag}}' | grep -v buildcache | head -20"
|
|
|
|
echo ""
|
|
log_info "Current running version:"
|
|
ssh -i ~/.ssh/production deploy@"${PRODUCTION_SERVER}" \
|
|
"docker service inspect framework_web --format '{{.Spec.TaskTemplate.ContainerSpec.Image}}'"
|
|
}
|
|
|
|
# Get current image tag
|
|
get_current_tag() {
|
|
ssh -i ~/.ssh/production deploy@"${PRODUCTION_SERVER}" \
|
|
"docker service inspect framework_web --format '{{.Spec.TaskTemplate.ContainerSpec.Image}}' | cut -d':' -f2"
|
|
}
|
|
|
|
# Emergency rollback
|
|
emergency_rollback() {
|
|
local target_tag="$1"
|
|
|
|
echo ""
|
|
log_warn "╔════════════════════════════════════════════════════════╗"
|
|
log_warn "║ 🚨 EMERGENCY ROLLBACK INITIATED 🚨 ║"
|
|
log_warn "╚════════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
|
|
local current_tag=$(get_current_tag)
|
|
|
|
echo "Current Version: ${current_tag}"
|
|
echo "Target Version: ${target_tag}"
|
|
echo ""
|
|
|
|
if [[ "${current_tag}" == "${target_tag}" ]]; then
|
|
log_warn "Already running ${target_tag}. No rollback needed."
|
|
exit 0
|
|
fi
|
|
|
|
log_warn "This will immediately rollback production WITHOUT health checks."
|
|
log_warn "Use only in emergency situations."
|
|
echo ""
|
|
read -p "Type 'ROLLBACK' to confirm: " -r
|
|
|
|
if [[ ! "$REPLY" == "ROLLBACK" ]]; then
|
|
log_info "Rollback cancelled"
|
|
exit 0
|
|
fi
|
|
|
|
log_info "Executing emergency rollback via Ansible..."
|
|
|
|
cd "${ANSIBLE_DIR}"
|
|
|
|
ansible-playbook \
|
|
-i "${INVENTORY}" \
|
|
playbooks/emergency-rollback.yml \
|
|
-e "rollback_tag=${target_tag}"
|
|
|
|
echo ""
|
|
log_warn "╔════════════════════════════════════════════════════════╗"
|
|
log_warn "║ MANUAL VERIFICATION REQUIRED ║"
|
|
log_warn "╚════════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
log_warn "1. Check application: https://michaelschiemer.de"
|
|
log_warn "2. Run health check: cd deployment && ansible-playbook -i ansible/inventory/production.yml ansible/playbooks/health-check.yml"
|
|
log_warn "3. Check service logs: ssh deploy@${PRODUCTION_SERVER} 'docker service logs framework_web --tail 100'"
|
|
echo ""
|
|
}
|
|
|
|
# Interactive mode
|
|
interactive_rollback() {
|
|
log_info "🚨 Emergency Rollback - Interactive Mode"
|
|
echo ""
|
|
|
|
log_info "Available image tags (last 20):"
|
|
list_tags
|
|
echo ""
|
|
|
|
read -p "Enter image tag to rollback to: " -r target_tag
|
|
|
|
if [[ -z "$target_tag" ]]; then
|
|
log_error "No tag provided"
|
|
exit 1
|
|
fi
|
|
|
|
emergency_rollback "$target_tag"
|
|
}
|
|
|
|
# Main
|
|
main() {
|
|
case "${1:-interactive}" in
|
|
list)
|
|
list_tags
|
|
;;
|
|
interactive)
|
|
interactive_rollback
|
|
;;
|
|
help|--help|-h)
|
|
cat <<EOF
|
|
Emergency Rollback Script
|
|
|
|
Usage: $0 [command|tag]
|
|
|
|
Commands:
|
|
list List available image tags on production
|
|
interactive Interactive rollback mode (default)
|
|
<image-tag> Direct rollback to specific tag
|
|
help Show this help
|
|
|
|
Examples:
|
|
$0 list # List available versions
|
|
$0 # Interactive mode
|
|
$0 abc1234-123456 # Rollback to specific tag
|
|
|
|
Emergency Procedures:
|
|
1. List versions: $0 list
|
|
2. Choose version: $0 <tag>
|
|
3. Verify manually: https://michaelschiemer.de
|
|
4. Run health check: cd deployment && ansible-playbook -i ansible/inventory/production.yml ansible/playbooks/health-check.yml
|
|
|
|
EOF
|
|
;;
|
|
*)
|
|
# Direct rollback with provided tag
|
|
emergency_rollback "$1"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|