mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-04-30 11:26:23 +00:00
Update flask_server.py
This commit is contained in:
@@ -6496,37 +6496,56 @@ 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 and get self-test log
|
# NVMe: Check for running test and get self-test log using JSON format
|
||||||
try:
|
try:
|
||||||
proc = subprocess.run(
|
proc = subprocess.run(
|
||||||
['nvme', 'self-test-log', device],
|
['nvme', 'self-test-log', device, '-o', 'json'],
|
||||||
capture_output=True, text=True, timeout=10
|
capture_output=True, text=True, timeout=10
|
||||||
)
|
)
|
||||||
if proc.returncode == 0:
|
if proc.returncode == 0:
|
||||||
output = proc.stdout
|
try:
|
||||||
# Check if test is in progress
|
selftest_data = json.loads(proc.stdout)
|
||||||
if 'in progress' in output.lower():
|
# Check if test is in progress
|
||||||
result['status'] = 'running'
|
# "Current Device Self-Test Operation": 0=none, 1=short, 2=extended
|
||||||
result['test_type'] = 'nvme'
|
current_op = selftest_data.get('Current Device Self-Test Operation', 0)
|
||||||
# Try to extract progress
|
if current_op > 0:
|
||||||
match = re.search(r'(\d+)%', output)
|
result['status'] = 'running'
|
||||||
if match:
|
result['test_type'] = 'short' if current_op == 1 else 'long'
|
||||||
result['progress'] = int(match.group(1))
|
# Get completion percentage
|
||||||
|
completion = selftest_data.get('Current Device Self-Test Completion', 0)
|
||||||
# Parse last test result from self-test log
|
result['progress'] = completion
|
||||||
# Format varies but typically shows test entries
|
|
||||||
lines = output.split('\n')
|
# Parse last test result from self-test log
|
||||||
for line in lines:
|
valid_reports = selftest_data.get('List of Valid Reports', [])
|
||||||
line_lower = line.lower()
|
if valid_reports:
|
||||||
if 'completed' in line_lower or 'passed' in line_lower or 'without error' in line_lower:
|
# Find most recent completed test (result != 15 which means not run)
|
||||||
test_type = 'short' if 'short' in line_lower else 'long' if 'extended' in line_lower or 'long' in line_lower else 'unknown'
|
for report in valid_reports:
|
||||||
test_status = 'passed' if 'without error' in line_lower or 'passed' in line_lower or 'success' in line_lower else 'failed'
|
test_result = report.get('Self test result', 15)
|
||||||
result['last_test'] = {
|
if test_result != 15: # 15 = entry not used
|
||||||
'type': test_type,
|
test_code = report.get('Self test code', 0)
|
||||||
'status': test_status,
|
test_type = 'short' if test_code == 1 else 'long' if test_code == 2 else 'unknown'
|
||||||
'timestamp': 'Completed without error'
|
# 0 = completed without error, other values = error
|
||||||
}
|
test_status = 'passed' if test_result == 0 else 'failed'
|
||||||
break
|
result['last_test'] = {
|
||||||
|
'type': test_type,
|
||||||
|
'status': test_status,
|
||||||
|
'timestamp': f'POH: {report.get("Power on hours", "N/A")}'
|
||||||
|
}
|
||||||
|
break
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
# Fallback to text parsing if JSON fails
|
||||||
|
output = proc.stdout
|
||||||
|
# Check Current operation field
|
||||||
|
op_match = re.search(r'Current operation\s*:\s*(0x[0-9a-fA-F]+|\d+)', output)
|
||||||
|
if op_match:
|
||||||
|
op_val = int(op_match.group(1), 0)
|
||||||
|
if op_val > 0:
|
||||||
|
result['status'] = 'running'
|
||||||
|
result['test_type'] = 'short' if op_val == 1 else 'long'
|
||||||
|
# Try to extract progress percentage
|
||||||
|
prog_match = re.search(r'Current Completion\s*:\s*(\d+)%', output)
|
||||||
|
if prog_match:
|
||||||
|
result['progress'] = int(prog_match.group(1))
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
pass
|
pass
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -6777,12 +6796,14 @@ def api_smart_run_test(disk_name):
|
|||||||
return jsonify({'error': f'Failed to start test: {error_msg}'}), 500
|
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
|
||||||
# Use 'nvme self-test-log' to check test status (not device-self-test)
|
# Check 'Current Device Self-Test Operation' field - if > 0, test is running
|
||||||
sleep_interval = 10 if test_type == 'short' else 60
|
sleep_interval = 10 if test_type == 'short' else 60
|
||||||
subprocess.Popen(
|
subprocess.Popen(
|
||||||
f'''
|
f'''
|
||||||
sleep 5
|
sleep 5
|
||||||
while nvme self-test-log {device} 2>/dev/null | grep -qi 'in progress\\|operation in progress'; do
|
while true; do
|
||||||
|
op=$(nvme self-test-log {device} -o json 2>/dev/null | grep -o '"Current Device Self-Test Operation":[0-9]*' | grep -o '[0-9]*$')
|
||||||
|
[ -z "$op" ] || [ "$op" -eq 0 ] && break
|
||||||
sleep {sleep_interval}
|
sleep {sleep_interval}
|
||||||
done
|
done
|
||||||
nvme smart-log -o json {device} > {json_path} 2>/dev/null
|
nvme smart-log -o json {device} > {json_path} 2>/dev/null
|
||||||
|
|||||||
Reference in New Issue
Block a user