177 lines
5.1 KiB
Bash
Executable File
177 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
###############################################################################
|
|
# 服务器端回滚脚本
|
|
# 此脚本在服务器上执行,由本地回滚脚本远程调用
|
|
###############################################################################
|
|
|
|
set -e
|
|
|
|
# 颜色定义
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
###############################################################################
|
|
# 配置变量(通过环境变量传入)
|
|
###############################################################################
|
|
PRODUCTION_PATH="${PRODUCTION_PATH:-/var/www/valuefrontier.cn}"
|
|
BACKUP_DIR="${BACKUP_DIR:-/home/ubuntu/deployments}"
|
|
|
|
###############################################################################
|
|
# 函数:打印带颜色的消息
|
|
###############################################################################
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
|
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
|
|
###############################################################################
|
|
# 函数:列出可用的备份版本
|
|
###############################################################################
|
|
list_backups() {
|
|
log_info "可用的备份版本:"
|
|
echo ""
|
|
|
|
if [ ! -d "$BACKUP_DIR" ]; then
|
|
log_error "备份目录不存在: $BACKUP_DIR"
|
|
return 1
|
|
fi
|
|
|
|
cd "$BACKUP_DIR"
|
|
|
|
# 获取所有备份目录,按时间倒序
|
|
local backups=($(find . -maxdepth 1 -type d -name "backup-*" | sort -r))
|
|
|
|
if [ ${#backups[@]} -eq 0 ]; then
|
|
log_warning "没有可用的备份版本"
|
|
return 1
|
|
fi
|
|
|
|
local index=1
|
|
for backup in "${backups[@]}"; do
|
|
local backup_name=$(basename "$backup")
|
|
local backup_time=$(echo "$backup_name" | sed 's/backup-//' | sed 's/-/ /')
|
|
local is_current=""
|
|
|
|
# 检查是否是当前版本
|
|
if [ -L "$BACKUP_DIR/current" ]; then
|
|
local current_link=$(readlink "$BACKUP_DIR/current")
|
|
if [ "$current_link" = "$backup" ] || [ "$current_link" = "$BACKUP_DIR/$backup_name" ]; then
|
|
is_current=" ${GREEN}[当前版本]${NC}"
|
|
fi
|
|
fi
|
|
|
|
echo -e " $index. $backup_name ($backup_time)$is_current"
|
|
((index++))
|
|
done
|
|
|
|
echo ""
|
|
return 0
|
|
}
|
|
|
|
###############################################################################
|
|
# 函数:回滚到指定版本
|
|
###############################################################################
|
|
rollback_to_version() {
|
|
local version_index="${1:-1}"
|
|
|
|
log_info "开始回滚到版本 #$version_index..."
|
|
|
|
if [ ! -d "$BACKUP_DIR" ]; then
|
|
log_error "备份目录不存在: $BACKUP_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
cd "$BACKUP_DIR"
|
|
|
|
# 获取所有备份目录,按时间倒序
|
|
local backups=($(find . -maxdepth 1 -type d -name "backup-*" | sort -r))
|
|
|
|
if [ ${#backups[@]} -eq 0 ]; then
|
|
log_error "没有可用的备份版本"
|
|
exit 1
|
|
fi
|
|
|
|
# 检查索引是否有效
|
|
if [ "$version_index" -lt 1 ] || [ "$version_index" -gt "${#backups[@]}" ]; then
|
|
log_error "无效的版本索引: $version_index (可用范围: 1-${#backups[@]})"
|
|
exit 1
|
|
fi
|
|
|
|
# 获取目标备份
|
|
local target_index=$((version_index - 1))
|
|
local target_backup="${backups[$target_index]}"
|
|
local backup_name=$(basename "$target_backup")
|
|
|
|
log_info "目标版本: $backup_name"
|
|
|
|
# 检查备份是否存在
|
|
if [ ! -d "$target_backup" ]; then
|
|
log_error "备份版本不存在: $target_backup"
|
|
exit 1
|
|
fi
|
|
|
|
# 清空生产目录
|
|
log_info "清空生产目录: $PRODUCTION_PATH"
|
|
rm -rf "$PRODUCTION_PATH"/*
|
|
|
|
# 恢复备份
|
|
log_info "恢复备份文件..."
|
|
cp -r "$target_backup"/* "$PRODUCTION_PATH/" || {
|
|
log_error "恢复备份失败"
|
|
exit 1
|
|
}
|
|
|
|
# 设置权限
|
|
chmod -R 755 "$PRODUCTION_PATH"
|
|
|
|
# 更新 current 符号链接
|
|
ln -snf "$target_backup" "$BACKUP_DIR/current"
|
|
|
|
log_success "回滚完成"
|
|
echo ""
|
|
echo "========================================"
|
|
echo " 回滚成功!"
|
|
echo "========================================"
|
|
echo "目标版本: $backup_name"
|
|
echo ""
|
|
|
|
# 输出结果供本地脚本解析
|
|
echo "ROLLBACK_SUCCESS=true"
|
|
echo "ROLLBACK_VERSION=$backup_name"
|
|
}
|
|
|
|
###############################################################################
|
|
# 主函数
|
|
###############################################################################
|
|
main() {
|
|
local action="${1:-list}"
|
|
|
|
echo ""
|
|
echo "========================================"
|
|
echo " 服务器端回滚脚本"
|
|
echo "========================================"
|
|
echo ""
|
|
|
|
case "$action" in
|
|
list)
|
|
list_backups
|
|
;;
|
|
rollback)
|
|
local version_index="${2:-1}"
|
|
rollback_to_version "$version_index"
|
|
;;
|
|
*)
|
|
log_error "未知操作: $action"
|
|
echo "用法: $0 {list|rollback} [version_index]"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# 执行主函数
|
|
main "$@"
|