From 2b03df0e3a09a6cb3a3a1a379a9fd750c3150254 Mon Sep 17 00:00:00 2001 From: Jino Jose Date: Tue, 30 Jun 2026 16:29:03 +0530 Subject: [PATCH] Fix portal branding icons and system info --- ansible/roles/cezen-backend/files/main.py | 32 ++++++- cezen-portal/index.html | 105 ++++++++++++++++------ cezen-portal/login.html | 30 ++++--- 3 files changed, 129 insertions(+), 38 deletions(-) diff --git a/ansible/roles/cezen-backend/files/main.py b/ansible/roles/cezen-backend/files/main.py index c768c1a..5a8b9c4 100644 --- a/ansible/roles/cezen-backend/files/main.py +++ b/ansible/roles/cezen-backend/files/main.py @@ -1621,14 +1621,40 @@ async def system_info(user: dict = Depends(current_user)): except Exception: v = "unknown" + try: + os_name = subprocess.check_output(["lsb_release", "-ds"], text=True, timeout=3).strip().strip('"') + except Exception: + os_name = subprocess.getoutput("uname -sr") or "unknown" + + ip_address = "" + try: + for _name, addrs in psutil.net_if_addrs().items(): + for addr in addrs: + if addr.address.count(".") == 3 and not addr.address.startswith("127."): + ip_address = addr.address + raise StopIteration + except StopIteration: + pass + except Exception: + ip_address = "" + + metrics = collect_metrics() + gpu_name = subprocess.getoutput( + "nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null | head -1" + ) or "N/A" + return { "hostname": hostname, + "ip_address": ip_address, + "os": os_name, "uptime": uptime, "python_version": subprocess.getoutput("python3 --version"), "ollama_version": v, - "gpu_name": subprocess.getoutput( - "nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null | head -1" - ) or "N/A", + "gpu_name": gpu_name, + "gpu_vram_gb": metrics.get("gpu_mem_total_gb"), + "ram_total_gb": metrics.get("ram_total_gb"), + "disk_total_gb": metrics.get("disk_total_gb"), + "cpu_cores": metrics.get("cpu_cores"), } @app.get("/api/system/feasibility") diff --git a/cezen-portal/index.html b/cezen-portal/index.html index f81c5ed..cabe9a8 100644 --- a/cezen-portal/index.html +++ b/cezen-portal/index.html @@ -5,7 +5,6 @@ Nexus One AI Portal - @@ -126,7 +125,7 @@
AI Tools
-
96 GB
+
GPU VRAM
@@ -163,27 +162,27 @@
Server Specifications
Hostname - ai-server + Detecting…
IP Address - 192.168.1.100 + Detecting…
GPU - NVIDIA RTX Pro 6000 (96 GB VRAM) + Detecting…
System RAM - 128 GB DDR5 + Detecting…
Storage - 4 TB NVMe SSD + Detecting…
OS - Ubuntu 22.04 LTS + Detecting…
Tier @@ -743,14 +742,11 @@ const set = (id, val) => { const el = document.getElementById(id); if (el) el.te // Realistic mock metrics for demo / offline use // Slight random drift so numbers feel live function mockMetrics() { - const base = { cpu: 23, gpu: 67, gtemp: 72, ram: 41, disk: 28 }; - const drift = v => Math.max(5, Math.min(95, v + Math.round((Math.random() - 0.5) * 6))); return { - cpu_pct: drift(base.cpu), gpu_pct: drift(base.gpu), - gpu_temp: drift(base.gtemp), ram_pct: drift(base.ram), - ram_used_gb: 52, ram_total_gb: 128, - disk_pct: base.disk, disk_used_gb: 1.1, disk_total_gb: 4.0, - uptime: '14 days, 6 hrs' + cpu_pct: null, gpu_pct: null, gpu_temp: null, ram_pct: null, + ram_used_gb: null, ram_total_gb: null, + disk_pct: null, disk_used_gb: null, disk_total_gb: null, + uptime: 'Unavailable' }; } @@ -774,30 +770,49 @@ function applyMetrics(d) { async function fetchMetrics() { try { - const d = await fetch('/api/metrics', { credentials: 'include' }).then(r => r.json()); + const d = await fetch('/api/metrics', { credentials: 'include' }).then(r => { + if (!r.ok) throw new Error('metrics unavailable'); + return r.json(); + }); applyMetrics(d); const notice = document.getElementById('metrics-notice'); if (notice) notice.style.display = 'none'; } catch { - // Backend offline — show realistic mock so dashboard looks live applyMetrics(mockMetrics()); const notice = document.getElementById('metrics-notice'); - if (notice) notice.style.display = 'none'; // hide warning in demo mode + if (notice) notice.style.display = 'flex'; } } async function fetchSystemInfo() { try { const [info, metrics] = await Promise.all([ - fetch('/api/system/info', { credentials: 'include' }).then(r => r.json()), - fetch('/api/metrics', { credentials: 'include' }).then(r => r.json()), + fetch('/api/system/info', { credentials: 'include' }).then(r => { + if (!r.ok) throw new Error('system info unavailable'); + return r.json(); + }), + fetch('/api/metrics', { credentials: 'include' }).then(r => { + if (!r.ok) throw new Error('metrics unavailable'); + return r.json(); + }), ]); set('spec-hostname', info.hostname || '—'); - if (info.gpu_name && info.gpu_name !== 'N/A') set('spec-gpu', info.gpu_name); - if (metrics.ram_total_gb) set('spec-ram', metrics.ram_total_gb + ' GB DDR5'); - if (metrics.disk_total_gb) set('spec-storage', metrics.disk_total_gb + ' TB NVMe SSD'); + set('spec-ip', info.ip_address || '—'); + set('spec-os', info.os || '—'); + const gpuName = info.gpu_name && info.gpu_name !== 'N/A' ? info.gpu_name : null; + const gpuVram = info.gpu_vram_gb || metrics.gpu_mem_total_gb; + set('spec-gpu', gpuName ? gpuName + (gpuVram ? ' (' + gpuVram + ' GB VRAM)' : '') : 'None detected'); + set('stat-vram', gpuVram ? gpuVram + ' GB' : '—'); + set('spec-ram', (info.ram_total_gb || metrics.ram_total_gb) ? (info.ram_total_gb || metrics.ram_total_gb) + ' GB' : '—'); + set('spec-storage', (info.disk_total_gb || metrics.disk_total_gb) ? (info.disk_total_gb || metrics.disk_total_gb) + ' GB' : '—'); } catch { - // API offline — keep the crisp hardcoded defaults (already accurate for Entry tier) + set('spec-hostname', 'Unavailable'); + set('spec-ip', 'Unavailable'); + set('spec-gpu', 'Unavailable'); + set('spec-ram', 'Unavailable'); + set('spec-storage', 'Unavailable'); + set('spec-os', 'Unavailable'); + set('stat-vram', '—'); } } @@ -807,7 +822,47 @@ setInterval(fetchMetrics, 30000); - +