chore: 可以实现应用补丁及回滚操作
This commit is contained in:
@@ -7,7 +7,9 @@ shopt -s nullglob extglob
|
||||
# 脚本目录
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/patch_config.sh"
|
||||
LOG_FILE="/var/log/patch_system/apply_$(date +%Y%m%d_%H%M%S).log"
|
||||
LOCK_FILE="/tmp/patch_apply.lock"
|
||||
ROLLBACK_INFO_DIR="/var/lib/patch_system/rollback_info"
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
@@ -53,21 +55,25 @@ load_config() {
|
||||
|
||||
# 设置默认值
|
||||
: ${LOG_LEVEL:="INFO"}
|
||||
: ${LOG_FILE:="/tmp/patch_apply_$(date +%Y%m%d_%H%M%S).log"}
|
||||
: ${BACKUP_DIR:="/var/backups/patch"}
|
||||
: ${TEMP_DIR:="/tmp/patch_apply_$$"}
|
||||
: ${ROLLBACK_ENABLED:="true"}
|
||||
: ${ROLLBACK_INFO_DIR:="/var/lib/patch_system/rollback_info"}
|
||||
: ${VALIDATION_ENABLED:="true"}
|
||||
: ${NOTIFICATIONS_ENABLED:="true"}
|
||||
: ${ATOMIC_OPERATIONS:="true"}
|
||||
: ${MAX_BACKUP_COUNT:=10}
|
||||
: ${MAX_BACKUP_COUNT:=10}
|
||||
: ${PATCH_STAGING_DIR:="/tmp/patch_staging"}
|
||||
}
|
||||
|
||||
setup_environment() {
|
||||
mkdir -p "$(dirname "$LOG_FILE")"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
mkdir -p "$TEMP_DIR"
|
||||
mkdir -p "$ROLLBACK_INFO_DIR"
|
||||
mkdir -p "$PATCH_STAGING_DIR"
|
||||
|
||||
info "环境设置完成"
|
||||
info "日志文件: $LOG_FILE"
|
||||
info "备份目录: $BACKUP_DIR"
|
||||
info "临时目录: $TEMP_DIR"
|
||||
@@ -127,7 +133,7 @@ trap cleanup EXIT INT TERM
|
||||
|
||||
# 依赖检查
|
||||
check_dependencies() {
|
||||
local deps=("tar" "gzip" "sha256sum" "cp" "mkdir" "find")
|
||||
local deps=("tar" "gzip" "find" "stat" "sha256sum" "date" "mkdir" "cp" "jq")
|
||||
local missing=()
|
||||
|
||||
for dep in "${deps[@]}"; do
|
||||
@@ -639,6 +645,7 @@ create_rollback_point() {
|
||||
local patch_file="$1"
|
||||
local backup_file="$2"
|
||||
local extract_dir="$3"
|
||||
local changes_file="$4"
|
||||
|
||||
if [[ "$ROLLBACK_ENABLED" != "true" ]]; then
|
||||
info "回滚功能已禁用"
|
||||
@@ -647,31 +654,94 @@ create_rollback_point() {
|
||||
|
||||
info "🔄 创建回滚点..."
|
||||
|
||||
local rollback_info_file="$BACKUP_DIR/rollback_info.json"
|
||||
local patch_name=$(basename "$patch_file")
|
||||
local patch_name=$(basename "$patch_file" .tar.gz)
|
||||
local timestamp=$(date +%Y%m%d_%H%M%S)
|
||||
local rollback_info_file="$ROLLBACK_INFO_DIR/${patch_name}_${timestamp}.json"
|
||||
|
||||
# 读取清单信息
|
||||
local manifest_file="$extract_dir/MANIFEST.MF"
|
||||
local patch_info=""
|
||||
if [[ -f "$manifest_file" ]]; then
|
||||
patch_info=$(grep -E "^(名称|版本|描述):" "$manifest_file" | head -3)
|
||||
patch_info=$(grep -E "^(名称|版本|描述):" "$manifest_file" | head -3 | tr '\n' ';')
|
||||
fi
|
||||
|
||||
# 统计变更类型
|
||||
local added_count=$(grep -c "^ADDED" "$changes_file")
|
||||
local modified_count=$(grep -c "^MODIFIED" "$changes_file")
|
||||
local deleted_count=$(grep -c "^DELETED" "$changes_file")
|
||||
|
||||
# 创建回滚信息JSON
|
||||
local rollback_info=$(cat << EOF
|
||||
{
|
||||
"patch_name": "$patch_name",
|
||||
"apply_time": "$(date -Iseconds)",
|
||||
"backup_path": "$backup_file",
|
||||
"rollback_dir": "$BACKUP_DIR/rollback_$timestamp",
|
||||
"manifest_info": "$(echo "$patch_info" | tr '\n' ';')",
|
||||
"status": "applied"
|
||||
"manifest_info": "$patch_info",
|
||||
"status": "applied",
|
||||
"changes": {
|
||||
"added": $added_count,
|
||||
"modified": $modified_count,
|
||||
"deleted": $deleted_count,
|
||||
"total": $((added_count + modified_count + deleted_count))
|
||||
},
|
||||
"system_info": {
|
||||
"hostname": "$(hostname)",
|
||||
"user": "$(whoami)",
|
||||
"working_directory": "$PWD"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
echo "$rollback_info" > "$rollback_info_file"
|
||||
info "✅ 回滚点创建完成: $rollback_info_file"
|
||||
|
||||
# 清理旧回滚点
|
||||
cleanup_old_rollback_points
|
||||
}
|
||||
|
||||
# 清理旧回滚点
|
||||
cleanup_old_rollback_points() {
|
||||
local max_points="${1:-$MAX_BACKUP_COUNT}"
|
||||
|
||||
info "🧹 清理旧回滚点 (保留最近 $max_points 个)"
|
||||
|
||||
if [[ ! -d "$ROLLBACK_INFO_DIR" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 获取所有回滚点并按时间排序
|
||||
local points=($(find "$ROLLBACK_INFO_DIR" -name "*.json" -type f -printf "%T@|%p\n" | sort -rn | cut -d'|' -f2))
|
||||
local total_points=${#points[@]}
|
||||
local points_to_remove=$((total_points - max_points))
|
||||
|
||||
if [[ $points_to_remove -le 0 ]]; then
|
||||
debug "无需清理,当前 $total_points 个回滚点"
|
||||
return 0
|
||||
fi
|
||||
|
||||
info "清理 $points_to_remove 个旧回滚点"
|
||||
|
||||
for ((i=max_points; i<total_points; i++)); do
|
||||
local old_file="${points[$i]}"
|
||||
if [[ -f "$old_file" ]]; then
|
||||
# 获取备份文件路径
|
||||
local backup_path=$(jq -r '.backup_path // ""' "$old_file")
|
||||
|
||||
# 删除备份文件
|
||||
if [[ -n "$backup_path" && -f "$backup_path" ]]; then
|
||||
rm -f "$backup_path"
|
||||
debug "删除备份文件: $(basename "$backup_path")"
|
||||
fi
|
||||
|
||||
# 删除回滚信息文件
|
||||
rm -f "$old_file"
|
||||
info "🗑️ 清理回滚点: $(basename "$old_file")"
|
||||
fi
|
||||
done
|
||||
|
||||
info "✅ 回滚点清理完成"
|
||||
}
|
||||
|
||||
# 发送通知
|
||||
@@ -806,7 +876,7 @@ apply_patch() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 创建备份
|
||||
# 创建备份文件(非干跑模式)
|
||||
local backup_file=""
|
||||
if [[ "$dry_run" != "true" ]]; then
|
||||
info ">>创建备份..."
|
||||
@@ -834,7 +904,7 @@ apply_patch() {
|
||||
|
||||
# 创建回滚点
|
||||
info ">>创建回滚点..."
|
||||
create_rollback_point "$patch_file" "$backup_file" "$extract_dir"
|
||||
create_rollback_point "$patch_file" "$backup_file" "$extract_dir" "$changes_file"
|
||||
fi
|
||||
|
||||
send_notification "success" "$patch_file" "补丁应用成功"
|
||||
@@ -854,6 +924,7 @@ usage() {
|
||||
-v, --verbose 详细输出
|
||||
-q, --quiet 安静模式
|
||||
-h, --help 显示此帮助
|
||||
-V, --version 显示版本
|
||||
|
||||
示例:
|
||||
$0 patch.tar.gz # 应用补丁
|
||||
@@ -870,6 +941,13 @@ usage() {
|
||||
EOF
|
||||
}
|
||||
|
||||
# 显示版本信息
|
||||
show_version() {
|
||||
echo "patch_applier.sh v2.0.0"
|
||||
echo "企业级补丁应用系统"
|
||||
echo "支持原子性操作、完整验证、智能回滚点创建"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
local patch_file=""
|
||||
@@ -910,6 +988,10 @@ main() {
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-V|--version)
|
||||
show_version
|
||||
exit 0
|
||||
;;
|
||||
-*)
|
||||
error "未知选项: $1"
|
||||
usage
|
||||
|
||||
Reference in New Issue
Block a user