auto install gurb

This commit is contained in:
zj
2026-02-11 14:59:51 +08:00
parent d0bd5520ac
commit d56c24275a
2 changed files with 132 additions and 30 deletions

Binary file not shown.

View File

@@ -881,23 +881,116 @@ def detect_distro_type(mount_point: str) -> str:
return "unknown" return "unknown"
def _get_grub_package_install_cmd(distro_type: str) -> str: def _get_grub_packages(distro_type: str) -> Tuple[List[str], str]:
"""获取安装 GRUB 包的命令提示""" """
package_commands = { 获取安装 GRUB 包所需的包列表和包管理器命令。
"centos": "yum install grub2-tools grub2-pc", 返回: (包列表, 包管理器基命令)
"fedora": "dnf install grub2-tools grub2-pc", """
"debian": "apt-get install grub-pc", package_map = {
"ubuntu": "apt-get install grub-pc", "centos": (["grub2-tools", "grub2-pc"], "yum install -y"),
"arch": "pacman -S grub", "fedora": (["grub2-tools", "grub2-pc"], "dnf install -y"),
"opensuse": "zypper install grub2", "rhel": (["grub2-tools", "grub2-pc"], "yum install -y"),
"rocky": (["grub2-tools", "grub2-pc"], "dnf install -y"),
"almalinux": (["grub2-tools", "grub2-pc"], "dnf install -y"),
"debian": (["grub-pc"], "apt-get install -y"),
"ubuntu": (["grub-pc"], "apt-get install -y"),
"arch": (["grub"], "pacman -S --noconfirm"),
"manjaro": (["grub"], "pacman -S --noconfirm"),
"opensuse": (["grub2"], "zypper install -y"),
"void": (["grub"], "xbps-install -y"),
"gentoo": (["sys-boot/grub"], "emerge"),
} }
return package_commands.get(distro_type, "安装 GRUB 包(请查阅发行版文档)") return package_map.get(distro_type, (["grub"], "包管理器安装"))
def _auto_install_grub(mount_point: str, distro_type: str) -> bool:
"""
自动在 chroot 环境中安装 GRUB 包。
返回是否成功。
"""
log_step("自动安装 GRUB 包", f"发行版: {distro_type}")
packages, pkg_cmd = _get_grub_packages(distro_type)
if not packages:
log_warning(f"未知的发行版 '{distro_type}',无法自动安装 GRUB")
return False
chroot_cmd_prefix = ["sudo", "chroot", mount_point]
# 1. 首先检查网络连接(通过 ping
log_info("检查网络连接...")
success, _, _ = run_command(
chroot_cmd_prefix + ["ping", "-c", "1", "8.8.8.8"],
"检查网络连接",
timeout=10
)
if not success:
# 尝试使用主机的网络配置
log_warning("chroot 环境无网络,尝试从 Live 环境复制 DNS 配置...")
# 复制 /etc/resolv.conf
resolv_source = "/etc/resolv.conf"
resolv_target = os.path.join(mount_point, "etc/resolv.conf")
if os.path.exists(resolv_source):
try:
shutil.copy2(resolv_source, resolv_target)
log_info("已复制 DNS 配置")
except Exception as e:
log_warning(f"复制 DNS 配置失败: {e}")
# 再次检查网络
success, _, _ = run_command(
chroot_cmd_prefix + ["ping", "-c", "1", "8.8.8.8"],
"再次检查网络连接",
timeout=10
)
if not success:
log_error("chroot 环境无法连接网络,无法自动安装 GRUB")
log_info("请手动安装 GRUB 包后再运行此工具")
return False
log_success("网络连接正常")
# 2. 更新包列表(某些发行版需要)
update_cmds = {
"debian": ["apt-get", "update"],
"ubuntu": ["apt-get", "update"],
"arch": ["pacman", "-Sy"],
"manjaro": ["pacman", "-Sy"],
}
if distro_type in update_cmds:
log_info(f"更新 {distro_type} 包列表...")
run_command(
chroot_cmd_prefix + update_cmds[distro_type],
f"更新 {distro_type} 包列表",
timeout=120
)
# 3. 安装 GRUB 包
log_info(f"安装 GRUB 包: {', '.join(packages)}")
install_cmd = chroot_cmd_prefix + pkg_cmd.split() + packages
success, stdout, stderr = run_command(
install_cmd,
f"安装 GRUB 包 ({' '.join(packages)})",
timeout=300
)
if success:
log_success(f"✓ GRUB 包安装成功")
return True
else:
log_error(f"✗ GRUB 包安装失败: {stderr}")
return False
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 命令,尝试自动安装。
""" """
log_step("检查 chroot 环境", f"挂载点: {mount_point}") log_step("检查 chroot 环境", f"挂载点: {mount_point}")
@@ -915,27 +1008,36 @@ def check_chroot_environment(mount_point: str, distro_type: str = "unknown") ->
log_debug(f" ✗ 未找到命令: {cmd}") log_debug(f" ✗ 未找到命令: {cmd}")
if not found_commands: if not found_commands:
log_error(f"=" * 60) log_warning(f"chroot 环境中未找到关键的 GRUB 命令")
log_error(f"chroot 环境中未找到关键的 GRUB 命令!") log_info(f"尝试自动安装 GRUB 包...")
log_error(f"")
log_error(f"目标系统缺少 GRUB 引导加载器。")
log_error(f"")
log_error(f"解决方案:")
log_error(f"1. 进入目标系统的 chroot 环境")
log_error(f"2. 安装 GRUB 包:")
install_cmd = _get_grub_package_install_cmd(distro_type)
log_error(f" {install_cmd}")
log_error(f"")
log_error(f"3. 然后重新运行此工具")
log_error(f"=" * 60)
error_msg = ( # 尝试自动安装
f"目标系统缺少 GRUB 工具。\n" if _auto_install_grub(mount_point, distro_type):
f"请先安装 GRUB 包:\n" # 重新检查命令
f"{install_cmd}\n" log_info("重新检查 GRUB 命令...")
f"然后重新运行修复工具。" for cmd in critical_commands:
) success, _, _ = run_command(["sudo", "chroot", mount_point, "which", cmd],
return False, error_msg f"检查命令 {cmd}", timeout=10)
if success:
found_commands.append(cmd)
log_info(f" ✓ 找到命令: {cmd}")
if found_commands:
log_success("✓ 自动安装成功GRUB 命令已可用")
else:
log_error("✗ 自动安装后仍未找到 GRUB 命令")
return False, "自动安装 GRUB 失败,请手动安装"
else:
log_error("=" * 60)
log_error(f"无法自动安装 GRUB 包")
log_error(f"")
log_error(f"请手动安装 GRUB 包:")
packages, pkg_cmd = _get_grub_packages(distro_type)
log_error(f" chroot {mount_point}")
log_error(f" {pkg_cmd} {' '.join(packages)}")
log_error(f" exit")
log_error(f"=" * 60)
return False, "自动安装 GRUB 失败"
# 检查 grub-install 版本(优先使用 grub2-install 如果存在) # 检查 grub-install 版本(优先使用 grub2-install 如果存在)
grub_cmd = "grub2-install" if "grub2-install" in found_commands else "grub-install" grub_cmd = "grub2-install" if "grub2-install" in found_commands else "grub-install"