6
This commit is contained in:
26
AGENTS.md
26
AGENTS.md
@@ -91,7 +91,30 @@ initrd /initramfs-4.18.0-348.el8.x86_64.img
|
|||||||
options root=/dev/mapper/cl-root ro crashkernel=auto rd.lvm.lv=cl/root rhgb quiet
|
options root=/dev/mapper/cl-root ro crashkernel=auto rd.lvm.lv=cl/root rhgb quiet
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6. GRUB 修复 (`backend.py:chroot_and_repair_grub`)
|
### 6. UEFI 模块自动安装 (`backend.py:check_and_install_efi_modules`)
|
||||||
|
|
||||||
|
**NEW v2.3**: 自动检测并安装 UEFI GRUB 模块
|
||||||
|
|
||||||
|
#### 问题场景
|
||||||
|
在 UEFI 模式下,`grub-install` 需要 `/usr/lib/grub/x86_64-efi/` 目录下的 EFI 模块。如果缺少这些模块,会报错:
|
||||||
|
```
|
||||||
|
/usr/lib/grub/x86_64-efi/modinfo.sh doesn't exist
|
||||||
|
```
|
||||||
|
|
||||||
|
这在以下场景常见:
|
||||||
|
- 最小化安装的系统
|
||||||
|
- 从 BIOS 模式安装后切换到 UEFI 模式
|
||||||
|
- `/usr` 被清空或损坏
|
||||||
|
|
||||||
|
#### 自动安装
|
||||||
|
检测到缺少 EFI 模块时,自动安装相应的包:
|
||||||
|
| 发行版 | 包名 |
|
||||||
|
|--------|------|
|
||||||
|
| CentOS/RHEL/Rocky/Alma/Fedora | `grub2-efi-x64`, `grub2-efi-x64-modules` |
|
||||||
|
| Debian/Ubuntu | `grub-efi-amd64` |
|
||||||
|
| Arch/Manjaro | `grub` (已包含 EFI 支持) |
|
||||||
|
|
||||||
|
### 7. GRUB 修复 (`backend.py:chroot_and_repair_grub`)
|
||||||
|
|
||||||
#### BIOS 模式
|
#### BIOS 模式
|
||||||
- `grub-install --target=i386-pc --recheck --force /dev/sdX`
|
- `grub-install --target=i386-pc --recheck --force /dev/sdX`
|
||||||
@@ -99,6 +122,7 @@ options root=/dev/mapper/cl-root ro crashkernel=auto rd.lvm.lv=cl/root rhgb quie
|
|||||||
|
|
||||||
#### UEFI 模式 (参考 Calamares 实现)
|
#### UEFI 模式 (参考 Calamares 实现)
|
||||||
- 自动检测系统架构 (x86_64/i386/arm64/loongarch64)
|
- 自动检测系统架构 (x86_64/i386/arm64/loongarch64)
|
||||||
|
- **NEW**: 自动检测并安装 UEFI GRUB 模块
|
||||||
- 获取正确的 EFI 参数 (target, grub_file, boot_file)
|
- 获取正确的 EFI 参数 (target, grub_file, boot_file)
|
||||||
- **多重安装策略**(自动回退):
|
- **多重安装策略**(自动回退):
|
||||||
1. 标准安装(带 NVRAM)
|
1. 标准安装(带 NVRAM)
|
||||||
|
|||||||
Binary file not shown.
95
backend.py
95
backend.py
@@ -1140,6 +1140,95 @@ def check_chroot_environment(mount_point: str, distro_type: str = "unknown") ->
|
|||||||
return True, ""
|
return True, ""
|
||||||
|
|
||||||
|
|
||||||
|
def check_and_install_efi_modules(mount_point: str, distro_type: str, is_uefi: bool) -> Tuple[bool, str]:
|
||||||
|
"""
|
||||||
|
检查并安装 UEFI GRUB 模块。
|
||||||
|
对于 UEFI 模式,需要检查 /usr/lib/grub/x86_64-efi/ 目录是否存在。
|
||||||
|
如果不存在,自动安装 grub2-efi 包。
|
||||||
|
|
||||||
|
返回: (是否成功, 错误信息)
|
||||||
|
"""
|
||||||
|
if not is_uefi:
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
log_step("检查 UEFI GRUB 模块")
|
||||||
|
|
||||||
|
# 检测架构
|
||||||
|
efi_params = get_grub_efi_parameters()
|
||||||
|
if not efi_params:
|
||||||
|
return False, "无法确定 EFI 架构"
|
||||||
|
|
||||||
|
efi_target, _, _ = efi_params
|
||||||
|
# efi_target 格式: x86_64-efi, i386-efi, arm64-efi
|
||||||
|
arch_dir = efi_target # 如: x86_64-efi
|
||||||
|
|
||||||
|
# 检查模块目录
|
||||||
|
module_dir = os.path.join(mount_point, f"usr/lib/grub/{arch_dir}")
|
||||||
|
modinfo_file = os.path.join(module_dir, "modinfo.sh")
|
||||||
|
|
||||||
|
if os.path.exists(modinfo_file):
|
||||||
|
log_success(f"✓ UEFI GRUB 模块已存在: {module_dir}")
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
log_warning(f"UEFI GRUB 模块不存在: {module_dir}")
|
||||||
|
log_info("尝试安装 UEFI GRUB 模块包...")
|
||||||
|
|
||||||
|
chroot_cmd_prefix = ["sudo", "chroot", mount_point]
|
||||||
|
|
||||||
|
# 根据发行版选择正确的 EFI 包
|
||||||
|
efi_packages_map = {
|
||||||
|
"centos": ["grub2-efi-x64", "grub2-efi-x64-modules"],
|
||||||
|
"rhel": ["grub2-efi-x64", "grub2-efi-x64-modules"],
|
||||||
|
"fedora": ["grub2-efi-x64", "grub2-efi-x64-modules"],
|
||||||
|
"rocky": ["grub2-efi-x64", "grub2-efi-x64-modules"],
|
||||||
|
"almalinux": ["grub2-efi-x64", "grub2-efi-x64-modules"],
|
||||||
|
"debian": ["grub-efi-amd64"],
|
||||||
|
"ubuntu": ["grub-efi-amd64"],
|
||||||
|
"arch": ["grub"], # Arch 的 grub 包包含 EFI 支持
|
||||||
|
"manjaro": ["grub"],
|
||||||
|
}
|
||||||
|
|
||||||
|
efi_packages = efi_packages_map.get(distro_type, [])
|
||||||
|
|
||||||
|
if not efi_packages:
|
||||||
|
log_warning(f"未知的发行版 '{distro_type}',无法自动安装 EFI 模块")
|
||||||
|
return False, f"无法确定 {distro_type} 的 EFI 包名"
|
||||||
|
|
||||||
|
# 安装 EFI 包
|
||||||
|
if distro_type in ["centos", "rhel", "fedora", "rocky", "almalinux"]:
|
||||||
|
success, _, stderr = run_command(
|
||||||
|
chroot_cmd_prefix + ["yum", "install", "-y"] + efi_packages,
|
||||||
|
f"安装 UEFI GRUB 包",
|
||||||
|
timeout=300
|
||||||
|
)
|
||||||
|
elif distro_type in ["debian", "ubuntu"]:
|
||||||
|
success, _, stderr = run_command(
|
||||||
|
chroot_cmd_prefix + ["apt-get", "install", "-y"] + efi_packages,
|
||||||
|
f"安装 UEFI GRUB 包",
|
||||||
|
timeout=300
|
||||||
|
)
|
||||||
|
elif distro_type in ["arch", "manjaro"]:
|
||||||
|
success, _, stderr = run_command(
|
||||||
|
chroot_cmd_prefix + ["pacman", "-S", "--noconfirm"] + efi_packages,
|
||||||
|
f"安装 UEFI GRUB 包",
|
||||||
|
timeout=300
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return False, f"不支持的发行版: {distro_type}"
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
log_error(f"UEFI GRUB 包安装失败")
|
||||||
|
return False, f"无法安装 UEFI GRUB 包: {stderr}"
|
||||||
|
|
||||||
|
# 重新检查模块
|
||||||
|
if os.path.exists(modinfo_file):
|
||||||
|
log_success(f"✓ UEFI GRUB 模块安装成功")
|
||||||
|
return True, ""
|
||||||
|
else:
|
||||||
|
log_error("UEFI GRUB 模块安装后仍不存在")
|
||||||
|
return False, "UEFI 模块安装失败"
|
||||||
|
|
||||||
|
|
||||||
def install_efi_fallback(mount_point: str, efi_target: str, efi_grub_file: str,
|
def install_efi_fallback(mount_point: str, efi_target: str, efi_grub_file: str,
|
||||||
efi_boot_file: str, bootloader_id: str = "GRUB") -> bool:
|
efi_boot_file: str, bootloader_id: str = "GRUB") -> bool:
|
||||||
"""
|
"""
|
||||||
@@ -1704,6 +1793,12 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
efi_target, efi_grub_file, efi_boot_file = efi_params
|
efi_target, efi_grub_file, efi_boot_file = efi_params
|
||||||
log_info(f"EFI 参数: target={efi_target}, grub={efi_grub_file}, boot={efi_boot_file}")
|
log_info(f"EFI 参数: target={efi_target}, grub={efi_grub_file}, boot={efi_boot_file}")
|
||||||
|
|
||||||
|
# 检查并安装 UEFI GRUB 模块
|
||||||
|
efi_modules_ok, efi_modules_err = check_and_install_efi_modules(mount_point, distro_type, True)
|
||||||
|
if not efi_modules_ok:
|
||||||
|
log_error(f"UEFI 模块检查失败: {efi_modules_err}")
|
||||||
|
return False, f"UEFI 模块检查失败: {efi_modules_err}"
|
||||||
|
|
||||||
grub_install_success = False
|
grub_install_success = False
|
||||||
install_errors = []
|
install_errors = []
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user