fix bug
This commit is contained in:
115
system_info.py
115
system_info.py
@@ -4,6 +4,7 @@ import json
|
||||
import logging
|
||||
import re
|
||||
import os
|
||||
from system_compat import get_system_compat
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,20 +27,26 @@ class SystemInfoManager:
|
||||
|
||||
logger.debug(f"运行命令: {' '.join(command_list)}")
|
||||
try:
|
||||
# Python 3.6 兼容: 使用 stdout/stderr 参数代替 capture_output
|
||||
# Python 3.6 兼容: 不使用 text 参数,手动解码
|
||||
result = subprocess.run(
|
||||
command_list,
|
||||
capture_output=check_output,
|
||||
text=True,
|
||||
stdout=subprocess.PIPE if check_output else None,
|
||||
stderr=subprocess.PIPE if check_output else None,
|
||||
stdin=subprocess.PIPE if input_data else None,
|
||||
check=True,
|
||||
encoding='utf-8',
|
||||
encoding='utf-8' if check_output else None,
|
||||
input=input_data
|
||||
)
|
||||
return result.stdout if check_output else "", result.stderr if check_output else ""
|
||||
if check_output:
|
||||
return result.stdout, result.stderr
|
||||
else:
|
||||
return "", ""
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(f"命令执行失败: {' '.join(command_list)}")
|
||||
logger.error(f"退出码: {e.returncode}")
|
||||
logger.error(f"标准输出: {e.stdout.strip()}")
|
||||
logger.error(f"标准错误: {e.stderr.strip()}")
|
||||
logger.error(f"标准输出: {e.stdout.strip() if e.stdout else ''}")
|
||||
logger.error(f"标准错误: {e.stderr.strip() if e.stderr else ''}")
|
||||
raise
|
||||
except FileNotFoundError:
|
||||
logger.error(f"命令 '{command_list[0]}' 未找到。请确保已安装相关工具。")
|
||||
@@ -52,33 +59,32 @@ class SystemInfoManager:
|
||||
"""
|
||||
使用 lsblk 获取块设备信息。
|
||||
返回一个字典列表,每个字典代表一个设备。
|
||||
自动适配不同系统的 lsblk 版本。
|
||||
"""
|
||||
cmd = [
|
||||
"lsblk", "-J", "-o",
|
||||
"NAME,FSTYPE,SIZE,MOUNTPOINT,RO,TYPE,UUID,PARTUUID,VENDOR,MODEL,SERIAL,MAJ:MIN,PKNAME,PATH"
|
||||
]
|
||||
try:
|
||||
# 使用兼容性模块获取适当的命令
|
||||
compat = get_system_compat()
|
||||
cmd, need_manual_parse = compat.get_lsblk_command()
|
||||
|
||||
stdout, _ = self._run_command(cmd)
|
||||
data = json.loads(stdout)
|
||||
devices = data.get('blockdevices', [])
|
||||
|
||||
def add_path_recursive(dev_list):
|
||||
devices = compat.parse_lsblk_output(stdout, need_manual_parse)
|
||||
|
||||
# 统一处理 path 字段
|
||||
def normalize_path_recursive(dev_list):
|
||||
for dev in dev_list:
|
||||
if 'PATH' not in dev and 'NAME' in dev:
|
||||
dev['PATH'] = f"/dev/{dev['NAME']}"
|
||||
# Rename PATH to path (lowercase) for consistency
|
||||
if 'path' not in dev and 'name' in dev:
|
||||
dev['path'] = f"/dev/{dev['name']}"
|
||||
if 'PATH' in dev:
|
||||
dev['path'] = dev.pop('PATH')
|
||||
if 'children' in dev:
|
||||
add_path_recursive(dev['children'])
|
||||
add_path_recursive(devices)
|
||||
normalize_path_recursive(dev['children'])
|
||||
|
||||
normalize_path_recursive(devices)
|
||||
return devices
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(f"获取块设备信息失败: {e.stderr.strip()}")
|
||||
return []
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"解析 lsblk JSON 输出失败: {e}")
|
||||
return []
|
||||
except Exception as e:
|
||||
logger.error(f"获取块设备信息失败 (未知错误): {e}")
|
||||
return []
|
||||
@@ -419,85 +425,50 @@ class SystemInfoManager:
|
||||
def get_lvm_info(self):
|
||||
"""
|
||||
获取 LVM 物理卷 (PVs)、卷组 (VGs) 和逻辑卷 (LVs) 的信息。
|
||||
自动适配不同系统的 LVM 版本。
|
||||
"""
|
||||
lvm_info = {'pvs': [], 'vgs': [], 'lvs': []}
|
||||
|
||||
# 使用兼容性模块获取适当的命令
|
||||
compat = get_system_compat()
|
||||
commands = compat.get_lvm_commands()
|
||||
|
||||
# Get PVs
|
||||
try:
|
||||
stdout, stderr = self._run_command(["pvs", "--reportformat", "json"])
|
||||
data = json.loads(stdout)
|
||||
if 'report' in data and data['report']:
|
||||
for pv_data in data['report'][0].get('pv', []):
|
||||
lvm_info['pvs'].append({
|
||||
'pv_name': pv_data.get('pv_name'),
|
||||
'vg_name': pv_data.get('vg_name'),
|
||||
'pv_uuid': pv_data.get('pv_uuid'),
|
||||
'pv_size': pv_data.get('pv_size'),
|
||||
'pv_free': pv_data.get('pv_free'),
|
||||
'pv_attr': pv_data.get('pv_attr'),
|
||||
'pv_fmt': pv_data.get('pv_fmt')
|
||||
})
|
||||
cmd, need_manual_parse = commands['pvs']
|
||||
stdout, stderr = self._run_command(cmd)
|
||||
lvm_info['pvs'] = compat.parse_pvs_output(stdout, need_manual_parse)
|
||||
except subprocess.CalledProcessError as e:
|
||||
if "No physical volume found" in e.stderr or "No physical volumes found" in e.stdout:
|
||||
logger.info("未找到任何LVM物理卷。")
|
||||
else:
|
||||
logger.error(f"获取LVM物理卷信息失败: {e.stderr.strip()}")
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"解析LVM物理卷JSON输出失败: {e}")
|
||||
except Exception as e:
|
||||
logger.error(f"获取LVM物理卷信息失败 (未知错误): {e}")
|
||||
|
||||
# Get VGs
|
||||
try:
|
||||
stdout, stderr = self._run_command(["vgs", "--reportformat", "json"])
|
||||
data = json.loads(stdout)
|
||||
if 'report' in data and data['report']:
|
||||
for vg_data in data['report'][0].get('vg', []):
|
||||
lvm_info['vgs'].append({
|
||||
'vg_name': vg_data.get('vg_name'),
|
||||
'vg_uuid': vg_data.get('vg_uuid'),
|
||||
'vg_size': vg_data.get('vg_size'),
|
||||
'vg_free': vg_data.get('vg_free'),
|
||||
'vg_attr': vg_data.get('vg_attr'),
|
||||
'pv_count': vg_data.get('pv_count'),
|
||||
'lv_count': vg_data.get('lv_count'),
|
||||
'vg_alloc_percent': vg_data.get('vg_alloc_percent'),
|
||||
'vg_fmt': vg_data.get('vg_fmt')
|
||||
})
|
||||
cmd, need_manual_parse = commands['vgs']
|
||||
stdout, stderr = self._run_command(cmd)
|
||||
lvm_info['vgs'] = compat.parse_vgs_output(stdout, need_manual_parse)
|
||||
except subprocess.CalledProcessError as e:
|
||||
if "No volume group found" in e.stderr or "No volume groups found" in e.stdout:
|
||||
logger.info("未找到任何LVM卷组。")
|
||||
else:
|
||||
logger.error(f"获取LVM卷组信息失败: {e.stderr.strip()}")
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"解析LVM卷组JSON输出失败: {e}")
|
||||
except Exception as e:
|
||||
logger.error(f"获取LVM卷组信息失败 (未知错误): {e}")
|
||||
|
||||
# Get LVs (MODIFIED: added -o lv_path)
|
||||
# Get LVs
|
||||
try:
|
||||
# 明确请求 lv_path,因为默认的 --reportformat json 不包含它
|
||||
stdout, stderr = self._run_command(["lvs", "-o", "lv_name,vg_name,lv_uuid,lv_size,lv_attr,origin,snap_percent,lv_path", "--reportformat", "json"])
|
||||
data = json.loads(stdout)
|
||||
if 'report' in data and data['report']:
|
||||
for lv_data in data['report'][0].get('lv', []):
|
||||
lvm_info['lvs'].append({
|
||||
'lv_name': lv_data.get('lv_name'),
|
||||
'vg_name': lv_data.get('vg_name'),
|
||||
'lv_uuid': lv_data.get('lv_uuid'),
|
||||
'lv_size': lv_data.get('lv_size'),
|
||||
'lv_attr': lv_data.get('lv_attr'),
|
||||
'origin': lv_data.get('origin'),
|
||||
'snap_percent': lv_data.get('snap_percent'),
|
||||
'lv_path': lv_data.get('lv_path') # 现在应该能正确获取到路径了
|
||||
})
|
||||
cmd, need_manual_parse = commands['lvs']
|
||||
stdout, stderr = self._run_command(cmd)
|
||||
lvm_info['lvs'] = compat.parse_lvs_output(stdout, need_manual_parse)
|
||||
except subprocess.CalledProcessError as e:
|
||||
if "No logical volume found" in e.stderr or "No logical volumes found" in e.stdout:
|
||||
logger.info("未找到任何LVM逻辑卷。")
|
||||
else:
|
||||
logger.error(f"获取LVM逻辑卷信息失败: {e.stderr.strip()}")
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"解析LVM逻辑卷JSON输出失败: {e}")
|
||||
except Exception as e:
|
||||
logger.error(f"获取LVM逻辑卷信息失败 (未知错误): {e}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user