This commit is contained in:
zj
2026-02-03 15:18:43 +08:00
parent f17080b506
commit 38ce31d93e
5 changed files with 480 additions and 143 deletions

View File

@@ -330,7 +330,7 @@ class MainWindow(QMainWindow):
self.ui.treeWidget_raid.header().setSectionResizeMode(i, QHeaderView.ResizeToContents)
try:
raid_arrays = self.system_manager.get_mdadm_arrays()
raid_arrays = self.system_manager.get_mdadm_arrays() # 现在会返回所有阵列,包括停止的
if not raid_arrays:
item = QTreeWidgetItem(self.ui.treeWidget_raid)
item.setText(0, "未找到RAID阵列。")
@@ -344,11 +344,14 @@ class MainWindow(QMainWindow):
logger.warning(f"RAID阵列 '{array.get('name', '未知')}' 的设备路径无效,跳过。")
continue
current_mount_point = self.system_manager.get_mountpoint_for_device(array_path)
# 对于停止状态的阵列,挂载点可能不存在或不相关
current_mount_point = ""
if array.get('state') != 'Stopped (Configured)':
current_mount_point = self.system_manager.get_mountpoint_for_device(array_path)
array_item.setText(0, array_path)
array_item.setText(1, array.get('level', 'N/A'))
array_item.setText(2, array.get('state', 'N/A'))
array_item.setText(2, array.get('state', 'N/A')) # 显示实际状态
array_item.setText(3, array.get('array_size', 'N/A'))
array_item.setText(4, array.get('active_devices', 'N/A'))
array_item.setText(5, array.get('failed_devices', 'N/A'))
@@ -359,16 +362,18 @@ class MainWindow(QMainWindow):
array_item.setText(10, array.get('chunk_size', 'N/A'))
array_item.setText(11, current_mount_point if current_mount_point else "")
array_item.setExpanded(True)
array_data_for_context = array.copy()
array_data_for_context['device'] = array_path
array_item.setData(0, Qt.UserRole, array_data_for_context)
for member in array.get('member_devices', []):
member_item = QTreeWidgetItem(array_item)
member_item.setText(0, f" {member.get('device_path', 'N/A')}")
member_item.setText(1, f"成员: {member.get('raid_device', 'N/A')}")
member_item.setText(2, member.get('state', 'N/A'))
member_item.setText(3, f"Major: {member.get('major', 'N/A')}, Minor: {member.get('minor', 'N/A')}")
# 存储完整的阵列数据,包括状态,供上下文菜单使用
array_item.setData(0, Qt.UserRole, array)
# 对于停止状态的阵列,成员设备可能为空,跳过显示子项
if array.get('state') != 'Stopped (Configured)':
for member in array.get('member_devices', []):
member_item = QTreeWidgetItem(array_item)
member_item.setText(0, f" {member.get('device_path', 'N/A')}")
member_item.setText(1, f"成员: {member.get('raid_device', 'N/A')}") # 假设 raid_device 字段存在
member_item.setText(2, member.get('state', 'N/A'))
# member_item.setText(3, f"Major: {member.get('major', 'N/A')}, Minor: {member.get('minor', 'N/A')}") # 假设 major/minor 字段存在
for i in range(len(raid_headers)):
self.ui.treeWidget_raid.resizeColumnToContents(i)
@@ -379,49 +384,95 @@ class MainWindow(QMainWindow):
logger.error(f"刷新RAID阵列信息失败: {e}")
def show_raid_context_menu(self, pos: QPoint):
item = self.ui.treeWidget_raid.itemAt(pos)
menu = QMenu(self)
item = self.ui.treeWidget_raid.itemAt(pos)
menu = QMenu(self)
create_raid_action = menu.addAction("创建 RAID 阵列...")
create_raid_action.triggered.connect(self._handle_create_raid_array)
menu.addSeparator()
if item and item.parent() is None:
array_data = item.data(0, Qt.UserRole)
if not array_data:
logger.warning(f"无法获取 RAID 阵列 {item.text(0)} 的详细数据。")
return
array_path = array_data.get('device')
member_devices = [m.get('device_path') for m in array_data.get('member_devices', [])]
if not array_path or array_path == 'N/A':
logger.warning(f"RAID阵列 '{array_data.get('name', '未知')}' 的设备路径无效,无法显示操作。")
return
current_mount_point = self.system_manager.get_mountpoint_for_device(array_path)
if current_mount_point and current_mount_point != '[SWAP]' and current_mount_point != '':
unmount_action = menu.addAction(f"卸载 {array_path} ({current_mount_point})")
unmount_action.triggered.connect(lambda: self._unmount_and_refresh(array_path))
else:
mount_action = menu.addAction(f"挂载 {array_path}...")
mount_action.triggered.connect(lambda: self._handle_mount(array_path))
create_raid_action = menu.addAction("创建 RAID 阵列...")
create_raid_action.triggered.connect(self._handle_create_raid_array)
menu.addSeparator()
stop_action = menu.addAction(f"停止阵列 {array_path}")
stop_action.triggered.connect(lambda: self._handle_stop_raid_array(array_path))
if item and item.parent() is None: # 只针对顶层阵列项
array_data = item.data(0, Qt.UserRole)
if not array_data:
logger.warning(f"无法获取 RAID 阵列 {item.text(0)} 的详细数据。")
return
delete_action = menu.addAction(f"删除阵列 {array_path}")
delete_action.triggered.connect(lambda: self._handle_delete_raid_array(array_path, member_devices))
array_path = array_data.get('device')
array_state = array_data.get('state', 'N/A')
member_devices = [m.get('device_path') for m in array_data.get('member_devices', [])]
array_uuid = array_data.get('uuid') # <--- 获取 UUID
format_action = menu.addAction(f"格式化阵列 {array_path}...")
format_action.triggered.connect(lambda: self._handle_format_raid_array(array_path))
if not array_path or array_path == 'N/A':
logger.warning(f"RAID阵列 '{array_data.get('name', '未知')}' 的设备路径无效,无法显示操作。")
return
if menu.actions():
menu.exec(self.ui.treeWidget_raid.mapToGlobal(pos))
else:
logger.info("右键点击了空白区域或没有可用的RAID操作。")
if array_state == 'Stopped (Configured)':
activate_action = menu.addAction(f"激活阵列 {array_path}")
activate_action.triggered.connect(lambda: self._handle_activate_raid_array(array_path))
# <--- 新增:删除停止状态阵列的配置条目
delete_config_action = menu.addAction(f"删除配置文件条目 (UUID: {array_uuid})")
delete_config_action.triggered.connect(lambda: self._handle_delete_configured_raid_array(array_uuid))
# 停止状态的阵列不显示卸载、停止、删除、格式化等操作
else: # 活动或降级状态的阵列
current_mount_point = self.system_manager.get_mountpoint_for_device(array_path)
if current_mount_point and current_mount_point != '[SWAP]' and current_mount_point != '':
unmount_action = menu.addAction(f"卸载 {array_path} ({current_mount_point})")
unmount_action.triggered.connect(lambda: self._unmount_and_refresh(array_path))
else:
mount_action = menu.addAction(f"挂载 {array_path}...")
mount_action.triggered.connect(lambda: self._handle_mount(array_path))
menu.addSeparator()
stop_action = menu.addAction(f"停止阵列 {array_path}")
stop_action.triggered.connect(lambda: self._handle_stop_raid_array(array_path))
# <--- 修改:删除活动阵列的动作,传递 UUID
delete_action = menu.addAction(f"删除阵列 {array_path}")
delete_action.triggered.connect(lambda: self._handle_delete_active_raid_array(array_path, member_devices, array_uuid))
format_action = menu.addAction(f"格式化阵列 {array_path}...")
format_action.triggered.connect(lambda: self._handle_format_raid_array(array_path))
if menu.actions():
menu.exec(self.ui.treeWidget_raid.mapToGlobal(pos))
else:
logger.info("右键点击了空白区域或没有可用的RAID操作。")
def _handle_activate_raid_array(self, array_path):
"""
处理激活已停止的 RAID 阵列。
"""
item = self.ui.treeWidget_raid.currentItem() # 获取当前选中的项
if not item or item.parent() is not None: # 确保是顶层阵列项
logger.warning("未选择有效的 RAID 阵列进行激活。")
return
array_data = item.data(0, Qt.UserRole)
if not array_data or array_data.get('device') != array_path:
logger.error(f"获取 RAID 阵列 {array_path} 的数据失败或数据不匹配。")
return
array_uuid = array_data.get('uuid')
if not array_uuid or array_uuid == 'N/A':
QMessageBox.critical(self, "错误", f"无法激活 RAID 阵列 {array_path}:缺少 UUID 信息。")
logger.error(f"激活 RAID 阵列 {array_path} 失败:缺少 UUID。")
return
reply = QMessageBox.question(
self,
"确认激活 RAID 阵列",
f"您确定要激活 RAID 阵列 {array_path} (UUID: {array_uuid}) 吗?\n"
"这将尝试重新组装阵列。",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
)
if reply == QMessageBox.No:
logger.info(f"用户取消了激活 RAID 阵列 {array_path} 的操作。")
return
if self.raid_ops.activate_raid_array(array_path, array_uuid): # 传递 UUID
self.refresh_all_info()
def _handle_create_raid_array(self):
available_devices = self.system_manager.get_unallocated_partitions()
@@ -441,8 +492,18 @@ class MainWindow(QMainWindow):
if self.raid_ops.stop_raid_array(array_path):
self.refresh_all_info()
def _handle_delete_raid_array(self, array_path, member_devices):
if self.raid_ops.delete_raid_array(array_path, member_devices):
def _handle_delete_active_raid_array(self, array_path, member_devices, uuid): # <--- 修改方法名并添加 uuid 参数
"""
处理删除活动 RAID 阵列的操作。
"""
if self.raid_ops.delete_active_raid_array(array_path, member_devices, uuid): # <--- 调用修改后的方法
self.refresh_all_info()
def _handle_delete_configured_raid_array(self, uuid): # <--- 新增方法
"""
处理删除停止状态 RAID 阵列的配置文件条目。
"""
if self.raid_ops.delete_configured_raid_array(uuid):
self.refresh_all_info()
def _handle_format_raid_array(self, array_path):
@@ -789,3 +850,4 @@ if __name__ == "__main__":
widget = MainWindow()
widget.show()
sys.exit(app.exec())