fix 23
This commit is contained in:
@@ -16,6 +16,7 @@ class LvmOperations:
|
||||
:param error_message: 命令失败时显示给用户的错误消息。
|
||||
:param root_privilege: 如果为 True,则使用 sudo 执行命令。
|
||||
:param suppress_critical_dialog_on_stderr_match: 如果 stderr 包含此字符串,则不显示关键错误对话框。
|
||||
可以是字符串或字符串元组/列表。
|
||||
:param input_data: 传递给命令stdin的数据 (str)。
|
||||
:return: (True/False, stdout_str, stderr_str)
|
||||
"""
|
||||
@@ -48,11 +49,24 @@ class LvmOperations:
|
||||
logger.error(f"标准输出: {e.stdout.strip()}")
|
||||
logger.error(f"标准错误: {stderr_output}")
|
||||
|
||||
if suppress_critical_dialog_on_stderr_match and \
|
||||
suppress_critical_dialog_on_stderr_match in stderr_output:
|
||||
# --- 修改开始:处理 suppress_critical_dialog_on_stderr_match 可以是字符串或元组/列表 ---
|
||||
should_suppress_dialog = False
|
||||
if suppress_critical_dialog_on_stderr_match:
|
||||
if isinstance(suppress_critical_dialog_on_stderr_match, str):
|
||||
if suppress_critical_dialog_on_stderr_match in stderr_output:
|
||||
should_suppress_dialog = True
|
||||
elif isinstance(suppress_critical_dialog_on_stderr_match, (list, tuple)):
|
||||
for pattern in suppress_critical_dialog_on_stderr_match:
|
||||
if pattern in stderr_output:
|
||||
should_suppress_dialog = True
|
||||
break # 找到一个匹配就足够了
|
||||
|
||||
if should_suppress_dialog:
|
||||
logger.info(f"错误信息 '{stderr_output}' 匹配抑制条件,不显示关键错误对话框。")
|
||||
else:
|
||||
QMessageBox.critical(None, "错误", f"{error_message}\n错误详情: {stderr_output}")
|
||||
# --- 修改结束 ---
|
||||
|
||||
return False, e.stdout.strip(), stderr_output
|
||||
except FileNotFoundError:
|
||||
QMessageBox.critical(None, "错误", f"命令 '{command_list[0]}' 未找到。请确保已安装相关工具。")
|
||||
@@ -66,7 +80,7 @@ class LvmOperations:
|
||||
def create_pv(self, device_path):
|
||||
"""
|
||||
创建物理卷 (PV)。
|
||||
:param device_path: 设备的路径,例如 /dev/sdb1。
|
||||
:param device_path: 设备的路径,例如 /dev/sdb1 或 /dev/sdb。
|
||||
:return: True 如果成功,否则 False。
|
||||
"""
|
||||
if not isinstance(device_path, str):
|
||||
@@ -82,15 +96,58 @@ class LvmOperations:
|
||||
return False
|
||||
|
||||
logger.info(f"尝试在 {device_path} 上创建物理卷。")
|
||||
# 第一次尝试创建物理卷,抑制 "device is partitioned" 错误,因为我们将在代码中处理它
|
||||
success, _, stderr = self._execute_shell_command(
|
||||
["pvcreate", "-y", device_path], # -y 自动确认
|
||||
f"在 {device_path} 上创建物理卷失败"
|
||||
f"在 {device_path} 上创建物理卷失败",
|
||||
suppress_critical_dialog_on_stderr_match="device is partitioned" # 抑制此特定错误
|
||||
)
|
||||
|
||||
if success:
|
||||
QMessageBox.information(None, "成功", f"物理卷已在 {device_path} 上成功创建。")
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
# 如果 pvcreate 失败,检查是否是 "device is partitioned" 错误
|
||||
if "device is partitioned" in stderr:
|
||||
# 提示用户是否要擦除分区表
|
||||
wipe_reply = QMessageBox.question(
|
||||
None, "设备已分区",
|
||||
f"设备 {device_path} 已分区。您是否要擦除设备上的所有分区表,"
|
||||
f"并将其整个用于物理卷?此操作将导致所有数据丢失!",
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.No
|
||||
)
|
||||
if wipe_reply == QMessageBox.Yes:
|
||||
logger.warning(f"用户选择擦除 {device_path} 上的分区表并创建物理卷。")
|
||||
# 尝试擦除分区表 (使用 GPT 作为默认,通常更现代且支持大容量磁盘)
|
||||
# 注意:这里需要 parted 命令,确保系统已安装 parted
|
||||
mklabel_success, _, mklabel_stderr = self._execute_shell_command(
|
||||
["parted", "-s", device_path, "mklabel", "gpt"], # 使用 gpt 分区表
|
||||
f"擦除 {device_path} 上的分区表失败"
|
||||
)
|
||||
if mklabel_success:
|
||||
logger.info(f"已成功擦除 {device_path} 上的分区表。重试创建物理卷。")
|
||||
# 再次尝试创建物理卷
|
||||
retry_success, _, retry_stderr = self._execute_shell_command(
|
||||
["pvcreate", "-y", device_path],
|
||||
f"在 {device_path} 上创建物理卷失败 (重试)"
|
||||
# 重试时不再抑制,如果再次失败,_execute_shell_command 会显示错误
|
||||
)
|
||||
if retry_success:
|
||||
QMessageBox.information(None, "成功", f"物理卷已在 {device_path} 上成功创建。")
|
||||
return True
|
||||
else:
|
||||
# 如果重试失败,_execute_shell_command 已经显示错误
|
||||
return False
|
||||
else:
|
||||
# mklabel 失败,_execute_shell_command 已经显示错误
|
||||
return False
|
||||
else:
|
||||
logger.info(f"用户取消了擦除 {device_path} 分区表的操作。")
|
||||
QMessageBox.information(None, "信息", f"未在已分区设备 {device_path} 上创建物理卷。")
|
||||
return False
|
||||
else:
|
||||
# 对于其他类型的 pvcreate 失败,_execute_shell_command 已经显示了错误
|
||||
return False
|
||||
|
||||
def delete_pv(self, device_path):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user