v2.1: 增加完整恢复模式 (rsync --delete)
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# VPS 快照备份脚本 v2.0
|
# VPS 快照备份脚本 v2.1
|
||||||
# 支持: Ubuntu, Debian, CentOS, Alpine
|
# 支持: Ubuntu, Debian, CentOS, Alpine
|
||||||
# 功能: 创建/恢复快照 + rsync 远程同步 + Telegram 通知 + 自动清理
|
# 功能: 创建/恢复快照 + rsync 远程同步 + Telegram 通知 + 自动清理
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
@@ -22,7 +22,7 @@ SSH_KEY_PATH="/root/.ssh/vps_snapshot_key"
|
|||||||
print_banner() {
|
print_banner() {
|
||||||
echo -e "${BLUE}"
|
echo -e "${BLUE}"
|
||||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||||
echo "║ VPS 快照备份脚本 v2.0 ║"
|
echo "║ VPS 快照备份脚本 v2.1 ║"
|
||||||
echo "║ 支持 Ubuntu/Debian/CentOS/Alpine ║"
|
echo "║ 支持 Ubuntu/Debian/CentOS/Alpine ║"
|
||||||
echo "║ 支持密码/SSH密钥认证 ║"
|
echo "║ 支持密码/SSH密钥认证 ║"
|
||||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||||
@@ -329,6 +329,52 @@ list_remote_snapshots() {
|
|||||||
# 恢复快照
|
# 恢复快照
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
select_restore_mode() {
|
||||||
|
echo -e "\n${YELLOW}选择恢复模式:${NC}"
|
||||||
|
echo "1) 覆盖模式 - 只覆盖快照中的文件(安全,保留新增文件)"
|
||||||
|
echo "2) 完整恢复 - 删除快照中不存在的文件(危险,恢复到干净状态)"
|
||||||
|
read -p "请选择 [1]: " mode
|
||||||
|
echo "${mode:-1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
do_restore() {
|
||||||
|
local file="$1"
|
||||||
|
local mode="$2"
|
||||||
|
local temp_dir="/tmp/snapshot_restore_$$"
|
||||||
|
|
||||||
|
log "解压快照到临时目录..."
|
||||||
|
mkdir -p "$temp_dir"
|
||||||
|
tar -xzf "$file" -C "$temp_dir" 2>/dev/null
|
||||||
|
|
||||||
|
if [ "$mode" = "2" ]; then
|
||||||
|
log "完整恢复模式: 使用 rsync --delete"
|
||||||
|
echo -e "${RED}警告: 将删除系统中快照不存在的文件!${NC}"
|
||||||
|
echo -e "${RED}排除目录: /proc /sys /dev /run /tmp /mnt /media${NC}"
|
||||||
|
read -p "最后确认,输入 YES 继续: " final
|
||||||
|
[ "$final" != "YES" ] && { rm -rf "$temp_dir"; return 1; }
|
||||||
|
|
||||||
|
# 完整恢复,删除快照中不存在的文件
|
||||||
|
rsync -aAXv --delete \
|
||||||
|
--exclude='/proc/*' \
|
||||||
|
--exclude='/sys/*' \
|
||||||
|
--exclude='/dev/*' \
|
||||||
|
--exclude='/run/*' \
|
||||||
|
--exclude='/tmp/*' \
|
||||||
|
--exclude='/mnt/*' \
|
||||||
|
--exclude='/media/*' \
|
||||||
|
--exclude='/lost+found' \
|
||||||
|
--exclude="$LOCAL_DIR/*" \
|
||||||
|
--exclude="$temp_dir" \
|
||||||
|
"$temp_dir/" /
|
||||||
|
else
|
||||||
|
log "覆盖模式: 只覆盖已有文件"
|
||||||
|
rsync -aAXv "$temp_dir/" /
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf "$temp_dir"
|
||||||
|
log "恢复完成,建议重启系统"
|
||||||
|
}
|
||||||
|
|
||||||
restore_local() {
|
restore_local() {
|
||||||
load_config || exit 1
|
load_config || exit 1
|
||||||
list_local_snapshots
|
list_local_snapshots
|
||||||
@@ -339,13 +385,13 @@ restore_local() {
|
|||||||
|
|
||||||
[ -z "$file" ] && { error "无效选择"; return 1; }
|
[ -z "$file" ] && { error "无效选择"; return 1; }
|
||||||
|
|
||||||
|
local mode=$(select_restore_mode)
|
||||||
|
|
||||||
echo -e "${RED}警告: 即将恢复快照到系统!${NC}"
|
echo -e "${RED}警告: 即将恢复快照到系统!${NC}"
|
||||||
read -p "确认恢复 $file? [y/N]: " confirm
|
read -p "确认恢复 $file? [y/N]: " confirm
|
||||||
[[ ! "$confirm" =~ ^[Yy]$ ]] && return
|
[[ ! "$confirm" =~ ^[Yy]$ ]] && return
|
||||||
|
|
||||||
log "恢复快照: $file"
|
do_restore "$file" "$mode"
|
||||||
tar -xzf "$file" -C / 2>/dev/null
|
|
||||||
log "恢复完成,建议重启系统"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_from_remote() {
|
restore_from_remote() {
|
||||||
@@ -360,6 +406,7 @@ restore_from_remote() {
|
|||||||
|
|
||||||
log "下载远程快照: $file"
|
log "下载远程快照: $file"
|
||||||
local local_file="$LOCAL_DIR/$(basename $file)"
|
local local_file="$LOCAL_DIR/$(basename $file)"
|
||||||
|
mkdir -p "$LOCAL_DIR"
|
||||||
|
|
||||||
if [ "$AUTH_METHOD" = "key" ]; then
|
if [ "$AUTH_METHOD" = "key" ]; then
|
||||||
rsync -avz -e "ssh -i $SSH_KEY_PATH -p $REMOTE_PORT" \
|
rsync -avz -e "ssh -i $SSH_KEY_PATH -p $REMOTE_PORT" \
|
||||||
@@ -370,13 +417,13 @@ restore_from_remote() {
|
|||||||
"${REMOTE_USER}@${REMOTE_IP}:${file}" "$local_file"
|
"${REMOTE_USER}@${REMOTE_IP}:${file}" "$local_file"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local mode=$(select_restore_mode)
|
||||||
|
|
||||||
echo -e "${RED}警告: 即将恢复快照!${NC}"
|
echo -e "${RED}警告: 即将恢复快照!${NC}"
|
||||||
read -p "确认恢复? [y/N]: " confirm
|
read -p "确认恢复? [y/N]: " confirm
|
||||||
[[ ! "$confirm" =~ ^[Yy]$ ]] && return
|
[[ ! "$confirm" =~ ^[Yy]$ ]] && return
|
||||||
|
|
||||||
log "恢复快照..."
|
do_restore "$local_file" "$mode"
|
||||||
tar -xzf "$local_file" -C / 2>/dev/null
|
|
||||||
log "恢复完成,建议重启"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_custom_remote() {
|
restore_custom_remote() {
|
||||||
@@ -398,12 +445,13 @@ restore_custom_remote() {
|
|||||||
"${REMOTE_USER}@${REMOTE_IP}:${remote_file}" "$local_file"
|
"${REMOTE_USER}@${REMOTE_IP}:${remote_file}" "$local_file"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local mode=$(select_restore_mode)
|
||||||
|
|
||||||
echo -e "${RED}警告: 即将恢复!${NC}"
|
echo -e "${RED}警告: 即将恢复!${NC}"
|
||||||
read -p "确认? [y/N]: " confirm
|
read -p "确认? [y/N]: " confirm
|
||||||
[[ ! "$confirm" =~ ^[Yy]$ ]] && return
|
[[ ! "$confirm" =~ ^[Yy]$ ]] && return
|
||||||
|
|
||||||
tar -xzf "$local_file" -C / 2>/dev/null
|
do_restore "$local_file" "$mode"
|
||||||
log "恢复完成"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user