update storage-overview.tsx

This commit is contained in:
MacRimi
2026-04-12 23:11:31 +02:00
parent 71950369e1
commit 7af4150e44
2 changed files with 48 additions and 27 deletions

View File

@@ -1904,7 +1904,7 @@ function SmartTestTab({ disk }: SmartTestTabProps) {
const [installing, setInstalling] = useState(false) const [installing, setInstalling] = useState(false)
// Check if required tools are installed for this disk type // Check if required tools are installed for this disk type
const isNvme = disk.name.startsWith('nvme') const isNvme = disk.name.includes('nvme')
const toolsAvailable = testStatus.tools_installed const toolsAvailable = testStatus.tools_installed
? (isNvme ? testStatus.tools_installed.nvme : testStatus.tools_installed.smartctl) ? (isNvme ? testStatus.tools_installed.nvme : testStatus.tools_installed.smartctl)
: true // Assume true until we get the status : true // Assume true until we get the status

View File

@@ -6355,8 +6355,8 @@ def api_proxmox_storage():
SMART_DIR = '/usr/local/share/proxmenux/smart' SMART_DIR = '/usr/local/share/proxmenux/smart'
def _is_nvme(disk_name): def _is_nvme(disk_name):
"""Check if disk is NVMe.""" """Check if disk is NVMe (supports names like nvme0n1, nvme0n1p1)."""
return disk_name.startswith('nvme') return 'nvme' in disk_name
def _get_smart_json_path(disk_name): def _get_smart_json_path(disk_name):
"""Get path to SMART JSON file for a disk.""" """Get path to SMART JSON file for a disk."""
@@ -6497,31 +6497,39 @@ def api_smart_status(disk_name):
# Get current SMART status # Get current SMART status
if is_nvme: if is_nvme:
# NVMe: Check for running test # NVMe: Check for running test
proc = subprocess.run( try:
['nvme', 'self-test-log', device], proc = subprocess.run(
capture_output=True, text=True, timeout=10 ['nvme', 'self-test-log', device],
) capture_output=True, text=True, timeout=10
if 'in progress' in proc.stdout.lower(): )
result['status'] = 'running' if proc.returncode == 0 and 'in progress' in proc.stdout.lower():
result['test_type'] = 'nvme' result['status'] = 'running'
result['test_type'] = 'nvme'
except subprocess.TimeoutExpired:
pass
# Get smart-log data # Get smart-log data
proc = subprocess.run( try:
['nvme', 'smart-log', device], proc = subprocess.run(
capture_output=True, text=True, timeout=10 ['nvme', 'smart-log', device],
) capture_output=True, text=True, timeout=10
if proc.returncode == 0: )
lines = proc.stdout.strip().split('\n') if proc.returncode == 0:
smart_data = {} lines = proc.stdout.strip().split('\n')
for line in lines: smart_data = {}
if ':' in line: for line in lines:
key, value = line.split(':', 1) if ':' in line:
smart_data[key.strip().lower().replace(' ', '_')] = value.strip() key, value = line.split(':', 1)
result['smart_data'] = smart_data smart_data[key.strip().lower().replace(' ', '_')] = value.strip()
result['smart_data'] = smart_data
# Check health
crit_warn = smart_data.get('critical_warning', '0') # Check health
result['smart_status'] = 'passed' if crit_warn == '0' else 'warning' crit_warn = smart_data.get('critical_warning', '0')
result['smart_status'] = 'passed' if crit_warn == '0' else 'warning'
else:
result['nvme_error'] = proc.stderr.strip() or 'Failed to read SMART data'
except subprocess.TimeoutExpired:
result['nvme_error'] = 'Command timeout'
else: else:
# SATA/SAS: Check for running test # SATA/SAS: Check for running test
proc = subprocess.run( proc = subprocess.run(
@@ -6638,13 +6646,26 @@ def api_smart_run_test(disk_name):
# NVMe: self-test-code 1=short, 2=long # NVMe: self-test-code 1=short, 2=long
code = 1 if test_type == 'short' else 2 code = 1 if test_type == 'short' else 2
# First check if device supports self-test
check_proc = subprocess.run(
['nvme', 'id-ctrl', device],
capture_output=True, text=True, timeout=10
)
if check_proc.returncode != 0:
return jsonify({'error': f'Cannot access NVMe device: {check_proc.stderr.strip() or "Device not responding"}'}), 500
proc = subprocess.run( proc = subprocess.run(
['nvme', 'device-self-test', device, f'--self-test-code={code}'], ['nvme', 'device-self-test', device, f'--self-test-code={code}'],
capture_output=True, text=True, timeout=30 capture_output=True, text=True, timeout=30
) )
if proc.returncode != 0: if proc.returncode != 0:
return jsonify({'error': f'Failed to start test: {proc.stderr}'}), 500 error_msg = proc.stderr.strip() or proc.stdout.strip() or 'Unknown error'
# Some NVMe devices don't support self-test
if 'not support' in error_msg.lower() or 'invalid' in error_msg.lower():
return jsonify({'error': f'This NVMe device does not support self-test: {error_msg}'}), 400
return jsonify({'error': f'Failed to start test: {error_msg}'}), 500
# Start background monitor to save JSON when test completes # Start background monitor to save JSON when test completes
sleep_interval = 10 if test_type == 'short' else 60 sleep_interval = 10 if test_type == 'short' else 60