This commit is contained in:
zj
2026-02-11 15:33:41 +08:00
parent 363c448872
commit 9f86574ece
2 changed files with 78 additions and 71 deletions

Binary file not shown.

View File

@@ -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}")
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 包...")
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_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}")