From 49050c042d9bcbd3bbd6ade2d6b45ec42898b0d2 Mon Sep 17 00:00:00 2001 From: MacRimi Date: Sun, 5 Oct 2025 13:50:29 +0200 Subject: [PATCH] Update AppImage --- AppImage/components/network-metrics.tsx | 61 ++----- AppImage/components/virtual-machines.tsx | 213 +++++++++++++---------- AppImage/scripts/flask_server.py | 11 +- 3 files changed, 145 insertions(+), 140 deletions(-) diff --git a/AppImage/components/network-metrics.tsx b/AppImage/components/network-metrics.tsx index 88d7dff..1debcb8 100644 --- a/AppImage/components/network-metrics.tsx +++ b/AppImage/components/network-metrics.tsx @@ -4,7 +4,7 @@ import { useState } from "react" import { Card, CardContent, CardHeader, CardTitle } from "./ui/card" import { Badge } from "./ui/badge" import { Dialog, DialogContent, DialogHeader, DialogTitle } from "./ui/dialog" -import { Wifi, Globe, Shield, Activity, Network, Router, AlertCircle, Zap } from "lucide-react" +import { Wifi, Activity, Network, Router, AlertCircle, Zap } from "lucide-react" import useSWR from "swr" interface NetworkData { @@ -57,6 +57,7 @@ interface NetworkInterface { bond_active_slave?: string | null bridge_members?: string[] bridge_physical_interface?: string + bridge_bond_slaves?: string[] packet_loss_in?: number packet_loss_out?: number vmid?: number @@ -213,45 +214,6 @@ export function NetworkMetrics() { - - - Firewall Status - - - -
Active
-
- - Protected - -
-

System protected

-
-
- - - - Packets - - - -
{packetsRecvK}K
-
- - Received - -
- {networkData.traffic.packet_loss_in !== undefined && networkData.traffic.packet_loss_in > 0 && ( -

Loss: {networkData.traffic.packet_loss_in}%

- )} - {(!networkData.traffic.packet_loss_in || networkData.traffic.packet_loss_in === 0) && ( -

No packet loss

- )} -
-
- - - {networkData.physical_interfaces && networkData.physical_interfaces.length > 0 && ( @@ -335,7 +297,7 @@ export function NetworkMetrics() { - )} + {networkData.bridge_interfaces && networkData.bridge_interfaces.length > 0 && ( @@ -368,7 +330,7 @@ export function NetworkMetrics() { {typeBadge.label} {interface_.bridge_physical_interface && ( -
+
→ {interface_.bridge_physical_interface} {interface_.bridge_physical_interface.startsWith("bond") && networkData.physical_interfaces && ( @@ -388,6 +350,11 @@ export function NetworkMetrics() { })()} )} + {interface_.bridge_bond_slaves && interface_.bridge_bond_slaves.length > 0 && ( + + ({interface_.bridge_bond_slaves.join(", ")}) + + )}
)}
@@ -732,7 +699,15 @@ export function NetworkMetrics() {
{selectedInterface.bridge_members.length > 0 ? ( selectedInterface.bridge_members - .filter((member) => !member.startsWith(("enp", "eth", "eno", "ens", "wlan", "wlp"))) + .filter( + (member) => + !member.startsWith("enp") && + !member.startsWith("eth") && + !member.startsWith("eno") && + !member.startsWith("ens") && + !member.startsWith("wlan") && + !member.startsWith("wlp"), + ) .map((member, idx) => ( - - - + + + - {selectedVM?.name} + {selectedVM?.name} {selectedVM && ( -
+
{getTypeBadge(selectedVM.type).label} @@ -444,36 +443,72 @@ export function VirtualMachines() { -
+
{selectedVM && ( <> {/* Basic Information */}
-

Basic Information

-
+

+ Basic Information +

+
-
VMID
-
{selectedVM.vmid}
+
Name
+
{selectedVM.name}
-
CPU Usage
-
{(selectedVM.cpu * 100).toFixed(1)}%
+
Type
+ + {getTypeBadge(selectedVM.type).label} +
-
Memory
-
+
VMID
+
{selectedVM.vmid}
+
+
+
Status
+ + {selectedVM.status.toUpperCase()} + +
+
+
CPU Usage
+
80 + ? "text-red-500" + : selectedVM.cpu * 100 > 60 + ? "text-yellow-500" + : "text-green-500" + }`} + > + {(selectedVM.cpu * 100).toFixed(1)}% +
+
+
+
Memory
+
80 + ? "text-red-500" + : (selectedVM.mem / selectedVM.maxmem) * 100 > 60 + ? "text-yellow-500" + : "text-blue-500" + }`} + > {(selectedVM.mem / 1024 ** 3).toFixed(1)} / {(selectedVM.maxmem / 1024 ** 3).toFixed(1)} GB
-
Disk
-
+
Disk
+
{(selectedVM.disk / 1024 ** 3).toFixed(1)} / {(selectedVM.maxdisk / 1024 ** 3).toFixed(1)} GB
-
Uptime
-
{formatUptime(selectedVM.uptime)}
+
Uptime
+
{formatUptime(selectedVM.uptime)}
@@ -484,94 +519,90 @@ export function VirtualMachines() { ) : vmDetails?.config ? ( <>
-

Resources

-
+

+ Resources +

+
{vmDetails.config.cores && (
-
CPU Cores
-
{vmDetails.config.cores}
+
CPU Cores
+
{vmDetails.config.cores}
)} {vmDetails.config.sockets && (
-
CPU Sockets
-
{vmDetails.config.sockets}
+
CPU Sockets
+
{vmDetails.config.sockets}
)} {vmDetails.config.memory && (
-
Memory
-
{vmDetails.config.memory} MB
+
Memory
+
{vmDetails.config.memory} MB
)} {vmDetails.config.swap && (
-
Swap
-
{vmDetails.config.swap} MB
+
Swap
+
{vmDetails.config.swap} MB
)} {vmDetails.config.rootfs && ( -
-
Root Filesystem
-
+
+
Root Filesystem
+
{vmDetails.config.rootfs}
)} - {vmDetails.config.scsi0 && ( -
-
SCSI Disk 0
-
- {vmDetails.config.scsi0} + {Object.keys(vmDetails.config) + .filter((key) => key.match(/^(scsi|sata|ide|virtio)\d+$/)) + .map((diskKey) => ( +
+
+ {diskKey.toUpperCase().replace(/(\d+)/, " $1")} +
+
+ {vmDetails.config[diskKey]} +
-
- )} - {vmDetails.config.ide0 && ( -
-
IDE Disk 0
-
{vmDetails.config.ide0}
-
- )} + ))}
{/* Network Configuration */}
-

Network

-
- {vmDetails.config.net0 && ( -
-
Network Interface 0
-
{vmDetails.config.net0}
-
- )} - {vmDetails.config.net1 && ( -
-
Network Interface 1
-
{vmDetails.config.net1}
-
- )} - {vmDetails.config.net2 && ( -
-
Network Interface 2
-
{vmDetails.config.net2}
-
- )} +

+ Network +

+
+ {Object.keys(vmDetails.config) + .filter((key) => key.match(/^net\d+$/)) + .map((netKey) => ( +
+
+ Network Interface {netKey.replace("net", "")} +
+
+ {vmDetails.config[netKey]} +
+
+ ))} {vmDetails.config.nameserver && (
-
DNS Nameserver
-
{vmDetails.config.nameserver}
+
DNS Nameserver
+
{vmDetails.config.nameserver}
)} {vmDetails.config.searchdomain && (
-
Search Domain
+
Search Domain
{vmDetails.config.searchdomain}
)} {vmDetails.config.hostname && (
-
Hostname
+
Hostname
{vmDetails.config.hostname}
)} @@ -580,17 +611,19 @@ export function VirtualMachines() { {/* Options */}
-

Options

-
+

+ Options +

+
{vmDetails.config.onboot !== undefined && (
-
Start on Boot
+
Start on Boot
{vmDetails.config.onboot ? "Yes" : "No"} @@ -599,13 +632,13 @@ export function VirtualMachines() { )} {vmDetails.config.unprivileged !== undefined && (
-
Unprivileged
+
Unprivileged
{vmDetails.config.unprivileged ? "Yes" : "No"} @@ -614,25 +647,25 @@ export function VirtualMachines() { )} {vmDetails.config.ostype && (
-
OS Type
+
OS Type
{vmDetails.config.ostype}
)} {vmDetails.config.arch && (
-
Architecture
+
Architecture
{vmDetails.config.arch}
)} {vmDetails.config.boot && (
-
Boot Order
+
Boot Order
{vmDetails.config.boot}
)} {vmDetails.config.features && ( -
-
Features
+
+
Features
{vmDetails.config.features}
)} @@ -643,7 +676,9 @@ export function VirtualMachines() { {/* Control Actions */}
-

Control Actions

+

+ Control Actions +

- - {/* Download Logs */} -
- -
)}
diff --git a/AppImage/scripts/flask_server.py b/AppImage/scripts/flask_server.py index 3116710..2a8e2fb 100644 --- a/AppImage/scripts/flask_server.py +++ b/AppImage/scripts/flask_server.py @@ -987,7 +987,9 @@ def get_bridge_info(bridge_name): bridge_info = { 'members': [], 'physical_interface': None, - 'physical_duplex': 'unknown' # Added physical_duplex field + 'physical_duplex': 'unknown', # Added physical_duplex field + # Added bond_slaves to show physical interfaces + 'bond_slaves': [] } try: @@ -1003,8 +1005,12 @@ def get_bridge_info(bridge_name): bridge_info['physical_interface'] = member print(f"[v0] Bridge {bridge_name} connected to bond: {member}") - # Get duplex from bond's active slave bond_info = get_bond_info(member) + if bond_info['slaves']: + bridge_info['bond_slaves'] = bond_info['slaves'] + print(f"[v0] Bond {member} slaves: {bond_info['slaves']}") + + # Get duplex from bond's active slave if bond_info['active_slave']: try: net_if_stats = psutil.net_if_stats() @@ -1160,6 +1166,7 @@ def get_network_info(): interface_info['bridge_members'] = bridge_info['members'] interface_info['bridge_physical_interface'] = bridge_info['physical_interface'] interface_info['bridge_physical_duplex'] = bridge_info['physical_duplex'] + interface_info['bridge_bond_slaves'] = bridge_info['bond_slaves'] # Override bridge duplex with physical interface duplex if bridge_info['physical_duplex'] != 'unknown': interface_info['duplex'] = bridge_info['physical_duplex']