This commit is contained in:
root
2026-02-10 02:54:13 +08:00
parent 4a59323398
commit 64bfd85368
22 changed files with 2572 additions and 422 deletions

292
dependency_checker.py Normal file
View File

@@ -0,0 +1,292 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
依赖检查模块
检查系统是否安装了必要的文件系统工具和其他依赖
"""
import subprocess
import logging
from typing import Dict, List, Tuple, Optional
logger = logging.getLogger(__name__)
class DependencyChecker:
"""依赖检查器"""
# 定义依赖项及其检查命令
DEPENDENCIES = {
# 文件系统工具
'ext4': {
'name': 'ext4 文件系统支持',
'commands': ['mkfs.ext4', 'fsck.ext4', 'resize2fs'],
'package': {
'centos': 'e2fsprogs',
'arch': 'e2fsprogs',
'ubuntu': 'e2fsprogs'
}
},
'xfs': {
'name': 'XFS 文件系统支持',
'commands': ['mkfs.xfs', 'xfs_repair', 'xfs_growfs'],
'package': {
'centos': 'xfsprogs',
'arch': 'xfsprogs',
'ubuntu': 'xfsprogs'
}
},
'ntfs': {
'name': 'NTFS 文件系统支持',
'commands': ['mkfs.ntfs', 'ntfsfix'],
'package': {
'centos': 'ntfs-3g',
'arch': 'ntfs-3g',
'ubuntu': 'ntfs-3g'
}
},
'fat32': {
'name': 'FAT32/VFAT 文件系统支持',
'commands': ['mkfs.vfat', 'fsck.vfat'],
'package': {
'centos': 'dosfstools',
'arch': 'dosfstools',
'ubuntu': 'dosfstools'
}
},
# 分区工具
'parted': {
'name': '分区工具',
'commands': ['parted', 'partprobe'],
'package': {
'centos': 'parted',
'arch': 'parted',
'ubuntu': 'parted'
}
},
# RAID 工具
'mdadm': {
'name': 'RAID 管理工具',
'commands': ['mdadm'],
'package': {
'centos': 'mdadm',
'arch': 'mdadm',
'ubuntu': 'mdadm'
}
},
# LVM 工具
'lvm': {
'name': 'LVM 逻辑卷管理',
'commands': ['pvcreate', 'vgcreate', 'lvcreate', 'pvs', 'vgs', 'lvs'],
'package': {
'centos': 'lvm2',
'arch': 'lvm2',
'ubuntu': 'lvm2'
}
},
# SMART 监控
'smartctl': {
'name': 'SMART 磁盘健康监控',
'commands': ['smartctl'],
'package': {
'centos': 'smartmontools',
'arch': 'smartmontools',
'ubuntu': 'smartmontools'
},
'optional': True
},
# 其他工具
'lsof': {
'name': '进程占用查询',
'commands': ['lsof', 'fuser'],
'package': {
'centos': 'lsof, psmisc',
'arch': 'lsof, psmisc',
'ubuntu': 'lsof, psmisc'
},
'optional': True
},
'sfdisk': {
'name': '分区表备份/恢复',
'commands': ['sfdisk'],
'package': {
'centos': 'util-linux',
'arch': 'util-linux',
'ubuntu': 'util-linux'
},
'optional': True
}
}
def __init__(self):
self._cache = {}
self._os_type = self._detect_os()
def _detect_os(self) -> str:
"""检测操作系统类型"""
try:
with open('/etc/os-release', 'r') as f:
content = f.read().lower()
if 'centos' in content or 'rhel' in content or 'fedora' in content:
return 'centos'
elif 'arch' in content:
return 'arch'
elif 'ubuntu' in content or 'debian' in content:
return 'ubuntu'
except Exception:
pass
return 'centos' # 默认
def _command_exists(self, cmd: str) -> bool:
"""检查命令是否存在"""
try:
result = subprocess.run(
['which', cmd],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False
)
return result.returncode == 0
except Exception:
return False
def check_dependency(self, key: str) -> Tuple[bool, List[str], List[str]]:
"""
检查单个依赖项
返回: (是否全部安装, 已安装的命令列表, 未安装的命令列表)
"""
if key in self._cache:
return self._cache[key]
dep = self.DEPENDENCIES.get(key)
if not dep:
return False, [], []
installed = []
missing = []
for cmd in dep['commands']:
if self._command_exists(cmd):
installed.append(cmd)
else:
missing.append(cmd)
result = (len(missing) == 0, installed, missing)
self._cache[key] = result
return result
def check_all(self) -> Dict[str, dict]:
"""
检查所有依赖项
返回: 依赖项状态字典
"""
results = {}
for key, dep in self.DEPENDENCIES.items():
is_complete, installed, missing = self.check_dependency(key)
results[key] = {
'name': dep['name'],
'is_complete': is_complete,
'installed': installed,
'missing': missing,
'package': dep['package'].get(self._os_type, dep['package']['centos']),
'optional': dep.get('optional', False),
'commands': dep['commands']
}
return results
def get_install_commands(self, results: Dict[str, dict] = None) -> Dict[str, List[str]]:
"""
获取安装命令
返回: {包名: [依赖项名称列表]}
"""
if results is None:
results = self.check_all()
packages = {}
for key, status in results.items():
if not status['is_complete'] and not status['optional']:
pkg = status['package']
if pkg not in packages:
packages[pkg] = []
packages[pkg].append(status['name'])
return packages
def get_summary(self) -> Dict[str, any]:
"""
获取依赖检查摘要
"""
results = self.check_all()
total = len(results)
complete = sum(1 for r in results.values() if r['is_complete'])
optional_missing = sum(1 for r in results.values() if not r['is_complete'] and r['optional'])
required_missing = sum(1 for r in results.values() if not r['is_complete'] and not r['optional'])
# 按类别分组
categories = {
'filesystem': ['ext4', 'xfs', 'ntfs', 'fat32'],
'partition': ['parted'],
'raid': ['mdadm'],
'lvm': ['lvm'],
'other': ['smartctl', 'lsof', 'sfdisk']
}
category_status = {}
for cat, keys in categories.items():
cat_results = {k: results[k] for k in keys if k in results}
category_status[cat] = cat_results
return {
'total': total,
'complete': complete,
'optional_missing': optional_missing,
'required_missing': required_missing,
'results': results,
'categories': category_status,
'install_commands': self.get_install_commands(results),
'os_type': self._os_type
}
# 全局实例
_checker = None
def get_dependency_checker() -> DependencyChecker:
"""获取全局依赖检查器实例"""
global _checker
if _checker is None:
_checker = DependencyChecker()
return _checker
if __name__ == '__main__':
# 测试
logging.basicConfig(level=logging.INFO)
checker = get_dependency_checker()
summary = checker.get_summary()
print("=" * 60)
print("依赖检查报告")
print("=" * 60)
print(f"操作系统: {summary['os_type']}")
print(f"总依赖项: {summary['total']}")
print(f"已安装: {summary['complete']}")
print(f"必需但缺失: {summary['required_missing']}")
print(f"可选缺失: {summary['optional_missing']}")
print()
for key, status in summary['results'].items():
icon = "" if status['is_complete'] else "" if status['optional'] else ""
print(f"{icon} {status['name']}")
if not status['is_complete']:
print(f" 缺失命令: {', '.join(status['missing'])}")
print(f" 安装包: {status['package']}")
print()
print("安装命令:")
if summary['install_commands']:
for pkg, names in summary['install_commands'].items():
print(f" {pkg} # {', '.join(names)}")
else:
print(" 所有必需依赖已安装")