175 lines
4.7 KiB
Bash
Executable File
175 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ==============================================================================
|
|
# nx9-wg Production Rollback Tool
|
|
# ==============================================================================
|
|
# PURPOSE:
|
|
# Rolls back the active production binary (/usr/local/bin/nx9-wg) to the most
|
|
# recent (or specified) backup binary created during previous deployments.
|
|
#
|
|
# PREREQUISITES:
|
|
# - Root privileges (or sudo)
|
|
# - At least one backup binary at /usr/local/bin/nx9-wg.backup.*
|
|
#
|
|
# SAFETY INVARIANTS:
|
|
# - Never modifies or deletes the SQLite database.
|
|
# - Restores executable permissions (0755) and root ownership.
|
|
# - Confirms service restoration and binary version after rollback.
|
|
#
|
|
# USAGE:
|
|
# sudo bash scripts/rollback.sh [OPTIONS] [SPECIFIC_BACKUP_PATH]
|
|
#
|
|
# OPTIONS:
|
|
# -y, --yes Skip confirmation prompt
|
|
# -l, --list List available backup binaries and exit
|
|
# -h, --help Show this help message
|
|
# ==============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
BIN_DIR="/usr/local/bin"
|
|
ACTIVE_BIN="${BIN_DIR}/nx9-wg"
|
|
ASSUME_YES=0
|
|
LIST_ONLY=0
|
|
SPECIFIED_BACKUP=""
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
nx9-wg Production Rollback Tool
|
|
|
|
Usage:
|
|
sudo bash scripts/rollback.sh [OPTIONS] [BACKUP_FILE]
|
|
|
|
Options:
|
|
-y, --yes Skip interactive confirmation prompt
|
|
-l, --list List available backup binaries and exit
|
|
-h, --help Show this help message
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-y|--yes)
|
|
ASSUME_YES=1
|
|
shift
|
|
;;
|
|
-l|--list)
|
|
LIST_ONLY=1
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
;;
|
|
-*)
|
|
echo "Unknown option: $1" >&2
|
|
usage
|
|
;;
|
|
*)
|
|
SPECIFIED_BACKUP="$1"
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
log() {
|
|
echo -e "\033[1;34m[ROLLBACK]\033[0m \033[1;37m$*\033[0m"
|
|
}
|
|
|
|
success() {
|
|
echo -e "\033[1;32m[SUCCESS]\033[0m $*"
|
|
}
|
|
|
|
warn() {
|
|
echo -e "\033[1;33m[WARN]\033[0m $*"
|
|
}
|
|
|
|
error() {
|
|
echo -e "\033[1;31m[ERROR]\033[0m $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
# 1. Privilege Verification (unless list only)
|
|
if [[ "${EUID}" -ne 0 && "${LIST_ONLY}" -eq 0 ]]; then
|
|
error "Rollback must be run as root (or via sudo)."
|
|
fi
|
|
|
|
# 2. Discover Available Backups
|
|
BACKUPS=($(ls -1t "${ACTIVE_BIN}".backup.* 2>/dev/null || true))
|
|
|
|
if [[ "${#BACKUPS[@]}" -eq 0 ]]; then
|
|
error "No backup binaries found in ${BIN_DIR} matching nx9-wg.backup.*"
|
|
fi
|
|
|
|
if [[ "${LIST_ONLY}" -eq 1 ]]; then
|
|
echo "Available production backup binaries in ${BIN_DIR}:"
|
|
for b in "${BACKUPS[@]}"; do
|
|
SIZE="$(du -h "$b" | cut -f1)"
|
|
DATE="$(date -r "$b" '+%Y-%m-%d %H:%M:%S')"
|
|
echo " $b (${SIZE}, ${DATE})"
|
|
done
|
|
exit 0
|
|
fi
|
|
|
|
# 3. Select Target Backup
|
|
TARGET_BACKUP=""
|
|
if [[ -n "${SPECIFIED_BACKUP}" ]]; then
|
|
if [[ -f "${SPECIFIED_BACKUP}" ]]; then
|
|
TARGET_BACKUP="${SPECIFIED_BACKUP}"
|
|
elif [[ -f "${BIN_DIR}/${SPECIFIED_BACKUP}" ]]; then
|
|
TARGET_BACKUP="${BIN_DIR}/${SPECIFIED_BACKUP}"
|
|
else
|
|
error "Specified backup file not found: ${SPECIFIED_BACKUP}"
|
|
fi
|
|
else
|
|
TARGET_BACKUP="${BACKUPS[0]}"
|
|
fi
|
|
|
|
log "Selected rollback target: ${TARGET_BACKUP}"
|
|
BACKUP_SIZE="$(du -h "${TARGET_BACKUP}" | cut -f1)"
|
|
BACKUP_DATE="$(date -r "${TARGET_BACKUP}" '+%Y-%m-%d %H:%M:%S')"
|
|
echo " Size: ${BACKUP_SIZE}"
|
|
echo " Timestamp: ${BACKUP_DATE}"
|
|
|
|
# 4. Confirmation Prompt
|
|
if [[ "${ASSUME_YES}" -eq 0 ]]; then
|
|
echo -e "\n\033[1;33mAre you sure you want to replace active binary ${ACTIVE_BIN} with ${TARGET_BACKUP}?\033[0m"
|
|
read -r -p "Type 'yes' to proceed with rollback: " CONFIRM
|
|
if [[ "${CONFIRM}" != "yes" ]]; then
|
|
error "Rollback aborted by user."
|
|
fi
|
|
fi
|
|
|
|
# 5. Execute Rollback
|
|
if command -v systemctl >/dev/null 2>&1; then
|
|
if systemctl is-active --quiet nx9-wg 2>/dev/null; then
|
|
log "Stopping nx9-wg service..."
|
|
systemctl stop nx9-wg || true
|
|
fi
|
|
fi
|
|
|
|
log "Restoring binary from ${TARGET_BACKUP} to ${ACTIVE_BIN}..."
|
|
install -m 0755 "${TARGET_BACKUP}" "${ACTIVE_BIN}"
|
|
|
|
# 6. Restart Service
|
|
if command -v systemctl >/dev/null 2>&1; then
|
|
log "Starting nx9-wg service..."
|
|
systemctl start nx9-wg || error "Failed to restart nx9-wg service after rollback."
|
|
sleep 1
|
|
|
|
if systemctl is-active --quiet nx9-wg; then
|
|
success "nx9-wg.service is active and running."
|
|
else
|
|
warn "nx9-wg.service is not active. Checking logs:"
|
|
journalctl -u nx9-wg -n 20 --no-pager || true
|
|
error "Service failed to become active after rollback."
|
|
fi
|
|
fi
|
|
|
|
# 7. Verify Restored Version
|
|
RESTORED_VER="$("${ACTIVE_BIN}" version | head -n 1)"
|
|
success "Rollback successful. Active binary version: ${RESTORED_VER}"
|
|
|
|
echo -e "\n================================================================="
|
|
echo -e "\033[1;32m PRODUCTION ROLLBACK COMPLETED SUCCESSFULLY!\033[0m"
|
|
echo -e "=================================================================\n"
|