chore: 可以实现应用补丁及回滚操作
This commit is contained in:
@@ -89,7 +89,6 @@ install_dependencies() {
|
|||||||
"jq"
|
"jq"
|
||||||
"gpg"
|
"gpg"
|
||||||
"bc"
|
"bc"
|
||||||
"gnupg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for dep in "${dependencies[@]}"; do
|
for dep in "${dependencies[@]}"; do
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ shopt -s nullglob extglob
|
|||||||
# 脚本目录
|
# 脚本目录
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
CONFIG_FILE="${SCRIPT_DIR}/patch_config.sh"
|
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"
|
LOCK_FILE="/tmp/patch_apply.lock"
|
||||||
|
ROLLBACK_INFO_DIR="/var/lib/patch_system/rollback_info"
|
||||||
|
|
||||||
# 颜色定义
|
# 颜色定义
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
@@ -53,21 +55,25 @@ load_config() {
|
|||||||
|
|
||||||
# 设置默认值
|
# 设置默认值
|
||||||
: ${LOG_LEVEL:="INFO"}
|
: ${LOG_LEVEL:="INFO"}
|
||||||
: ${LOG_FILE:="/tmp/patch_apply_$(date +%Y%m%d_%H%M%S).log"}
|
|
||||||
: ${BACKUP_DIR:="/var/backups/patch"}
|
: ${BACKUP_DIR:="/var/backups/patch"}
|
||||||
: ${TEMP_DIR:="/tmp/patch_apply_$$"}
|
: ${TEMP_DIR:="/tmp/patch_apply_$$"}
|
||||||
: ${ROLLBACK_ENABLED:="true"}
|
: ${ROLLBACK_ENABLED:="true"}
|
||||||
|
: ${ROLLBACK_INFO_DIR:="/var/lib/patch_system/rollback_info"}
|
||||||
: ${VALIDATION_ENABLED:="true"}
|
: ${VALIDATION_ENABLED:="true"}
|
||||||
: ${NOTIFICATIONS_ENABLED:="true"}
|
: ${NOTIFICATIONS_ENABLED:="true"}
|
||||||
: ${ATOMIC_OPERATIONS:="true"}
|
: ${ATOMIC_OPERATIONS:="true"}
|
||||||
: ${MAX_BACKUP_COUNT:=10}
|
: ${MAX_BACKUP_COUNT:=10}
|
||||||
|
: ${PATCH_STAGING_DIR:="/tmp/patch_staging"}
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_environment() {
|
setup_environment() {
|
||||||
mkdir -p "$(dirname "$LOG_FILE")"
|
mkdir -p "$(dirname "$LOG_FILE")"
|
||||||
mkdir -p "$BACKUP_DIR"
|
mkdir -p "$BACKUP_DIR"
|
||||||
mkdir -p "$TEMP_DIR"
|
mkdir -p "$TEMP_DIR"
|
||||||
|
mkdir -p "$ROLLBACK_INFO_DIR"
|
||||||
|
mkdir -p "$PATCH_STAGING_DIR"
|
||||||
|
|
||||||
|
info "环境设置完成"
|
||||||
info "日志文件: $LOG_FILE"
|
info "日志文件: $LOG_FILE"
|
||||||
info "备份目录: $BACKUP_DIR"
|
info "备份目录: $BACKUP_DIR"
|
||||||
info "临时目录: $TEMP_DIR"
|
info "临时目录: $TEMP_DIR"
|
||||||
@@ -127,7 +133,7 @@ trap cleanup EXIT INT TERM
|
|||||||
|
|
||||||
# 依赖检查
|
# 依赖检查
|
||||||
check_dependencies() {
|
check_dependencies() {
|
||||||
local deps=("tar" "gzip" "sha256sum" "cp" "mkdir" "find")
|
local deps=("tar" "gzip" "find" "stat" "sha256sum" "date" "mkdir" "cp" "jq")
|
||||||
local missing=()
|
local missing=()
|
||||||
|
|
||||||
for dep in "${deps[@]}"; do
|
for dep in "${deps[@]}"; do
|
||||||
@@ -639,6 +645,7 @@ create_rollback_point() {
|
|||||||
local patch_file="$1"
|
local patch_file="$1"
|
||||||
local backup_file="$2"
|
local backup_file="$2"
|
||||||
local extract_dir="$3"
|
local extract_dir="$3"
|
||||||
|
local changes_file="$4"
|
||||||
|
|
||||||
if [[ "$ROLLBACK_ENABLED" != "true" ]]; then
|
if [[ "$ROLLBACK_ENABLED" != "true" ]]; then
|
||||||
info "回滚功能已禁用"
|
info "回滚功能已禁用"
|
||||||
@@ -647,31 +654,94 @@ create_rollback_point() {
|
|||||||
|
|
||||||
info "🔄 创建回滚点..."
|
info "🔄 创建回滚点..."
|
||||||
|
|
||||||
local rollback_info_file="$BACKUP_DIR/rollback_info.json"
|
local patch_name=$(basename "$patch_file" .tar.gz)
|
||||||
local patch_name=$(basename "$patch_file")
|
|
||||||
local timestamp=$(date +%Y%m%d_%H%M%S)
|
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 manifest_file="$extract_dir/MANIFEST.MF"
|
||||||
local patch_info=""
|
local patch_info=""
|
||||||
if [[ -f "$manifest_file" ]]; then
|
if [[ -f "$manifest_file" ]]; then
|
||||||
patch_info=$(grep -E "^(名称|版本|描述):" "$manifest_file" | head -3)
|
patch_info=$(grep -E "^(名称|版本|描述):" "$manifest_file" | head -3 | tr '\n' ';')
|
||||||
fi
|
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
|
local rollback_info=$(cat << EOF
|
||||||
{
|
{
|
||||||
"patch_name": "$patch_name",
|
"patch_name": "$patch_name",
|
||||||
"apply_time": "$(date -Iseconds)",
|
"apply_time": "$(date -Iseconds)",
|
||||||
"backup_path": "$backup_file",
|
"backup_path": "$backup_file",
|
||||||
"rollback_dir": "$BACKUP_DIR/rollback_$timestamp",
|
"rollback_dir": "$BACKUP_DIR/rollback_$timestamp",
|
||||||
"manifest_info": "$(echo "$patch_info" | tr '\n' ';')",
|
"manifest_info": "$patch_info",
|
||||||
"status": "applied"
|
"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
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
echo "$rollback_info" > "$rollback_info_file"
|
echo "$rollback_info" > "$rollback_info_file"
|
||||||
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
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 创建备份
|
# 创建备份文件(非干跑模式)
|
||||||
local backup_file=""
|
local backup_file=""
|
||||||
if [[ "$dry_run" != "true" ]]; then
|
if [[ "$dry_run" != "true" ]]; then
|
||||||
info ">>创建备份..."
|
info ">>创建备份..."
|
||||||
@@ -834,7 +904,7 @@ apply_patch() {
|
|||||||
|
|
||||||
# 创建回滚点
|
# 创建回滚点
|
||||||
info ">>创建回滚点..."
|
info ">>创建回滚点..."
|
||||||
create_rollback_point "$patch_file" "$backup_file" "$extract_dir"
|
create_rollback_point "$patch_file" "$backup_file" "$extract_dir" "$changes_file"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
send_notification "success" "$patch_file" "补丁应用成功"
|
send_notification "success" "$patch_file" "补丁应用成功"
|
||||||
@@ -854,6 +924,7 @@ usage() {
|
|||||||
-v, --verbose 详细输出
|
-v, --verbose 详细输出
|
||||||
-q, --quiet 安静模式
|
-q, --quiet 安静模式
|
||||||
-h, --help 显示此帮助
|
-h, --help 显示此帮助
|
||||||
|
-V, --version 显示版本
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
$0 patch.tar.gz # 应用补丁
|
$0 patch.tar.gz # 应用补丁
|
||||||
@@ -870,6 +941,13 @@ usage() {
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 显示版本信息
|
||||||
|
show_version() {
|
||||||
|
echo "patch_applier.sh v2.0.0"
|
||||||
|
echo "企业级补丁应用系统"
|
||||||
|
echo "支持原子性操作、完整验证、智能回滚点创建"
|
||||||
|
}
|
||||||
|
|
||||||
# 主函数
|
# 主函数
|
||||||
main() {
|
main() {
|
||||||
local patch_file=""
|
local patch_file=""
|
||||||
@@ -910,6 +988,10 @@ main() {
|
|||||||
usage
|
usage
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
-V|--version)
|
||||||
|
show_version
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
-*)
|
-*)
|
||||||
error "未知选项: $1"
|
error "未知选项: $1"
|
||||||
usage
|
usage
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ ENCRYPTION_IV="/etc/patch/keys/encryption.iv" # 加密初始化向量文件路
|
|||||||
BACKUP_ENABLED=true # 是否启用备份
|
BACKUP_ENABLED=true # 是否启用备份
|
||||||
BACKUP_STRATEGY="full" # 备份策略,full, incremental, differential
|
BACKUP_STRATEGY="full" # 备份策略,full, incremental, differential
|
||||||
BACKUP_RETENTION_DAYS=30 # 备份保留天数
|
BACKUP_RETENTION_DAYS=30 # 备份保留天数
|
||||||
|
BACKUP_DIR="/var/backups/patch" # 备份目录
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# 回滚配置 - 定义是否启用自动回滚和回滚策略
|
# 回滚配置 - 定义是否启用自动回滚和回滚策略
|
||||||
@@ -130,6 +131,7 @@ BACKUP_RETENTION_DAYS=30 # 备份保留天数
|
|||||||
ROLLBACK_ENABLED=true # 是否启用自动回滚
|
ROLLBACK_ENABLED=true # 是否启用自动回滚
|
||||||
ROLLBACK_AUTO_GENERATE=true # 是否自动生成回滚脚本
|
ROLLBACK_AUTO_GENERATE=true # 是否自动生成回滚脚本
|
||||||
ROLLBACK_STRATEGY="snapshot" # 回滚策略,snapshot, restore
|
ROLLBACK_STRATEGY="snapshot" # 回滚策略,snapshot, restore
|
||||||
|
ROLLBACK_INFO_DIR="/var/lib/patch_system/rollback_info"
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# 通知配置 - 定义是否启用通知和通知渠道
|
# 通知配置 - 定义是否启用通知和通知渠道
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
41
scripts/patch_tools/tmp_0/cache.php
Normal file
41
scripts/patch_tools/tmp_0/cache.php
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
use think\facade\Env;
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 缓存设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认缓存驱动
|
||||||
|
'default' => Env::get('cache.driver', 'file'),
|
||||||
|
// 缓存连接方式配置
|
||||||
|
'stores' => [
|
||||||
|
'file' => [
|
||||||
|
// 驱动方式
|
||||||
|
'type' => 'File',
|
||||||
|
// 缓存保存目录
|
||||||
|
'path' => '',
|
||||||
|
// 缓存前缀
|
||||||
|
'prefix' => '',
|
||||||
|
// 缓存有效期 0表示永久缓存
|
||||||
|
'expire' => 0,
|
||||||
|
// 缓存标签前缀
|
||||||
|
'tag_prefix' => 'tag:',
|
||||||
|
// 序列化机制 例如 ['serialize', 'unserialize']
|
||||||
|
'serialize' => [],
|
||||||
|
],
|
||||||
|
// redis缓存
|
||||||
|
'redis' => [
|
||||||
|
// 驱动方式
|
||||||
|
'type' => 'redis',
|
||||||
|
// 服务器地址
|
||||||
|
'host' => '127.0.0.1',
|
||||||
|
// redis密码
|
||||||
|
'password' => 'luckyshop123!@#',
|
||||||
|
// 缓存有效期 0表示永久缓存
|
||||||
|
'expire' => 604800,
|
||||||
|
],
|
||||||
|
// 更多的缓存连接
|
||||||
|
],
|
||||||
|
];
|
||||||
Reference in New Issue
Block a user