Files
PVE-Tools-9/src/modules/05-vm-container/restore.sh
Maple 886e82f0cb refactor: 模块化重构 — 拆分 lib/ 基础设施层与 src/modules/ 功能模块
PVE-Tools.sh 从 ~14,700 行单文件重构为 150 行入口点,
所有函数按职责拆分到独立文件,通过 source 机制加载。

lib/ — 基础设施层(零业务逻辑)
  config.sh: 全局变量与常量
  core.sh: 日志、UI、确认、备份、GRUB、进度条
  network.sh: 网络检测、镜像选择
  runtime.sh: 运行时守卫、main() 入口

src/modules/ — 功能模块(10 个目录)
  01-optimization  02-sources  03-boot-kernel
  04-gpu-passthrough  05-vm-container  06-networking
  07-storage-disk  08-tools-about  09-security  10-third-party

新增 build.sh(合并编译)和 dev.sh(开发 source 入口),
release.yml 新增构建步骤,CI 适配模块化结构。
2026-07-08 11:15:59 +08:00

118 lines
4.1 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# SPDX-License-Identifier: GPL-3.0-only
# Copyright (C) 2026 Ciriu Networks
vm_select_backup_archive() {
local archives
archives="$(vm_discover_backup_archives)"
if [[ -z "$archives" ]]; then
local manual
read -p "未自动发现备份文件,请手动输入备份文件完整路径: " manual
[[ -n "$manual" && -f "$manual" ]] || return 1
echo "$manual"
return 0
fi
{
echo -e "${CYAN}已发现备份文件:${NC}"
echo "$archives" | awk -F'|' '{printf " [%d] %-10s %-16s %s\n", NR, $2, $3, $1}'
echo -e "${UI_DIVIDER}"
} >&2
local pick line path
read -p "请选择备份序号 (0 手动输入): " pick
pick="${pick:-0}"
if [[ "$pick" == "0" ]]; then
local manual
read -p "请输入备份文件完整路径: " manual
[[ -n "$manual" && -f "$manual" ]] || return 1
echo "$manual"
return 0
fi
[[ "$pick" =~ ^[0-9]+$ ]] || return 1
line="$(echo "$archives" | awk -F'|' -v n="$pick" 'NR==n{print $0}')"
path="$(echo "$line" | awk -F'|' '{print $1}')"
[[ -n "$path" && -f "$path" ]] || return 1
echo "$path"
}
vm_restore_from_backup() {
vm_require_commands qmrestore qm pvesm || return 1
local archive
archive="$(vm_select_backup_archive)"
local rc=$?
[[ "$rc" -eq 2 ]] && return 0
[[ -n "$archive" ]] || return 1
local new_vmid
read -p "请输入新的 VMID: " new_vmid
vm_validate_new_vmid "$new_vmid" || return 1
local store
store="$(vm_select_storage_by_content images "请选择恢复后的磁盘存储")"
rc=$?
[[ "$rc" -eq 2 ]] && return 0
[[ -n "$store" ]] || return 1
local unique start_after
read -p "是否重新生成唯一标识(推荐 yes?(yes/no) [yes]: " unique
unique="${unique:-yes}"
read -p "恢复后是否自动启动 VM(yes/no) [no]: " start_after
start_after="${start_after:-no}"
clear
show_menu_header "从备份恢复 VM"
echo -e "${YELLOW}备份文件:${NC} $archive"
echo -e "${YELLOW}新 VMID:${NC} $new_vmid"
echo -e "${YELLOW}目标存储:${NC} $store"
echo -e "${YELLOW}唯一标识重建:${NC} $unique"
echo -e "${UI_DIVIDER}"
if ! confirm_high_risk_action "从备份恢复为新 VM $new_vmid" "恢复会创建新的 VM 和磁盘卷;如果关闭唯一标识重建,还可能引入 MAC/系统标识冲突。" "可能大量占用目标存储,并在误选备份文件时恢复出错误业务数据。" "请确认备份文件来源、目标 VMID 与目标存储均已核对,并预留足够空间。" "RESTORE"; then
return 0
fi
local -a cmd=(qmrestore "$archive" "$new_vmid" --storage "$store")
if [[ "$unique" == "yes" || "$unique" == "YES" ]]; then
cmd+=(--unique 1)
fi
local output
if ! output="$("${cmd[@]}" 2>&1)"; then
echo "$output" | sed 's/^/ /'
display_error "qmrestore 执行失败" "请检查备份文件、目标存储和日志输出。"
return 1
fi
echo "$output" | sed 's/^/ /'
if [[ "$start_after" == "yes" || "$start_after" == "YES" ]]; then
qm start "$new_vmid" >/dev/null 2>&1 || log_warn "自动启动 VM 失败,请手动检查。"
fi
display_success "恢复完成" "新 VMID: $new_vmid"
}
vm_backup_restore_menu() {
while true; do
clear
show_menu_header "VM 备份与恢复"
vm_show_data_risk_banner
show_menu_option "1" "创建 VM 备份vzdump"
show_menu_option "2" "从备份恢复为新 VM"
show_menu_option "3" "定时备份任务管理"
show_menu_option "4" "备份文件跨机恢复引导"
show_menu_option "0" "返回"
show_menu_footer
local choice
read -p "请选择操作 [0-4]: " choice
case "$choice" in
1) vm_backup_create ;;
2) vm_restore_from_backup ;;
3) vm_schedule_backup_menu ;;
4) vm_backup_transfer_guide ;;
0) return ;;
*) log_error "无效选择" ;;
esac
pause_function
done
}