fix
This commit is contained in:
156
frontend.py
156
frontend.py
@@ -3,6 +3,8 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox
|
||||
import threading
|
||||
import os
|
||||
import re
|
||||
import backend # 导入后端逻辑
|
||||
|
||||
class GrubRepairApp:
|
||||
@@ -153,18 +155,31 @@ class GrubRepairApp:
|
||||
self.selected_root_partition_info = self.all_partitions_data.get(selected_display)
|
||||
|
||||
if self.selected_root_partition_info:
|
||||
self.log_message(f"已选择根分区: {self.selected_root_partition_info['name']}", "info")
|
||||
# 尝试根据根分区所在的磁盘自动选择目标磁盘
|
||||
# /dev/sda1 -> /dev/sda
|
||||
disk_name_from_root = "/".join(self.selected_root_partition_info['name'].split('/')[:3])
|
||||
if disk_name_from_root in self.target_disk_combo['values']:
|
||||
self.target_disk_combo.set(disk_name_from_root)
|
||||
self.selected_target_disk_info = self.all_disks_data.get(disk_name_from_root)
|
||||
self.log_message(f"自动选择目标磁盘: {self.selected_target_disk_info['name']}", "info")
|
||||
else:
|
||||
root_part_name = self.selected_root_partition_info['name']
|
||||
self.log_message(f"已选择根分区: {root_part_name}", "info")
|
||||
|
||||
# 检查是否是 LVM 逻辑卷
|
||||
is_lvm = self.selected_root_partition_info.get('is_lvm', False)
|
||||
|
||||
if is_lvm:
|
||||
# LVM 逻辑卷无法直接从路径推断父磁盘,提示用户手动选择
|
||||
self.target_disk_combo.set("")
|
||||
self.selected_target_disk_info = None
|
||||
self.log_message("无法自动选择目标磁盘,请手动选择。", "warning")
|
||||
self.log_message("检测到 LVM 逻辑卷,请手动选择 GRUB 安装的目标磁盘。", "warning")
|
||||
else:
|
||||
# 尝试根据根分区所在的磁盘自动选择目标磁盘
|
||||
# /dev/sda1 -> /dev/sda
|
||||
# /dev/nvme0n1p1 -> /dev/nvme0n1
|
||||
# /dev/mmcblk0p1 -> /dev/mmcblk0
|
||||
disk_name_from_root = re.sub(r'(\d+)?p?\d+$', '', root_part_name)
|
||||
if disk_name_from_root in self.target_disk_combo['values']:
|
||||
self.target_disk_combo.set(disk_name_from_root)
|
||||
self.selected_target_disk_info = self.all_disks_data.get(disk_name_from_root)
|
||||
self.log_message(f"自动选择目标磁盘: {self.selected_target_disk_info['name']}", "info")
|
||||
else:
|
||||
self.target_disk_combo.set("")
|
||||
self.selected_target_disk_info = None
|
||||
self.log_message("无法自动选择目标磁盘,请手动选择。", "warning")
|
||||
else:
|
||||
self.selected_root_partition_info = None
|
||||
self.target_disk_combo.set("")
|
||||
@@ -215,71 +230,76 @@ class GrubRepairApp:
|
||||
repair_thread.start()
|
||||
|
||||
def _run_repair_process(self):
|
||||
root_part_path = self.selected_root_partition_info['name']
|
||||
boot_part_path = self.selected_boot_partition_info['name'] if self.selected_boot_partition_info else None
|
||||
efi_part_path = self.selected_efi_partition_info['name'] if self.selected_efi_partition_info else None
|
||||
target_disk_path = self.selected_target_disk_info['name']
|
||||
try:
|
||||
root_part_path = self.selected_root_partition_info['name']
|
||||
boot_part_path = self.selected_boot_partition_info['name'] if self.selected_boot_partition_info else None
|
||||
efi_part_path = self.selected_efi_partition_info['name'] if self.selected_efi_partition_info else None
|
||||
target_disk_path = self.selected_target_disk_info['name']
|
||||
|
||||
self.log_message(f"选择的根分区: {root_part_path}", "info")
|
||||
self.log_message(f"选择的独立 /boot 分区: {boot_part_path if boot_part_path else '无'}", "info")
|
||||
self.log_message(f"选择的EFI分区: {efi_part_path if efi_part_path else '无'}", "info")
|
||||
self.log_message(f"GRUB安装目标磁盘: {target_disk_path}", "info")
|
||||
self.log_message(f"UEFI模式: {'启用' if self.is_uefi_mode else '禁用'}", "info")
|
||||
self.log_message(f"选择的根分区: {root_part_path}", "info")
|
||||
self.log_message(f"选择的独立 /boot 分区: {boot_part_path if boot_part_path else '无'}", "info")
|
||||
self.log_message(f"选择的EFI分区: {efi_part_path if efi_part_path else '无'}", "info")
|
||||
self.log_message(f"GRUB安装目标磁盘: {target_disk_path}", "info")
|
||||
self.log_message(f"UEFI模式: {'启用' if self.is_uefi_mode else '禁用'}", "info")
|
||||
|
||||
# 1. 挂载目标系统
|
||||
self.log_message("正在挂载目标系统分区...", "info")
|
||||
mount_ok, self.mount_point, mount_err = backend.mount_target_system(
|
||||
root_part_path,
|
||||
boot_part_path,
|
||||
efi_part_path if self.is_uefi_mode else None # 只有UEFI模式才挂载EFI分区
|
||||
)
|
||||
if not mount_ok:
|
||||
self.log_message(f"挂载失败,修复中止: {mount_err}", "error")
|
||||
messagebox.showerror("修复失败", f"无法挂载目标系统分区。请检查分区选择和权限。\n错误: {mount_err}")
|
||||
self.start_button.config(state="normal")
|
||||
return
|
||||
# 1. 挂载目标系统
|
||||
self.log_message("正在挂载目标系统分区...", "info")
|
||||
mount_ok, self.mount_point, mount_err = backend.mount_target_system(
|
||||
root_part_path,
|
||||
boot_part_path,
|
||||
efi_part_path if self.is_uefi_mode else None # 只有UEFI模式才挂载EFI分区
|
||||
)
|
||||
if not mount_ok:
|
||||
self.log_message(f"挂载失败,修复中止: {mount_err}", "error")
|
||||
self.master.after(0, lambda: messagebox.showerror("修复失败", f"无法挂载目标系统分区。请检查分区选择和权限。\n错误: {mount_err}"))
|
||||
return
|
||||
|
||||
# 2. 尝试识别发行版类型
|
||||
self.log_message("正在检测目标系统发行版...", "info")
|
||||
distro_type = backend.detect_distro_type(self.mount_point)
|
||||
self.log_message(f"检测到目标系统发行版: {distro_type}", "info")
|
||||
# 2. 尝试识别发行版类型
|
||||
self.log_message("正在检测目标系统发行版...", "info")
|
||||
distro_type = backend.detect_distro_type(self.mount_point)
|
||||
self.log_message(f"检测到目标系统发行版: {distro_type}", "info")
|
||||
|
||||
# 3. Chroot并修复GRUB
|
||||
self.log_message("正在进入Chroot环境并修复GRUB...", "info")
|
||||
repair_ok, repair_err = backend.chroot_and_repair_grub(
|
||||
self.mount_point,
|
||||
target_disk_path,
|
||||
self.is_uefi_mode,
|
||||
distro_type
|
||||
)
|
||||
if not repair_ok:
|
||||
self.log_message(f"GRUB修复失败: {repair_err}", "error")
|
||||
messagebox.showerror("修复失败", f"GRUB修复过程中发生错误。\n错误: {repair_err}")
|
||||
# 即使失败,也要尝试卸载
|
||||
else:
|
||||
self.log_message("GRUB修复命令执行成功!", "success")
|
||||
# 3. Chroot并修复GRUB
|
||||
self.log_message("正在进入Chroot环境并修复GRUB...", "info")
|
||||
repair_ok, repair_err = backend.chroot_and_repair_grub(
|
||||
self.mount_point,
|
||||
target_disk_path,
|
||||
self.is_uefi_mode,
|
||||
distro_type
|
||||
)
|
||||
if not repair_ok:
|
||||
self.log_message(f"GRUB修复失败: {repair_err}", "error")
|
||||
self.master.after(0, lambda: messagebox.showerror("修复失败", f"GRUB修复过程中发生错误。\n错误: {repair_err}"))
|
||||
# 即使失败,也要尝试卸载
|
||||
else:
|
||||
self.log_message("GRUB修复命令执行成功!", "success")
|
||||
|
||||
|
||||
# 4. 卸载分区
|
||||
self.log_message("正在卸载目标系统分区...", "info")
|
||||
unmount_ok, unmount_err = backend.unmount_target_system(self.mount_point)
|
||||
if not unmount_ok:
|
||||
self.log_message(f"卸载分区失败: {unmount_err}", "error")
|
||||
messagebox.showwarning("卸载警告", f"部分分区可能未能正确卸载。请手动检查并卸载。\n错误: {unmount_err}")
|
||||
else:
|
||||
self.log_message("所有分区已成功卸载。", "success")
|
||||
# 4. 卸载分区
|
||||
self.log_message("正在卸载目标系统分区...", "info")
|
||||
unmount_ok, unmount_err = backend.unmount_target_system(self.mount_point)
|
||||
if not unmount_ok:
|
||||
self.log_message(f"卸载分区失败: {unmount_err}", "error")
|
||||
self.master.after(0, lambda: messagebox.showwarning("卸载警告", f"部分分区可能未能正确卸载。请手动检查并卸载。\n错误: {unmount_err}"))
|
||||
else:
|
||||
self.log_message("所有分区已成功卸载。", "success")
|
||||
|
||||
self.log_message("--- GRUB 修复过程结束 ---", "info")
|
||||
|
||||
# 最终结果提示
|
||||
if repair_ok and unmount_ok:
|
||||
self.master.after(0, lambda: messagebox.showinfo("修复成功", "GRUB引导修复已完成!请重启系统以验证。"))
|
||||
elif repair_ok and not unmount_ok:
|
||||
self.master.after(0, lambda: messagebox.showwarning("修复完成,但有警告", "GRUB引导修复已完成,但部分分区卸载失败。请重启系统以验证。"))
|
||||
else:
|
||||
self.master.after(0, lambda: messagebox.showerror("修复失败", "GRUB引导修复过程中发生错误。请检查日志并尝试手动修复。"))
|
||||
|
||||
self.log_message("--- GRUB 修复过程结束 ---", "info")
|
||||
|
||||
# 最终结果提示
|
||||
if repair_ok and unmount_ok:
|
||||
messagebox.showinfo("修复成功", "GRUB引导修复已完成!请重启系统以验证。")
|
||||
elif repair_ok and not unmount_ok:
|
||||
messagebox.showwarning("修复完成,但有警告", "GRUB引导修复已完成,但部分分区卸载失败。请重启系统以验证。")
|
||||
else:
|
||||
messagebox.showerror("修复失败", "GRUB引导修复过程中发生错误。请检查日志并尝试手动修复。")
|
||||
|
||||
self.start_button.config(state="normal")
|
||||
except Exception as e:
|
||||
self.log_message(f"发生未预期的错误: {str(e)}", "error")
|
||||
self.master.after(0, lambda err=str(e): messagebox.showerror("错误", f"修复过程中发生错误:\n{err}"))
|
||||
finally:
|
||||
# 确保按钮状态被恢复
|
||||
self.master.after(0, lambda: self.start_button.config(state="normal"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user