2
This commit is contained in:
Binary file not shown.
147
backend.py
147
backend.py
@@ -1026,63 +1026,76 @@ def _auto_install_grub(mount_point: str, distro_type: str) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _get_grub_cmd_path(mount_point: str, distro_type: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
"""
|
||||||
|
查找 GRUB 命令的完整路径。
|
||||||
|
返回: (grub_install_path, grub_mkconfig_path) 或 (None, None)
|
||||||
|
"""
|
||||||
|
# 可能的命令名
|
||||||
|
install_names = ["grub2-install", "grub-install"]
|
||||||
|
mkconfig_names = ["grub2-mkconfig", "grub-mkconfig"]
|
||||||
|
|
||||||
|
# 可能的目录
|
||||||
|
dirs = ["/usr/sbin", "/sbin", "/usr/bin", "/bin"]
|
||||||
|
|
||||||
|
install_path = None
|
||||||
|
mkconfig_path = None
|
||||||
|
|
||||||
|
for name in install_names:
|
||||||
|
for dir_path in dirs:
|
||||||
|
full_path = os.path.join(mount_point, dir_path.lstrip('/'), name)
|
||||||
|
if os.path.exists(full_path):
|
||||||
|
install_path = os.path.join(dir_path, name)
|
||||||
|
break
|
||||||
|
if install_path:
|
||||||
|
break
|
||||||
|
|
||||||
|
for name in mkconfig_names:
|
||||||
|
for dir_path in dirs:
|
||||||
|
full_path = os.path.join(mount_point, dir_path.lstrip('/'), name)
|
||||||
|
if os.path.exists(full_path):
|
||||||
|
mkconfig_path = os.path.join(dir_path, name)
|
||||||
|
break
|
||||||
|
if mkconfig_path:
|
||||||
|
break
|
||||||
|
|
||||||
|
return install_path, mkconfig_path
|
||||||
|
|
||||||
|
|
||||||
|
# 全局变量存储找到的命令路径
|
||||||
|
_grub_install_cmd: Optional[str] = None
|
||||||
|
_grub_mkconfig_cmd: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
def check_chroot_environment(mount_point: str, distro_type: str = "unknown") -> Tuple[bool, str]:
|
def check_chroot_environment(mount_point: str, distro_type: str = "unknown") -> Tuple[bool, str]:
|
||||||
"""
|
"""
|
||||||
检查 chroot 环境是否可用。
|
检查 chroot 环境是否可用。
|
||||||
检测可用的 GRUB 命令及其版本。
|
检测可用的 GRUB 命令及其版本。
|
||||||
如果缺少 GRUB 命令,尝试自动安装。
|
如果缺少 GRUB 命令,尝试自动安装。
|
||||||
"""
|
"""
|
||||||
|
global _grub_install_cmd, _grub_mkconfig_cmd
|
||||||
|
|
||||||
log_step("检查 chroot 环境", f"挂载点: {mount_point}")
|
log_step("检查 chroot 环境", f"挂载点: {mount_point}")
|
||||||
|
|
||||||
# 检查关键命令是否存在(在 PATH 中)
|
# 首先尝试找到命令路径
|
||||||
critical_commands = ["grub-install", "grub-mkconfig", "update-grub", "grub2-install", "grub2-mkconfig"]
|
install_path, mkconfig_path = _get_grub_cmd_path(mount_point, distro_type)
|
||||||
found_commands = []
|
|
||||||
|
|
||||||
for cmd in critical_commands:
|
if install_path and mkconfig_path:
|
||||||
success, _, _ = run_command(["sudo", "chroot", mount_point, "which", cmd],
|
log_info(f" ✓ 找到 grub-install: {install_path}")
|
||||||
f"检查命令 {cmd}", timeout=10)
|
log_info(f" ✓ 找到 grub-mkconfig: {mkconfig_path}")
|
||||||
if success:
|
_grub_install_cmd = install_path
|
||||||
found_commands.append(cmd)
|
_grub_mkconfig_cmd = mkconfig_path
|
||||||
log_info(f" ✓ 找到命令: {cmd}")
|
|
||||||
else:
|
else:
|
||||||
log_debug(f" ✗ 未找到命令: {cmd}")
|
log_warning("未找到 GRUB 命令,尝试自动安装...")
|
||||||
|
|
||||||
# 如果在 PATH 中未找到,检查常见的sbin路径(某些发行版sbin不在默认PATH中)
|
|
||||||
if not found_commands:
|
|
||||||
log_info("在 PATH 中未找到命令,检查 sbin 目录...")
|
|
||||||
sbin_paths = [
|
|
||||||
"/usr/sbin/grub2-install",
|
|
||||||
"/usr/sbin/grub2-mkconfig",
|
|
||||||
"/usr/sbin/grub-install",
|
|
||||||
"/usr/sbin/grub-mkconfig",
|
|
||||||
"/sbin/grub2-install",
|
|
||||||
"/sbin/grub2-mkconfig",
|
|
||||||
]
|
|
||||||
|
|
||||||
for sbin_path in sbin_paths:
|
|
||||||
full_path = mount_point + sbin_path
|
|
||||||
if os.path.exists(full_path):
|
|
||||||
cmd_name = os.path.basename(sbin_path)
|
|
||||||
found_commands.append(cmd_name)
|
|
||||||
log_info(f" ✓ 找到命令: {sbin_path}")
|
|
||||||
|
|
||||||
if not found_commands:
|
|
||||||
log_warning(f"chroot 环境中未找到关键的 GRUB 命令")
|
|
||||||
log_info(f"尝试自动安装 GRUB 包...")
|
|
||||||
|
|
||||||
# 尝试自动安装
|
# 尝试自动安装
|
||||||
if _auto_install_grub(mount_point, distro_type):
|
if _auto_install_grub(mount_point, distro_type):
|
||||||
# 重新检查命令
|
# 重新查找
|
||||||
log_info("重新检查 GRUB 命令...")
|
install_path, mkconfig_path = _get_grub_cmd_path(mount_point, distro_type)
|
||||||
for cmd in critical_commands:
|
if install_path and mkconfig_path:
|
||||||
success, _, _ = run_command(["sudo", "chroot", mount_point, "which", cmd],
|
|
||||||
f"检查命令 {cmd}", timeout=10)
|
|
||||||
if success:
|
|
||||||
found_commands.append(cmd)
|
|
||||||
log_info(f" ✓ 找到命令: {cmd}")
|
|
||||||
|
|
||||||
if found_commands:
|
|
||||||
log_success("✓ 自动安装成功,GRUB 命令已可用")
|
log_success("✓ 自动安装成功,GRUB 命令已可用")
|
||||||
|
_grub_install_cmd = install_path
|
||||||
|
_grub_mkconfig_cmd = mkconfig_path
|
||||||
else:
|
else:
|
||||||
log_error("✗ 自动安装后仍未找到 GRUB 命令")
|
log_error("✗ 自动安装后仍未找到 GRUB 命令")
|
||||||
return False, "自动安装 GRUB 失败,请手动安装"
|
return False, "自动安装 GRUB 失败,请手动安装"
|
||||||
@@ -1098,9 +1111,8 @@ def check_chroot_environment(mount_point: str, distro_type: str = "unknown") ->
|
|||||||
log_error(f"=" * 60)
|
log_error(f"=" * 60)
|
||||||
return False, "自动安装 GRUB 失败"
|
return False, "自动安装 GRUB 失败"
|
||||||
|
|
||||||
# 检查 grub-install 版本(优先使用 grub2-install 如果存在)
|
# 检查 grub-install 版本
|
||||||
grub_cmd = "grub2-install" if "grub2-install" in found_commands else "grub-install"
|
success, stdout, _ = run_command(["sudo", "chroot", mount_point, _grub_install_cmd, "--version"],
|
||||||
success, stdout, _ = run_command(["sudo", "chroot", mount_point, grub_cmd, "--version"],
|
|
||||||
"检查 grub-install 版本", timeout=10)
|
"检查 grub-install 版本", timeout=10)
|
||||||
if success:
|
if success:
|
||||||
log_info(f"grub-install 版本: {stdout.strip()}")
|
log_info(f"grub-install 版本: {stdout.strip()}")
|
||||||
@@ -1234,17 +1246,26 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
use_fallback: 是否安装 EFI fallback 文件
|
use_fallback: 是否安装 EFI fallback 文件
|
||||||
efi_bootloader_id: EFI 启动项名称
|
efi_bootloader_id: EFI 启动项名称
|
||||||
"""
|
"""
|
||||||
|
global _grub_install_cmd, _grub_mkconfig_cmd
|
||||||
|
|
||||||
log_step("修复 GRUB", f"目标磁盘: {target_disk}, UEFI: {is_uefi}, 发行版: {distro_type}")
|
log_step("修复 GRUB", f"目标磁盘: {target_disk}, UEFI: {is_uefi}, 发行版: {distro_type}")
|
||||||
|
|
||||||
if not is_uefi and not validate_device_path(target_disk):
|
if not is_uefi and not validate_device_path(target_disk):
|
||||||
log_error(f"无效的目标磁盘路径: {target_disk}")
|
log_error(f"无效的目标磁盘路径: {target_disk}")
|
||||||
return False, f"无效的目标磁盘路径: {target_disk}"
|
return False, f"无效的目标磁盘路径: {target_disk}"
|
||||||
|
|
||||||
# 检查 chroot 环境
|
# 检查 chroot 环境(这会设置 _grub_install_cmd 和 _grub_mkconfig_cmd)
|
||||||
ok, err = check_chroot_environment(mount_point, distro_type)
|
ok, err = check_chroot_environment(mount_point, distro_type)
|
||||||
if not ok:
|
if not ok:
|
||||||
return False, err
|
return False, err
|
||||||
|
|
||||||
|
# 确保命令路径已设置
|
||||||
|
if not _grub_install_cmd or not _grub_mkconfig_cmd:
|
||||||
|
return False, "无法确定 GRUB 命令路径"
|
||||||
|
|
||||||
|
log_info(f"使用 grub-install: {_grub_install_cmd}")
|
||||||
|
log_info(f"使用 grub-mkconfig: {_grub_mkconfig_cmd}")
|
||||||
|
|
||||||
chroot_cmd_prefix = ["sudo", "chroot", mount_point]
|
chroot_cmd_prefix = ["sudo", "chroot", mount_point]
|
||||||
|
|
||||||
# 检测 Live 环境
|
# 检测 Live 环境
|
||||||
@@ -1281,7 +1302,7 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
log_warning(f"✗ EFI 目录不存在: {efi_check_path}")
|
log_warning(f"✗ EFI 目录不存在: {efi_check_path}")
|
||||||
|
|
||||||
grub_install_cmd = chroot_cmd_prefix + [
|
grub_install_cmd = chroot_cmd_prefix + [
|
||||||
"grub-install" if distro_type != "centos" else "grub2-install",
|
_grub_install_cmd,
|
||||||
f"--target={efi_target}",
|
f"--target={efi_target}",
|
||||||
"--efi-directory=/boot/efi",
|
"--efi-directory=/boot/efi",
|
||||||
f"--bootloader-id={efi_bootloader_id}",
|
f"--bootloader-id={efi_bootloader_id}",
|
||||||
@@ -1292,7 +1313,7 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
if is_live_env:
|
if is_live_env:
|
||||||
log_info("Live 环境: 优先使用 --removable 模式")
|
log_info("Live 环境: 优先使用 --removable 模式")
|
||||||
removable_cmd = chroot_cmd_prefix + [
|
removable_cmd = chroot_cmd_prefix + [
|
||||||
"grub-install" if distro_type != "centos" else "grub2-install",
|
_grub_install_cmd,
|
||||||
f"--target={efi_target}",
|
f"--target={efi_target}",
|
||||||
"--efi-directory=/boot/efi",
|
"--efi-directory=/boot/efi",
|
||||||
"--removable",
|
"--removable",
|
||||||
@@ -1312,6 +1333,7 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
else:
|
else:
|
||||||
log_warning(f"removable 模式失败,尝试标准模式")
|
log_warning(f"removable 模式失败,尝试标准模式")
|
||||||
|
|
||||||
|
|
||||||
install_errors.append(f"removable 模式: {stderr}")
|
install_errors.append(f"removable 模式: {stderr}")
|
||||||
|
|
||||||
if not grub_install_success:
|
if not grub_install_success:
|
||||||
@@ -1333,7 +1355,7 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
# 第二次尝试: removable 模式
|
# 第二次尝试: removable 模式
|
||||||
log_info("尝试 2/3: Live环境/可移动模式(--removable)...")
|
log_info("尝试 2/3: Live环境/可移动模式(--removable)...")
|
||||||
removable_cmd = chroot_cmd_prefix + [
|
removable_cmd = chroot_cmd_prefix + [
|
||||||
"grub-install" if distro_type != "centos" else "grub2-install",
|
_grub_install_cmd,
|
||||||
f"--target={efi_target}",
|
f"--target={efi_target}",
|
||||||
"--efi-directory=/boot/efi",
|
"--efi-directory=/boot/efi",
|
||||||
"--removable",
|
"--removable",
|
||||||
@@ -1376,7 +1398,7 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
log_step("安装 BIOS GRUB")
|
log_step("安装 BIOS GRUB")
|
||||||
|
|
||||||
bios_cmd = chroot_cmd_prefix + [
|
bios_cmd = chroot_cmd_prefix + [
|
||||||
"grub-install" if distro_type != "centos" else "grub2-install",
|
_grub_install_cmd,
|
||||||
"--target=i386-pc",
|
"--target=i386-pc",
|
||||||
"--recheck",
|
"--recheck",
|
||||||
"--force",
|
"--force",
|
||||||
@@ -1436,28 +1458,13 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
# ===== 更新 GRUB 配置 =====
|
# ===== 更新 GRUB 配置 =====
|
||||||
log_step("更新 GRUB 配置文件")
|
log_step("更新 GRUB 配置文件")
|
||||||
|
|
||||||
# 确定正确的命令和路径
|
# 确定配置文件路径
|
||||||
grub_update_cmd = []
|
|
||||||
config_path = ""
|
|
||||||
|
|
||||||
# 根据发行版确定命令
|
|
||||||
grub_install_bin = "grub-install"
|
|
||||||
grub_mkconfig_bin = "grub-mkconfig"
|
|
||||||
|
|
||||||
if distro_type == "centos":
|
|
||||||
grub_install_bin = "grub2-install"
|
|
||||||
grub_mkconfig_bin = "grub2-mkconfig"
|
|
||||||
elif distro_type == "fedora":
|
|
||||||
grub_mkconfig_bin = "grub2-mkconfig"
|
|
||||||
elif distro_type == "opensuse":
|
|
||||||
grub_mkconfig_bin = "grub2-mkconfig"
|
|
||||||
|
|
||||||
# 检测配置文件路径
|
|
||||||
possible_config_paths = [
|
possible_config_paths = [
|
||||||
"/boot/grub/grub.cfg",
|
"/boot/grub/grub.cfg",
|
||||||
"/boot/grub2/grub.cfg",
|
"/boot/grub2/grub.cfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
config_path = ""
|
||||||
for cfg_path in possible_config_paths:
|
for cfg_path in possible_config_paths:
|
||||||
full_path = os.path.join(mount_point, cfg_path.lstrip('/'))
|
full_path = os.path.join(mount_point, cfg_path.lstrip('/'))
|
||||||
if os.path.exists(os.path.dirname(full_path)):
|
if os.path.exists(os.path.dirname(full_path)):
|
||||||
@@ -1474,9 +1481,9 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
if success:
|
if success:
|
||||||
grub_update_cmd = ["update-grub"]
|
grub_update_cmd = ["update-grub"]
|
||||||
else:
|
else:
|
||||||
grub_update_cmd = [grub_mkconfig_bin, "-o", config_path]
|
grub_update_cmd = [_grub_mkconfig_cmd, "-o", config_path]
|
||||||
else:
|
else:
|
||||||
grub_update_cmd = [grub_mkconfig_bin, "-o", config_path]
|
grub_update_cmd = [_grub_mkconfig_cmd, "-o", config_path]
|
||||||
|
|
||||||
log_info(f"使用命令: {' '.join(grub_update_cmd)}")
|
log_info(f"使用命令: {' '.join(grub_update_cmd)}")
|
||||||
log_info(f"配置文件路径: {config_path}")
|
log_info(f"配置文件路径: {config_path}")
|
||||||
|
|||||||
Reference in New Issue
Block a user