Update AppImage

This commit is contained in:
MacRimi
2025-10-15 00:03:56 +02:00
parent e4864d3871
commit 2ce87cdac0
2 changed files with 30 additions and 86 deletions

View File

@@ -72,9 +72,6 @@ interface ProxmoxStorageData {
}
const formatStorage = (sizeInGB: number): string => {
if (sizeInGB <= 0) {
return "0 GB"
}
if (sizeInGB < 1) {
// Less than 1 GB, show in MB
return `${(sizeInGB * 1024).toFixed(1)} MB`
@@ -358,9 +355,7 @@ export function StorageOverview() {
: 0
const usagePercent =
storageData.total > 0 && totalProxmoxUsed > 0
? ((totalProxmoxUsed / (storageData.total * 1024)) * 100).toFixed(2)
: "0.00"
storageData.total > 0 ? ((totalProxmoxUsed / (storageData.total * 1024)) * 100).toFixed(2) : "0.00"
return (
<div className="space-y-6">

View File

@@ -529,9 +529,8 @@ def serve_images(filename):
# Moved helper functions for system info up
# def get_system_info(): ... (moved up)
# get_storage_info() function is OPTIMIZED to remove SMART data
def get_storage_info():
"""Get storage and disk information - OPTIMIZED: Basic info only, no SMART data"""
"""Get storage and disk information"""
try:
storage_data = {
'total': 0,
@@ -568,9 +567,10 @@ def get_storage_info():
total_disk_size_bytes += disk_size_bytes
print(f"[v0] Getting basic info for {disk_name}...")
basic_info = get_basic_disk_info(disk_name)
print(f"[v0] Basic info for {disk_name}: {basic_info}")
# Get SMART data for this disk
print(f"[v0] Getting SMART data for {disk_name}...")
smart_data = get_smart_data(disk_name)
print(f"[v0] SMART data for {disk_name}: {smart_data}")
disk_size_kb = disk_size_bytes / 1024
@@ -581,17 +581,29 @@ def get_storage_info():
physical_disks[disk_name] = {
'name': disk_name,
'size': disk_size_kb,
'size_formatted': size_str,
'size': disk_size_kb, # In KB for formatMemory() in Storage Summary
'size_formatted': size_str, # Added formatted size string for Storage section
'size_bytes': disk_size_bytes,
'temperature': basic_info.get('temperature', 0),
'health': basic_info.get('health', 'unknown'),
'model': basic_info.get('model', 'Unknown'),
'rotation_rate': basic_info.get('rotation_rate', 0),
'temperature': smart_data.get('temperature', 0),
'health': smart_data.get('health', 'unknown'),
'power_on_hours': smart_data.get('power_on_hours', 0),
'smart_status': smart_data.get('smart_status', 'unknown'),
'model': smart_data.get('model', 'Unknown'),
'serial': smart_data.get('serial', 'Unknown'),
'reallocated_sectors': smart_data.get('reallocated_sectors', 0),
'pending_sectors': smart_data.get('pending_sectors', 0),
'crc_errors': smart_data.get('crc_errors', 0),
'rotation_rate': smart_data.get('rotation_rate', 0), # Added
'power_cycles': smart_data.get('power_cycles', 0), # Added
'percentage_used': smart_data.get('percentage_used'), # Added
'media_wearout_indicator': smart_data.get('media_wearout_indicator'), # Added
'wear_leveling_count': smart_data.get('wear_leveling_count'), # Added
'total_lbas_written': smart_data.get('total_lbas_written'), # Added
'ssd_life_left': smart_data.get('ssd_life_left') # Added
}
storage_data['disk_count'] += 1
health = basic_info.get('health', 'unknown').lower()
health = smart_data.get('health', 'unknown').lower()
if health == 'healthy':
storage_data['healthy_disks'] += 1
elif health == 'warning':
@@ -692,57 +704,6 @@ def get_storage_info():
'critical_disks': 0
}
# New function to get basic disk info quickly
def get_basic_disk_info(disk_name):
"""Get basic disk info quickly without full SMART scan - OPTIMIZED"""
basic_info = {
'temperature': 0,
'health': 'unknown',
'model': 'Unknown',
'rotation_rate': 0,
}
try:
# Only get basic info (-i) and health (-H), skip full attributes scan
cmd = ['smartctl', '-i', '-H', '-j', f'/dev/{disk_name}']
result = subprocess.run(cmd, capture_output=True, text=True, timeout=5)
if result.returncode in [0, 4]: # 0 = success, 4 = some SMART values exceeded threshold
try:
data = json.loads(result.stdout)
# Extract model
if 'model_name' in data:
basic_info['model'] = data['model_name']
elif 'model_family' in data:
basic_info['model'] = data['model_family']
# Extract rotation rate
if 'rotation_rate' in data:
basic_info['rotation_rate'] = data['rotation_rate']
# Extract SMART status
if 'smart_status' in data and 'passed' in data['smart_status']:
basic_info['health'] = 'healthy' if data['smart_status']['passed'] else 'critical'
# Extract temperature (quick check)
if 'temperature' in data and 'current' in data['temperature']:
basic_info['temperature'] = data['temperature']['current']
elif 'nvme_smart_health_information_log' in data:
nvme_data = data['nvme_smart_health_information_log']
if 'temperature' in nvme_data:
basic_info['temperature'] = nvme_data['temperature']
except json.JSONDecodeError:
pass
except Exception as e:
print(f"[v0] Error getting basic disk info for {disk_name}: {e}")
return basic_info
def get_smart_data(disk_name):
"""Get SMART data for a specific disk - Enhanced with multiple device type attempts"""
smart_data = {
@@ -2057,7 +2018,7 @@ def get_detailed_gpu_info(gpu):
if 'clients' in json_data:
client_count = len(json_data['clients'])
print(f"[v0] *** FOUND CLIENTS SECTION with {client_count} client(s) ***", flush=True)
for client_id, client_data in json_data['clients']:
for client_id, client_data in json_data['clients'].items():
client_name = client_data.get('name', 'Unknown')
client_pid = client_data.get('pid', 'Unknown')
print(f"[v0] - Client: {client_name} (PID: {client_pid})", flush=True)
@@ -2563,7 +2524,7 @@ def get_detailed_gpu_info(gpu):
mem_clock = clocks['GFX_MCLK']
if 'value' in mem_clock:
detailed_info['clock_memory'] = f"{mem_clock['value']} MHz"
print(f"[v0] Memory Clock: {detailed_info['clock_memory']}", flush=True)
print(f"[v0] Memory Clock: {detailed_info['clock_memory']} MHz", flush=True)
data_retrieved = True
# Parse GPU activity (gpu_activity.GFX)
@@ -3612,20 +3573,9 @@ def api_system():
@app.route('/api/storage', methods=['GET'])
def api_storage():
"""Get storage information - OPTIMIZED: Basic info only"""
"""Get storage information"""
return jsonify(get_storage_info())
@app.route('/api/storage/disk/<disk_name>/details', methods=['GET'])
def api_disk_details(disk_name):
"""Get detailed SMART data for a specific disk - loaded on demand"""
try:
print(f"[v0] Getting detailed SMART data for {disk_name}...")
smart_data = get_smart_data(disk_name)
return jsonify(smart_data)
except Exception as e:
print(f"[v0] Error getting disk details: {e}")
return jsonify({'error': str(e)}), 500
@app.route('/api/proxmox-storage', methods=['GET'])
def api_proxmox_storage():
"""Get Proxmox storage information"""
@@ -4511,7 +4461,6 @@ def api_info():
'/api/system',
'/api/system-info',
'/api/storage',
'/api/storage/disk/<disk_name>/details', # Added endpoint for detailed disk SMART data
'/api/proxmox-storage',
'/api/network',
'/api/vms',
@@ -4785,6 +4734,6 @@ if __name__ == '__main__':
cli.show_server_banner = lambda *x: None
# Print only essential information
print("API endpoints available at: /api/system, /api/system-info, /api/storage, /api/storage/disk/<disk_name>/details, /api/proxmox-storage, /api/network, /api/vms, /api/logs, /api/health, /api/hardware, /api/gpu/<slot>/realtime, /api/prometheus")
print("API endpoints available at: /api/system, /api/system-info, /api/storage, /api/proxmox-storage, /api/network, /api/vms, /api/logs, /api/health, /api/hardware, /api/prometheus")
app.run(host='0.0.0.0', port=8008, debug=False)