diff --git a/virtweb_backend/src/controllers/server_controller.rs b/virtweb_backend/src/controllers/server_controller.rs index b1425cc..72d66df 100644 --- a/virtweb_backend/src/controllers/server_controller.rs +++ b/virtweb_backend/src/controllers/server_controller.rs @@ -39,6 +39,7 @@ pub async fn server_info(client: LibVirtReq) -> HttpResult { let mut system = System::new(); system.refresh_disks_list(); system.refresh_components_list(); + system.refresh_networks_list(); system.refresh_all(); Ok(HttpResponse::Ok().json(ServerInfo { diff --git a/virtweb_frontend/src/api/ServerApi.ts b/virtweb_frontend/src/api/ServerApi.ts index 84b8328..a6403c8 100644 --- a/virtweb_frontend/src/api/ServerApi.ts +++ b/virtweb_frontend/src/api/ServerApi.ts @@ -54,7 +54,7 @@ interface SystemInfo { components: SysComponent; users: []; disks: DiskInfo[]; - networks: []; + networks: NetworkInfo[]; uptime: number; boot_time: number; load_average: SysLoadAverage; @@ -89,7 +89,7 @@ interface SysComponent { label: string; } -interface DiskInfo { +export interface DiskInfo { DiskKind: "HDD" | "SSD"; name: string; file_system: number[]; @@ -99,6 +99,23 @@ interface DiskInfo { is_removable: boolean; } +export type NetworkInfo = [string, NetworkDetails]; +interface NetworkDetails { + received: number; + total_received: number; + transmitted: number; + total_transmitted: number; + packets_received: number; + total_packets_received: number; + packets_transmitted: number; + total_packets_transmitted: number; + errors_on_received: number; + total_errors_on_received: number; + errors_on_transmitted: number; + total_errors_on_transmitted: number; + mac_address: number[]; +} + interface SysLoadAverage { one: number; five: number; diff --git a/virtweb_frontend/src/routes/SysInfoRoute.tsx b/virtweb_frontend/src/routes/SysInfoRoute.tsx index 6a45308..7498670 100644 --- a/virtweb_frontend/src/routes/SysInfoRoute.tsx +++ b/virtweb_frontend/src/routes/SysInfoRoute.tsx @@ -1,21 +1,35 @@ -import { mdiInformation, mdiMemory, mdiPackageVariantClosed } from "@mdi/js"; +import { + mdiHarddisk, + mdiInformation, + mdiMemory, + mdiNetwork, + mdiPackageVariantClosed, +} from "@mdi/js"; import Icon from "@mdi/react"; import { Box, Grid, + LinearProgress, Table, TableBody, TableCell, + TableHead, TableRow, Typography, } from "@mui/material"; import { PieChart } from "@mui/x-charts"; import React from "react"; -import { ServerApi, ServerSystemInfo } from "../api/ServerApi"; +import { + DiskInfo, + NetworkInfo, + ServerApi, + ServerSystemInfo, +} from "../api/ServerApi"; import { AsyncWidget } from "../widgets/AsyncWidget"; import { VirtWebPaper } from "../widgets/VirtWebPaper"; import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer"; import humanizeDuration from "humanize-duration"; +import { filesize } from "filesize"; export function SysInfoRoute(): React.ReactElement { const [info, setInfo] = React.useState(); @@ -212,6 +226,9 @@ export function SysInfoRouteInner(p: { { label: "Kernel version", value: p.info.system.kernel_version }, ]} /> + + + ); } @@ -244,3 +261,83 @@ function SysInfoDetailsTable(p: { ); } + +function DiskDetailsTable(p: { disks: DiskInfo[] }): React.ReactElement { + return ( + + Storage + + } + > + + + + Name + Kind + Mount point + Total space + Free space + + Removable + + + + {p.disks.map((e, c) => ( + + {e.name} + {e.DiskKind} + {e.mount_point} + {filesize(e.total_space)} + {filesize(e.available_space)} + + + + {e.is_removable ? "Yes" : "No"} + + ))} + +
+
+ ); +} + +function NetworksDetailsTable(p: { + networks: NetworkInfo[]; +}): React.ReactElement { + return ( + + Networks + + } + > + + + + Name + Total received + Total transmitted + + + + {p.networks.map((e, c) => ( + + {e[0]} + {filesize(e[1].total_received)} + {filesize(e[1].total_transmitted)} + + ))} + +
+
+ ); +}