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
|
||||
|
||||
|
||||
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]:
|
||||
"""
|
||||
检查 chroot 环境是否可用。
|
||||
检测可用的 GRUB 命令及其版本。
|
||||
如果缺少 GRUB 命令,尝试自动安装。
|
||||
"""
|
||||
global _grub_install_cmd, _grub_mkconfig_cmd
|
||||
|
||||
log_step("检查 chroot 环境", f"挂载点: {mount_point}")
|
||||
|
||||
# 检查关键命令是否存在(在 PATH 中)
|
||||
critical_commands = ["grub-install", "grub-mkconfig", "update-grub", "grub2-install", "grub2-mkconfig"]
|
||||
found_commands = []
|
||||
# 首先尝试找到命令路径
|
||||
install_path, mkconfig_path = _get_grub_cmd_path(mount_point, distro_type)
|
||||
|
||||
for cmd in critical_commands:
|
||||
success, _, _ = run_command(["sudo", "chroot", mount_point, "which", cmd],
|
||||
f"检查命令 {cmd}", timeout=10)
|
||||
if success:
|
||||
found_commands.append(cmd)
|
||||
log_info(f" ✓ 找到命令: {cmd}")
|
||||
if install_path and mkconfig_path:
|
||||
log_info(f" ✓ 找到 grub-install: {install_path}")
|
||||
log_info(f" ✓ 找到 grub-mkconfig: {mkconfig_path}")
|
||||
_grub_install_cmd = install_path
|
||||
_grub_mkconfig_cmd = mkconfig_path
|
||||
else:
|
||||
log_debug(f" ✗ 未找到命令: {cmd}")
|
||||
|
||||
# 如果在 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 包...")
|
||||
log_warning("未找到 GRUB 命令,尝试自动安装...")
|
||||
|
||||
# 尝试自动安装
|
||||
if _auto_install_grub(mount_point, distro_type):
|
||||
# 重新检查命令
|
||||
log_info("重新检查 GRUB 命令...")
|
||||
for cmd in critical_commands:
|
||||
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:
|
||||
# 重新查找
|
||||
install_path, mkconfig_path = _get_grub_cmd_path(mount_point, distro_type)
|
||||
if install_path and mkconfig_path:
|
||||
log_success("✓ 自动安装成功,GRUB 命令已可用")
|
||||
_grub_install_cmd = install_path
|
||||
_grub_mkconfig_cmd = mkconfig_path
|
||||
else:
|
||||
log_error("✗ 自动安装后仍未找到 GRUB 命令")
|
||||
return False, "自动安装 GRUB 失败,请手动安装"
|
||||
@@ -1098,9 +1111,8 @@ def check_chroot_environment(mount_point: str, distro_type: str = "unknown") ->
|
||||
log_error(f"=" * 60)
|
||||
return False, "自动安装 GRUB 失败"
|
||||
|
||||
# 检查 grub-install 版本(优先使用 grub2-install 如果存在)
|
||||
grub_cmd = "grub2-install" if "grub2-install" in found_commands else "grub-install"
|
||||
success, stdout, _ = run_command(["sudo", "chroot", mount_point, grub_cmd, "--version"],
|
||||
# 检查 grub-install 版本
|
||||
success, stdout, _ = run_command(["sudo", "chroot", mount_point, _grub_install_cmd, "--version"],
|
||||
"检查 grub-install 版本", timeout=10)
|
||||
if success:
|
||||
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 文件
|
||||
efi_bootloader_id: EFI 启动项名称
|
||||
"""
|
||||
global _grub_install_cmd, _grub_mkconfig_cmd
|
||||
|
||||
log_step("修复 GRUB", f"目标磁盘: {target_disk}, UEFI: {is_uefi}, 发行版: {distro_type}")
|
||||
|
||||
if not is_uefi and not validate_device_path(target_disk):
|
||||
log_error(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)
|
||||
if not ok:
|
||||
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]
|
||||
|
||||
# 检测 Live 环境
|
||||
@@ -1281,7 +1302,7 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
||||
log_warning(f"✗ EFI 目录不存在: {efi_check_path}")
|
||||
|
||||
grub_install_cmd = chroot_cmd_prefix + [
|
||||
"grub-install" if distro_type != "centos" else "grub2-install",
|
||||
_grub_install_cmd,
|
||||
f"--target={efi_target}",
|
||||
"--efi-directory=/boot/efi",
|
||||
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:
|
||||
log_info("Live 环境: 优先使用 --removable 模式")
|
||||
removable_cmd = chroot_cmd_prefix + [
|
||||
"grub-install" if distro_type != "centos" else "grub2-install",
|
||||
_grub_install_cmd,
|
||||
f"--target={efi_target}",
|
||||
"--efi-directory=/boot/efi",
|
||||
"--removable",
|
||||
@@ -1312,6 +1333,7 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
||||
else:
|
||||
log_warning(f"removable 模式失败,尝试标准模式")
|
||||
|
||||
|
||||
install_errors.append(f"removable 模式: {stderr}")
|
||||
|
||||
if not grub_install_success:
|
||||
@@ -1333,7 +1355,7 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
||||
# 第二次尝试: removable 模式
|
||||
log_info("尝试 2/3: Live环境/可移动模式(--removable)...")
|
||||
removable_cmd = chroot_cmd_prefix + [
|
||||
"grub-install" if distro_type != "centos" else "grub2-install",
|
||||
_grub_install_cmd,
|
||||
f"--target={efi_target}",
|
||||
"--efi-directory=/boot/efi",
|
||||
"--removable",
|
||||
@@ -1376,7 +1398,7 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
||||
log_step("安装 BIOS GRUB")
|
||||
|
||||
bios_cmd = chroot_cmd_prefix + [
|
||||
"grub-install" if distro_type != "centos" else "grub2-install",
|
||||
_grub_install_cmd,
|
||||
"--target=i386-pc",
|
||||
"--recheck",
|
||||
"--force",
|
||||
@@ -1436,28 +1458,13 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
||||
# ===== 更新 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 = [
|
||||
"/boot/grub/grub.cfg",
|
||||
"/boot/grub2/grub.cfg",
|
||||
]
|
||||
|
||||
config_path = ""
|
||||
for cfg_path in possible_config_paths:
|
||||
full_path = os.path.join(mount_point, cfg_path.lstrip('/'))
|
||||
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:
|
||||
grub_update_cmd = ["update-grub"]
|
||||
else:
|
||||
grub_update_cmd = [grub_mkconfig_bin, "-o", config_path]
|
||||
grub_update_cmd = [_grub_mkconfig_cmd, "-o", config_path]
|
||||
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"配置文件路径: {config_path}")
|
||||
|
||||
Reference in New Issue
Block a user