1
This commit is contained in:
108
backend.py
108
backend.py
@@ -1342,13 +1342,28 @@ def _manual_install_efi_files(mount_point: str, efi_target: str, efi_grub_file:
|
|||||||
# 构建 chroot 内的输出路径
|
# 构建 chroot 内的输出路径
|
||||||
chroot_output_path = f"/boot/efi/EFI/{bootloader_id}/{efi_grub_file}"
|
chroot_output_path = f"/boot/efi/EFI/{bootloader_id}/{efi_grub_file}"
|
||||||
|
|
||||||
|
# 检测是否有独立的 /boot 分区
|
||||||
|
has_separate_boot = os.path.ismount(os.path.join(mount_point, "boot"))
|
||||||
|
|
||||||
|
# 确定正确的 prefix
|
||||||
|
# 对于独立 /boot 分区,使用 '(<device>)/grub2' 格式,让 GRUB 自动搜索
|
||||||
|
# 或者使用 '/boot/grub2' 配合 search 命令
|
||||||
|
if has_separate_boot:
|
||||||
|
# 独立 /boot 分区:使用相对路径,依赖 grub.cfg 中的 search 命令
|
||||||
|
# 或者使用 '(,gpt2)/grub2' 格式指定分区
|
||||||
|
grub_prefix = "/grub2"
|
||||||
|
log_info(f"检测到独立 /boot 分区,使用 prefix: {grub_prefix}")
|
||||||
|
else:
|
||||||
|
grub_prefix = "/boot/grub2"
|
||||||
|
log_info(f"使用标准 prefix: {grub_prefix}")
|
||||||
|
|
||||||
# 尝试使用 grub-mkimage 生成 EFI 文件
|
# 尝试使用 grub-mkimage 生成 EFI 文件
|
||||||
chroot_cmd_prefix = ["sudo", "chroot", mount_point]
|
chroot_cmd_prefix = ["sudo", "chroot", mount_point]
|
||||||
mkimage_cmd = chroot_cmd_prefix + [
|
mkimage_cmd = chroot_cmd_prefix + [
|
||||||
"grub2-mkimage",
|
"grub2-mkimage",
|
||||||
"-o", chroot_output_path,
|
"-o", chroot_output_path,
|
||||||
"-O", efi_target,
|
"-O", efi_target,
|
||||||
"-p", "/boot/grub2",
|
"-p", grub_prefix,
|
||||||
] + modules.split()
|
] + modules.split()
|
||||||
|
|
||||||
success, _, stderr = run_command(
|
success, _, stderr = run_command(
|
||||||
@@ -1361,6 +1376,38 @@ def _manual_install_efi_files(mount_point: str, efi_target: str, efi_grub_file:
|
|||||||
host_output_path = os.path.join(mount_point, chroot_output_path.lstrip('/'))
|
host_output_path = os.path.join(mount_point, chroot_output_path.lstrip('/'))
|
||||||
if success and os.path.exists(host_output_path):
|
if success and os.path.exists(host_output_path):
|
||||||
log_success(f"✓ 成功生成 EFI 文件: {host_output_path}")
|
log_success(f"✓ 成功生成 EFI 文件: {host_output_path}")
|
||||||
|
|
||||||
|
# 对于独立 /boot 分区,创建一个辅助的 grub.cfg 来设置正确的 root
|
||||||
|
if has_separate_boot:
|
||||||
|
log_info("为独立 /boot 分区创建辅助 grub.cfg...")
|
||||||
|
helper_cfg_path = os.path.join(mount_point, f"boot/efi/EFI/{bootloader_id}/grub.cfg")
|
||||||
|
try:
|
||||||
|
helper_cfg = '''# Auto-generated by BootRepairTool for separate /boot partition
|
||||||
|
# This file sets the correct root and loads the main config
|
||||||
|
|
||||||
|
# Search for the /boot partition by filesystem type and files
|
||||||
|
search --no-floppy --fs-uuid --set=root
|
||||||
|
|
||||||
|
# If search fails, try common partition numbers
|
||||||
|
if [ "${root}" = "${prefix}" ]; then
|
||||||
|
# Try (hd0,gpt2) - common /boot partition
|
||||||
|
if [ -f (hd0,gpt2)/grub2/grub.cfg ]; then
|
||||||
|
set root=(hd0,gpt2)
|
||||||
|
set prefix=(hd0,gpt2)/grub2
|
||||||
|
elif [ -f (hd0,2)/grub2/grub.cfg ]; then
|
||||||
|
set root=(hd0,2)
|
||||||
|
set prefix=(hd0,2)/grub2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Load the main configuration
|
||||||
|
configfile ${prefix}/grub.cfg
|
||||||
|
'''
|
||||||
|
with open(helper_cfg_path, 'w') as f:
|
||||||
|
f.write(helper_cfg)
|
||||||
|
log_success(f"✓ 创建辅助 grub.cfg: {helper_cfg_path}")
|
||||||
|
except Exception as e:
|
||||||
|
log_warning(f"创建辅助 grub.cfg 失败: {e}")
|
||||||
else:
|
else:
|
||||||
log_error(f"生成 EFI 文件失败: {stderr}")
|
log_error(f"生成 EFI 文件失败: {stderr}")
|
||||||
return False
|
return False
|
||||||
@@ -2519,8 +2566,65 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
|||||||
log_warning(f"查找内核文件失败: {e}")
|
log_warning(f"查找内核文件失败: {e}")
|
||||||
|
|
||||||
if kernel_files and root_uuid:
|
if kernel_files and root_uuid:
|
||||||
|
# 检测是否有独立 /boot 分区
|
||||||
|
boot_uuid = None
|
||||||
|
try:
|
||||||
|
boot_mount_point = os.path.join(mount_point, "boot")
|
||||||
|
if os.path.ismount(boot_mount_point):
|
||||||
|
# 有独立 /boot 分区,获取其 UUID
|
||||||
|
success_uuid, uuid_out, _ = run_command(
|
||||||
|
["sudo", "blkid", "-s", "UUID", "-o", "value", boot_mount_point],
|
||||||
|
"获取 /boot 分区 UUID",
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
if success_uuid:
|
||||||
|
boot_uuid = uuid_out.strip()
|
||||||
|
log_info(f"检测到独立 /boot 分区,UUID: {boot_uuid}")
|
||||||
|
except Exception as e:
|
||||||
|
log_warning(f"获取 /boot UUID 失败: {e}")
|
||||||
|
|
||||||
# 创建基本 grub.cfg
|
# 创建基本 grub.cfg
|
||||||
|
if boot_uuid:
|
||||||
|
# 独立 /boot 分区配置 - 需要先搜索 /boot 分区
|
||||||
grub_cfg_content = f"""# Minimal GRUB config generated by BootRepairTool
|
grub_cfg_content = f"""# Minimal GRUB config generated by BootRepairTool
|
||||||
|
# For system with separate /boot partition
|
||||||
|
|
||||||
|
set timeout=5
|
||||||
|
set default=0
|
||||||
|
|
||||||
|
# Load necessary modules
|
||||||
|
insmod part_gpt
|
||||||
|
insmod xfs
|
||||||
|
insmod fat
|
||||||
|
|
||||||
|
# Search for the /boot partition by UUID, then set root to the system root
|
||||||
|
search --no-floppy --fs-uuid --set=root {boot_uuid}
|
||||||
|
set prefix=($root)/grub2
|
||||||
|
|
||||||
|
menuentry 'CentOS Linux (Auto)' {{
|
||||||
|
load_video
|
||||||
|
set gfxpayload=keep
|
||||||
|
insmod gzio
|
||||||
|
insmod part_gpt
|
||||||
|
insmod xfs
|
||||||
|
linux /{kernel_files[0]} root=UUID={root_uuid} ro rhgb quiet
|
||||||
|
initrd /{initramfs_files[0] if initramfs_files else ''}
|
||||||
|
}}
|
||||||
|
|
||||||
|
menuentry 'CentOS Linux (Rescue)' {{
|
||||||
|
load_video
|
||||||
|
set gfxpayload=keep
|
||||||
|
insmod gzio
|
||||||
|
insmod part_gpt
|
||||||
|
insmod xfs
|
||||||
|
linux /{kernel_files[0]} root=UUID={root_uuid} ro rescue
|
||||||
|
initrd /{initramfs_files[0] if initramfs_files else ''}
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
# 无独立 /boot 分区配置
|
||||||
|
grub_cfg_content = f"""# Minimal GRUB config generated by BootRepairTool
|
||||||
|
|
||||||
set timeout=5
|
set timeout=5
|
||||||
set default=0
|
set default=0
|
||||||
|
|
||||||
@@ -2538,7 +2642,7 @@ menuentry 'CentOS Linux (Auto)' {{
|
|||||||
insmod gzio
|
insmod gzio
|
||||||
insmod part_gpt
|
insmod part_gpt
|
||||||
insmod xfs
|
insmod xfs
|
||||||
linux /{kernel_files[0]} root=UUID={root_uuid} ro
|
linux /{kernel_files[0]} root=UUID={root_uuid} ro rhgb quiet
|
||||||
initrd /{initramfs_files[0] if initramfs_files else ''}
|
initrd /{initramfs_files[0] if initramfs_files else ''}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user