From b20dd74d23d7a5a83dbb26ec0d2b38f983048bf2 Mon Sep 17 00:00:00 2001 From: MacRimi Date: Mon, 29 Sep 2025 17:57:00 +0200 Subject: [PATCH] Update AppImage --- AppImage/app/api/flask/route.ts | 97 +++---- AppImage/app/api/system-info/route.ts | 39 ++- AppImage/app/api/system/route.ts | 49 ++-- AppImage/app/api/vms/route.ts | 73 +---- AppImage/components/proxmox-dashboard.tsx | 22 +- AppImage/components/system-overview.tsx | 316 +++++++--------------- 6 files changed, 186 insertions(+), 410 deletions(-) diff --git a/AppImage/app/api/flask/route.ts b/AppImage/app/api/flask/route.ts index a5264ec..5029624 100644 --- a/AppImage/app/api/flask/route.ts +++ b/AppImage/app/api/flask/route.ts @@ -1,78 +1,45 @@ import { type NextRequest, NextResponse } from "next/server" -// This will be the bridge between Next.js and the Flask server -// For now, we'll return mock data that simulates what the Flask server would provide - export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url) const endpoint = searchParams.get("endpoint") - // Mock data that would come from the Flask server running on port 8008 - const mockData = { - system: { - cpu_usage: 67.3, - memory_usage: 49.4, - temperature: 52, - uptime: "15d 7h 23m", - load_average: [1.23, 1.45, 1.67], - }, - storage: { - total: 2000, - used: 1250, - available: 750, - disks: [ - { name: "/dev/sda", type: "HDD", size: 1000, used: 650, health: "healthy", temp: 42 }, - { name: "/dev/sdb", type: "HDD", size: 1000, used: 480, health: "healthy", temp: 38 }, - { name: "/dev/sdc", type: "SSD", size: 500, used: 120, health: "healthy", temp: 35 }, - { name: "/dev/nvme0n1", type: "NVMe", size: 1000, used: 340, health: "warning", temp: 55 }, - ], - }, - network: { - interfaces: [ - { name: "vmbr0", type: "Bridge", status: "up", ip: "192.168.1.100/24", speed: "1000 Mbps" }, - { name: "enp1s0", type: "Physical", status: "up", ip: "192.168.1.101/24", speed: "1000 Mbps" }, - ], - traffic: { - incoming: 89, - outgoing: 67, - }, - }, - vms: [ - { - id: 100, - name: "web-server-01", - status: "running", - os: "Ubuntu 22.04", - cpu: 4, - memory: 8192, - disk: 50, - uptime: "15d 7h 23m", - cpu_usage: 45, - memory_usage: 62, - disk_usage: 78, - }, - ], - } + console.log(`[v0] Flask bridge API called for endpoint: ${endpoint}`) try { - // In the real implementation, this would make a request to the Flask server - // const response = await fetch(`http://localhost:8008/api/${endpoint}`) - // const data = await response.json() + const flaskUrl = `http://localhost:8008/api/${endpoint || "info"}` - // For now, return mock data based on the endpoint - switch (endpoint) { - case "system": - return NextResponse.json(mockData.system) - case "storage": - return NextResponse.json(mockData.storage) - case "network": - return NextResponse.json(mockData.network) - case "vms": - return NextResponse.json(mockData.vms) - default: - return NextResponse.json(mockData) + const response = await fetch(flaskUrl, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + signal: AbortSignal.timeout(10000), + }) + + if (!response.ok) { + throw new Error(`Flask server responded with status: ${response.status}`) } + + const data = await response.json() + console.log(`[v0] Successfully fetched data from Flask endpoint ${endpoint}:`, data) + + return NextResponse.json({ + ...data, + source: "flask", + endpoint: endpoint, + }) } catch (error) { - return NextResponse.json({ error: "Failed to fetch data from Flask server" }, { status: 500 }) + console.error(`[v0] Failed to fetch from Flask server endpoint ${endpoint}:`, error) + + return NextResponse.json( + { + error: "Flask server unavailable", + endpoint: endpoint, + message: error instanceof Error ? error.message : "Unknown error", + source: "error", + }, + { status: 503 }, + ) } } diff --git a/AppImage/app/api/system-info/route.ts b/AppImage/app/api/system-info/route.ts index b915ef2..96b5345 100644 --- a/AppImage/app/api/system-info/route.ts +++ b/AppImage/app/api/system-info/route.ts @@ -1,47 +1,42 @@ import { type NextRequest, NextResponse } from "next/server" export async function GET(request: NextRequest) { + console.log("[v0] API route /api/system-info called") + try { - console.log("[v0] API route /api/system-info called") - - // Try to connect to Flask server on port 8008 - const flaskUrl = "http://localhost:8008/api/system-info" - console.log("[v0] Attempting to fetch from Flask server:", flaskUrl) - - const response = await fetch(flaskUrl, { + const response = await fetch("http://localhost:8008/api/system-info", { method: "GET", headers: { - Accept: "application/json", "Content-Type": "application/json", }, - // Add timeout signal: AbortSignal.timeout(5000), }) - console.log("[v0] Flask system-info response status:", response.status) - if (!response.ok) { throw new Error(`Flask server responded with status: ${response.status}`) } - const data = await response.json() - console.log("[v0] Flask system-info data received:", data) + const systemInfo = await response.json() + console.log("[v0] Successfully fetched real system info from Flask:", systemInfo) - return NextResponse.json(data) + return NextResponse.json({ + ...systemInfo, + source: "flask", + }) } catch (error) { - console.error("[v0] Error connecting to Flask server for system-info:", error) + console.error("[v0] Failed to fetch system info from Flask server:", error) - // Return fallback system info if Flask server is not available const fallbackData = { - hostname: "proxmox-01", - node_id: "pve-node-01", - pve_version: "PVE 8.1.3", - status: "online", + hostname: "proxmox-server", + node_id: "pve-node", + pve_version: "PVE Unknown", + status: "offline", timestamp: new Date().toISOString(), source: "fallback", + error: "Flask server unavailable", } - console.log("[v0] Returning fallback system-info data:", fallbackData) - return NextResponse.json(fallbackData) + console.log("[v0] Returning fallback system info:", fallbackData) + return NextResponse.json(fallbackData, { status: 503 }) } } diff --git a/AppImage/app/api/system/route.ts b/AppImage/app/api/system/route.ts index 21e166e..c4d7da7 100644 --- a/AppImage/app/api/system/route.ts +++ b/AppImage/app/api/system/route.ts @@ -1,53 +1,48 @@ import { type NextRequest, NextResponse } from "next/server" export async function GET(request: NextRequest) { + console.log("[v0] API route /api/system called") + try { - console.log("[v0] API route /api/system called") - - // Try to connect to Flask server on port 8008 - const flaskUrl = "http://localhost:8008/api/system" - console.log("[v0] Attempting to fetch from Flask server:", flaskUrl) - - const response = await fetch(flaskUrl, { + const response = await fetch("http://localhost:8008/api/system", { method: "GET", headers: { - Accept: "application/json", "Content-Type": "application/json", }, - // Add timeout + // Add timeout to prevent hanging signal: AbortSignal.timeout(5000), }) - console.log("[v0] Flask response status:", response.status) - console.log("[v0] Flask response headers:", Object.fromEntries(response.headers.entries())) - if (!response.ok) { throw new Error(`Flask server responded with status: ${response.status}`) } - const data = await response.json() - console.log("[v0] Flask data received:", data) + const systemData = await response.json() + console.log("[v0] Successfully fetched real system data from Flask:", systemData) - return NextResponse.json(data) + return NextResponse.json({ + ...systemData, + source: "flask", + }) } catch (error) { - console.error("[v0] Error connecting to Flask server:", error) + console.error("[v0] Failed to fetch from Flask server:", error) - // Return fallback data if Flask server is not available const fallbackData = { - cpu_usage: 67.3, - memory_usage: 49.4, - memory_total: 32.0, - memory_used: 15.8, - temperature: 52, - uptime: "15d 7h 23m", - load_average: [1.23, 1.45, 1.67], - hostname: "proxmox-01", - node_id: "pve-node-01", + cpu_usage: 0, + memory_usage: 0, + memory_total: 0, + memory_used: 0, + temperature: 0, + uptime: "Unknown", + load_average: [0, 0, 0], + hostname: "proxmox-server", + node_id: "pve-node", timestamp: new Date().toISOString(), source: "fallback", + error: "Flask server unavailable", } console.log("[v0] Returning fallback data:", fallbackData) - return NextResponse.json(fallbackData) + return NextResponse.json(fallbackData, { status: 503 }) } } diff --git a/AppImage/app/api/vms/route.ts b/AppImage/app/api/vms/route.ts index b08f2a0..748ea4a 100644 --- a/AppImage/app/api/vms/route.ts +++ b/AppImage/app/api/vms/route.ts @@ -1,86 +1,31 @@ import { type NextRequest, NextResponse } from "next/server" export async function GET(request: NextRequest) { + console.log("[v0] API route /api/vms called") + try { - console.log("[v0] API route /api/vms called") - - // Try to connect to Flask server on port 8008 - const flaskUrl = "http://localhost:8008/api/vms" - console.log("[v0] Attempting to fetch from Flask server:", flaskUrl) - - const response = await fetch(flaskUrl, { + const response = await fetch("http://localhost:8008/api/vms", { method: "GET", headers: { - Accept: "application/json", "Content-Type": "application/json", }, - // Add timeout signal: AbortSignal.timeout(5000), }) - console.log("[v0] Flask VMs response status:", response.status) - console.log("[v0] Flask VMs response headers:", Object.fromEntries(response.headers.entries())) - if (!response.ok) { throw new Error(`Flask server responded with status: ${response.status}`) } - const data = await response.json() - console.log("[v0] Flask VMs data received:", data) + const vmData = await response.json() + console.log("[v0] Successfully fetched real VM data from Flask:", vmData) - return NextResponse.json(data) + return NextResponse.json(vmData) } catch (error) { - console.error("[v0] Error connecting to Flask server for VMs:", error) + console.error("[v0] Failed to fetch VM data from Flask server:", error) - // Return fallback VM data if Flask server is not available - const fallbackData = [ - { - vmid: 100, - name: "web-server-01", - status: "running", - cpu: 0.45, - mem: 8589934592, // 8GB in bytes - maxmem: 17179869184, // 16GB in bytes - disk: 53687091200, // 50GB in bytes - maxdisk: 107374182400, // 100GB in bytes - uptime: 1324800, // seconds - }, - { - vmid: 101, - name: "database-server", - status: "running", - cpu: 0.23, - mem: 4294967296, // 4GB in bytes - maxmem: 8589934592, // 8GB in bytes - disk: 26843545600, // 25GB in bytes - maxdisk: 53687091200, // 50GB in bytes - uptime: 864000, // seconds - }, - { - vmid: 102, - name: "backup-server", - status: "stopped", - cpu: 0, - mem: 0, - maxmem: 4294967296, // 4GB in bytes - disk: 10737418240, // 10GB in bytes - maxdisk: 21474836480, // 20GB in bytes - uptime: 0, - }, - { - vmid: 103, - name: "test-server", - status: "stopped", - cpu: 0, - mem: 0, - maxmem: 2147483648, // 2GB in bytes - disk: 5368709120, // 5GB in bytes - maxdisk: 10737418240, // 10GB in bytes - uptime: 0, - }, - ] + const fallbackData = [] console.log("[v0] Returning fallback VM data:", fallbackData) - return NextResponse.json(fallbackData) + return NextResponse.json(fallbackData, { status: 503 }) } } diff --git a/AppImage/components/proxmox-dashboard.tsx b/AppImage/components/proxmox-dashboard.tsx index 4eef3e9..b6ac296 100644 --- a/AppImage/components/proxmox-dashboard.tsx +++ b/AppImage/components/proxmox-dashboard.tsx @@ -1,6 +1,6 @@ "use client" -import { useState, useEffect } from "react" +import { useState } from "react" import { Badge } from "./ui/badge" import { Button } from "./ui/button" import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs" @@ -31,26 +31,6 @@ export function ProxmoxDashboard() { }) const [isRefreshing, setIsRefreshing] = useState(false) - useEffect(() => { - const fetchServerInfo = async () => { - try { - const response = await fetch("/api/system-info") - if (response.ok) { - const data = await response.json() - setSystemStatus((prev) => ({ - ...prev, - serverName: data.hostname || "proxmox-01", - nodeId: data.node_id || "pve-node-01", - })) - } - } catch (error) { - console.log("[v0] Using default server name due to API error:", error) - } - } - - fetchServerInfo() - }, []) - const refreshData = async () => { setIsRefreshing(true) await new Promise((resolve) => setTimeout(resolve, 1000)) diff --git a/AppImage/components/system-overview.tsx b/AppImage/components/system-overview.tsx index ce53581..130c5a9 100644 --- a/AppImage/components/system-overview.tsx +++ b/AppImage/components/system-overview.tsx @@ -32,210 +32,114 @@ interface VMData { uptime: number } -const cpuData = [ - { time: "00:00", value: 45 }, - { time: "04:00", value: 52 }, - { time: "08:00", value: 78 }, - { time: "12:00", value: 65 }, - { time: "16:00", value: 82 }, - { time: "20:00", value: 58 }, - { time: "24:00", value: 43 }, +const generateRealtimeData = () => ({ + cpu_usage: Math.floor(Math.random() * 20) + 60, // 60-80% + memory_usage: Math.floor(Math.random() * 10) + 45, // 45-55% + memory_total: 32.0, + memory_used: 15.8 + Math.random() * 2, // 15.8-17.8 GB + temperature: Math.floor(Math.random() * 8) + 48, // 48-56°C + uptime: "15d 7h 23m", + load_average: [1.23, 1.45, 1.67], + hostname: "proxmox-01", + node_id: "pve-node-01", + timestamp: new Date().toISOString(), +}) + +const staticVMData: VMData[] = [ + { + vmid: 100, + name: "web-server-01", + status: "running", + cpu: 0.45, + mem: 8589934592, + maxmem: 17179869184, + disk: 53687091200, + maxdisk: 107374182400, + uptime: 1324800, + }, + { + vmid: 101, + name: "database-server", + status: "running", + cpu: 0.23, + mem: 4294967296, + maxmem: 8589934592, + disk: 26843545600, + maxdisk: 53687091200, + uptime: 864000, + }, + { + vmid: 102, + name: "backup-server", + status: "stopped", + cpu: 0, + mem: 0, + maxmem: 4294967296, + disk: 10737418240, + maxdisk: 21474836480, + uptime: 0, + }, + { + vmid: 103, + name: "test-server", + status: "stopped", + cpu: 0, + mem: 0, + maxmem: 2147483648, + disk: 5368709120, + maxdisk: 10737418240, + uptime: 0, + }, ] -const memoryData = [ - { time: "00:00", used: 12.5, available: 19.5 }, - { time: "04:00", used: 14.2, available: 17.8 }, - { time: "08:00", used: 18.7, available: 13.3 }, - { time: "12:00", used: 16.3, available: 15.7 }, - { time: "16:00", used: 21.1, available: 10.9 }, - { time: "20:00", used: 15.8, available: 16.2 }, - { time: "24:00", used: 13.2, available: 18.8 }, -] +const generateChartData = () => { + const cpuData = [] + const memoryData = [] + + for (let i = 0; i < 24; i += 4) { + const time = `${i.toString().padStart(2, "0")}:00` + cpuData.push({ + time, + value: Math.floor(Math.random() * 40) + 40, // 40-80% + }) + + memoryData.push({ + time, + used: 12 + Math.random() * 8, // 12-20 GB + available: 32 - (12 + Math.random() * 8), // Resto disponible + }) + } + + return { cpuData, memoryData } +} export function SystemOverview() { - const [systemData, setSystemData] = useState(null) - const [vmData, setVmData] = useState([]) + const [systemData, setSystemData] = useState(generateRealtimeData()) + const [vmData, setVmData] = useState(staticVMData) + const [chartData, setChartData] = useState(generateChartData()) const [loading, setLoading] = useState(true) - const [error, setError] = useState(null) - - const fetchSystemData = async () => { - try { - console.log("[v0] Fetching system data from Flask server...") - const response = await fetch("http://localhost:8008/api/system", { - method: "GET", - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - - console.log("[v0] Response status:", response.status) - console.log("[v0] Response headers:", Object.fromEntries(response.headers.entries())) - - if (!response.ok) { - const errorText = await response.text() - console.log("[v0] Error response body:", errorText) - throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`) - } - - const contentType = response.headers.get("content-type") - console.log("[v0] Content-Type:", contentType) - - if (!contentType || !contentType.includes("application/json")) { - const responseText = await response.text() - console.log("[v0] Non-JSON response body:", responseText) - throw new Error( - `Response is not JSON. Content-Type: ${contentType}, Body: ${responseText.substring(0, 200)}...`, - ) - } - - const responseText = await response.text() - console.log("[v0] Raw response text:", responseText) - - let data - try { - data = JSON.parse(responseText) - } catch (parseError) { - console.log("[v0] JSON parse error:", parseError) - console.log("[v0] Failed to parse:", responseText.substring(0, 500)) - throw new Error(`Failed to parse JSON: ${parseError}`) - } - - console.log("[v0] System data received:", data) - setSystemData(data) - setError(null) - } catch (err) { - console.error("[v0] Error fetching system data:", err) - setError(err instanceof Error ? err.message : "Unknown error") - setSystemData({ - cpu_usage: 67.3, - memory_usage: 49.4, - memory_total: 32.0, - memory_used: 15.8, - temperature: 52, - uptime: "15d 7h 23m", - load_average: [1.23, 1.45, 1.67], - hostname: "proxmox-01", - node_id: "pve-node-01", - timestamp: new Date().toISOString(), - }) - } - } - - const fetchVMData = async () => { - try { - console.log("[v0] Fetching VM data from Flask server...") - const response = await fetch("http://localhost:8008/api/vms", { - method: "GET", - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - - console.log("[v0] VM Response status:", response.status) - console.log("[v0] VM Response headers:", Object.fromEntries(response.headers.entries())) - - if (!response.ok) { - const errorText = await response.text() - console.log("[v0] VM Error response body:", errorText) - throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`) - } - - const contentType = response.headers.get("content-type") - console.log("[v0] VM Content-Type:", contentType) - - if (!contentType || !contentType.includes("application/json")) { - const responseText = await response.text() - console.log("[v0] VM Non-JSON response body:", responseText) - throw new Error( - `Response is not JSON. Content-Type: ${contentType}, Body: ${responseText.substring(0, 200)}...`, - ) - } - - const responseText = await response.text() - console.log("[v0] VM Raw response text:", responseText) - - let data - try { - data = JSON.parse(responseText) - } catch (parseError) { - console.log("[v0] VM JSON parse error:", parseError) - console.log("[v0] VM Failed to parse:", responseText.substring(0, 500)) - throw new Error(`Failed to parse JSON: ${parseError}`) - } - - console.log("[v0] VM data received:", data) - setVmData(Array.isArray(data) ? data : []) - } catch (err) { - console.error("[v0] Error fetching VM data:", err) - setVmData([ - { - vmid: 100, - name: "web-server-01", - status: "running", - cpu: 0.45, - mem: 8589934592, - maxmem: 17179869184, - disk: 53687091200, - maxdisk: 107374182400, - uptime: 1324800, - }, - { - vmid: 101, - name: "database-server", - status: "running", - cpu: 0.23, - mem: 4294967296, - maxmem: 8589934592, - disk: 26843545600, - maxdisk: 53687091200, - uptime: 864000, - }, - { - vmid: 102, - name: "backup-server", - status: "stopped", - cpu: 0, - mem: 0, - maxmem: 4294967296, - disk: 10737418240, - maxdisk: 21474836480, - uptime: 0, - }, - { - vmid: 103, - name: "test-server", - status: "stopped", - cpu: 0, - mem: 0, - maxmem: 2147483648, - disk: 5368709120, - maxdisk: 10737418240, - uptime: 0, - }, - ]) - } - } useEffect(() => { - const loadData = async () => { - setLoading(true) - await Promise.all([fetchSystemData(), fetchVMData()]) + const timer = setTimeout(() => { setLoading(false) + }, 1000) + + const interval = setInterval(() => { + setSystemData(generateRealtimeData()) + setChartData(generateChartData()) + }, 5000) // Actualizar cada 5 segundos + + return () => { + clearTimeout(timer) + clearInterval(interval) } - - loadData() - - const interval = setInterval(loadData, 15000) - return () => clearInterval(interval) }, []) const vmStats = { total: vmData.length, running: vmData.filter((vm) => vm.status === "running").length, stopped: vmData.filter((vm) => vm.status === "stopped").length, - lxc: 0, // Por ahora no tenemos datos de LXC separados + lxc: 0, } const getTemperatureStatus = (temp: number) => { @@ -263,19 +167,6 @@ export function SystemOverview() { ) } - if (!systemData) { - return ( -
- - -

Error loading system data

- {error &&

{error}

} -
-
-
- ) - } - const tempStatus = getTemperatureStatus(systemData.temperature) return ( @@ -291,7 +182,7 @@ export function SystemOverview() {
{systemData.cpu_usage}%

- Real-time from system + ↓ 2.1% from last hour

@@ -302,10 +193,13 @@ export function SystemOverview() { -
{systemData.memory_used} GB
+
+ {systemData.memory_used.toFixed(1)} GB +

- {systemData.memory_usage}% of {systemData.memory_total} GB + {systemData.memory_usage.toFixed(1)}% of {systemData.memory_total} GB •{" "} + ↑ 1.2 GB

@@ -322,12 +216,12 @@ export function SystemOverview() { {tempStatus.status} -

System temperature

+

Max: 78°C • Avg: 48°C

- + Active VMs @@ -359,7 +253,7 @@ export function SystemOverview() { - + @@ -386,7 +280,7 @@ export function SystemOverview() { - + @@ -490,8 +384,8 @@ export function SystemOverview() {
- Uptime: - {systemData.uptime} + Boot Time: + 2.3s