Ready to build sysinfo route screen
This commit is contained in:
parent
bd5ea1fb23
commit
f14e8a8e58
97
virtweb_backend/Cargo.lock
generated
97
virtweb_backend/Cargo.lock
generated
@ -749,6 +749,30 @@ dependencies = [
|
|||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"memoffset",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.16"
|
version = "0.8.16"
|
||||||
@ -843,6 +867,12 @@ dependencies = [
|
|||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.33"
|
version = "0.8.33"
|
||||||
@ -1325,6 +1355,15 @@ version = "2.6.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e"
|
checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
@ -1380,6 +1419,25 @@ dependencies = [
|
|||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntapi"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.32.0"
|
version = "0.32.0"
|
||||||
@ -1570,6 +1628,28 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
@ -1877,6 +1957,22 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sysinfo"
|
||||||
|
version = "0.29.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0a18d114d420ada3a891e6bc8e96a2023402203296a47cdd65083377dad18ba5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
"ntapi",
|
||||||
|
"once_cell",
|
||||||
|
"rayon",
|
||||||
|
"serde",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.8.0"
|
version = "3.8.0"
|
||||||
@ -2145,6 +2241,7 @@ dependencies = [
|
|||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"sysinfo",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"url",
|
"url",
|
||||||
"virt",
|
"virt",
|
||||||
|
@ -26,4 +26,5 @@ actix-multipart = "0.6.1"
|
|||||||
tempfile = "3.8.0"
|
tempfile = "3.8.0"
|
||||||
reqwest = { version = "0.11.18", features = ["stream"] }
|
reqwest = { version = "0.11.18", features = ["stream"] }
|
||||||
url = "2.4.0"
|
url = "2.4.0"
|
||||||
virt = "0.3.0"
|
virt = "0.3.0"
|
||||||
|
sysinfo = { version = "0.29.10", features = ["serde"] }
|
@ -4,6 +4,7 @@ use crate::constants;
|
|||||||
use crate::controllers::{HttpResult, LibVirtReq};
|
use crate::controllers::{HttpResult, LibVirtReq};
|
||||||
use crate::extractors::local_auth_extractor::LocalAuthEnabled;
|
use crate::extractors::local_auth_extractor::LocalAuthEnabled;
|
||||||
use actix_web::{HttpResponse, Responder};
|
use actix_web::{HttpResponse, Responder};
|
||||||
|
use sysinfo::{System, SystemExt};
|
||||||
|
|
||||||
pub async fn root_index() -> impl Responder {
|
pub async fn root_index() -> impl Responder {
|
||||||
HttpResponse::Ok().body("Hello world!")
|
HttpResponse::Ok().body("Hello world!")
|
||||||
@ -31,10 +32,17 @@ pub async fn static_config(local_auth: LocalAuthEnabled) -> impl Responder {
|
|||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
struct ServerInfo {
|
struct ServerInfo {
|
||||||
hypervisor: HypervisorInfo,
|
hypervisor: HypervisorInfo,
|
||||||
|
system: System,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn server_info(client: LibVirtReq) -> HttpResult {
|
pub async fn server_info(client: LibVirtReq) -> HttpResult {
|
||||||
|
let mut system = System::new();
|
||||||
|
system.refresh_disks_list();
|
||||||
|
system.refresh_components_list();
|
||||||
|
system.refresh_all();
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(ServerInfo {
|
Ok(HttpResponse::Ok().json(ServerInfo {
|
||||||
hypervisor: client.get_info().await?,
|
hypervisor: client.get_info().await?,
|
||||||
|
system,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import { LoginRoute } from "./routes/auth/LoginRoute";
|
|||||||
import { AuthApi } from "./api/AuthApi";
|
import { AuthApi } from "./api/AuthApi";
|
||||||
import { IsoFilesRoute } from "./routes/IsoFilesRoute";
|
import { IsoFilesRoute } from "./routes/IsoFilesRoute";
|
||||||
import { ServerApi } from "./api/ServerApi";
|
import { ServerApi } from "./api/ServerApi";
|
||||||
|
import { SysInfoRoute } from "./routes/SysInfoRoute";
|
||||||
|
|
||||||
interface AuthContext {
|
interface AuthContext {
|
||||||
signedIn: boolean;
|
signedIn: boolean;
|
||||||
@ -35,6 +36,7 @@ export function App() {
|
|||||||
signedIn || ServerApi.Config.auth_disabled ? (
|
signedIn || ServerApi.Config.auth_disabled ? (
|
||||||
<Route path="*" element={<BaseAuthenticatedPage />}>
|
<Route path="*" element={<BaseAuthenticatedPage />}>
|
||||||
<Route path="iso" element={<IsoFilesRoute />} />
|
<Route path="iso" element={<IsoFilesRoute />} />
|
||||||
|
<Route path="sysinfo" element={<SysInfoRoute />} />
|
||||||
<Route path="*" element={<NotFoundRoute />} />
|
<Route path="*" element={<NotFoundRoute />} />
|
||||||
</Route>
|
</Route>
|
||||||
) : (
|
) : (
|
||||||
|
@ -10,7 +10,100 @@ export interface ServerConfig {
|
|||||||
|
|
||||||
let config: ServerConfig | null = null;
|
let config: ServerConfig | null = null;
|
||||||
|
|
||||||
export interface ServerInfo {}
|
export interface ServerSystemInfo {
|
||||||
|
hypervisor: HypervisorInfo;
|
||||||
|
system: SystemInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HypervisorInfo {
|
||||||
|
type: string;
|
||||||
|
hyp_version: number;
|
||||||
|
lib_version: number;
|
||||||
|
capabilities: string;
|
||||||
|
free_memory: number;
|
||||||
|
hostname: string;
|
||||||
|
node: {
|
||||||
|
cpu_model: string;
|
||||||
|
memory_size: number;
|
||||||
|
number_of_active_cpus: number;
|
||||||
|
cpu_frequency_mhz: number;
|
||||||
|
number_of_numa_cell: number;
|
||||||
|
number_of_cpu_socket_per_node: number;
|
||||||
|
number_of_core_per_sockets: number;
|
||||||
|
number_of_threads_per_sockets: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SystemInfo {
|
||||||
|
IS_SUPPORTED: boolean;
|
||||||
|
SUPPORTED_SIGNALS: string[];
|
||||||
|
MINIMUM_CPU_UPDATE_INTERVAL: {
|
||||||
|
secs: number;
|
||||||
|
nanos: number;
|
||||||
|
};
|
||||||
|
global_cpu_info: GlobalCPUInfo;
|
||||||
|
cpus: CpuCore[];
|
||||||
|
physical_core_count: number;
|
||||||
|
total_memory: number;
|
||||||
|
free_memory: number;
|
||||||
|
available_memory: number;
|
||||||
|
used_memory: number;
|
||||||
|
total_swap: number;
|
||||||
|
free_swap: number;
|
||||||
|
used_swap: number;
|
||||||
|
components: SysComponent;
|
||||||
|
users: [];
|
||||||
|
disks: DiskInfo[];
|
||||||
|
networks: [];
|
||||||
|
uptime: number;
|
||||||
|
boot_time: number;
|
||||||
|
load_average: SysLoadAverage;
|
||||||
|
name: string;
|
||||||
|
kernel_version: string;
|
||||||
|
os_version: string;
|
||||||
|
long_os_version: string;
|
||||||
|
distribution_id: string;
|
||||||
|
host_name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GlobalCPUInfo {
|
||||||
|
cpu_usage: number;
|
||||||
|
name: string;
|
||||||
|
vendor_id: string;
|
||||||
|
brand: string;
|
||||||
|
frequency: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CpuCore {
|
||||||
|
cpu_usage: number;
|
||||||
|
name: string;
|
||||||
|
vendor_id: string;
|
||||||
|
brand: string;
|
||||||
|
frequency: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SysComponent {
|
||||||
|
temperature: number;
|
||||||
|
max: number;
|
||||||
|
critical: number;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DiskInfo {
|
||||||
|
DiskKind: "HDD" | "SSD";
|
||||||
|
name: string;
|
||||||
|
file_system: number[];
|
||||||
|
mount_point: string;
|
||||||
|
total_space: number;
|
||||||
|
available_space: number;
|
||||||
|
is_removable: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SysLoadAverage {
|
||||||
|
one: number;
|
||||||
|
five: number;
|
||||||
|
fifteen: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class ServerApi {
|
export class ServerApi {
|
||||||
/**
|
/**
|
||||||
@ -36,7 +129,7 @@ export class ServerApi {
|
|||||||
/**
|
/**
|
||||||
* Get server information
|
* Get server information
|
||||||
*/
|
*/
|
||||||
static async SystemInfo(): Promise<ServerInfo> {
|
static async SystemInfo(): Promise<ServerSystemInfo> {
|
||||||
return (
|
return (
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
26
virtweb_frontend/src/routes/SysInfoRoute.tsx
Normal file
26
virtweb_frontend/src/routes/SysInfoRoute.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { ServerApi, ServerSystemInfo } from "../api/ServerApi";
|
||||||
|
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||||
|
|
||||||
|
export function SysInfoRoute(): React.ReactElement {
|
||||||
|
const [info, setInfo] = React.useState<ServerSystemInfo>();
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
setInfo(await ServerApi.SystemInfo());
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AsyncWidget
|
||||||
|
load={load}
|
||||||
|
loadKey={1}
|
||||||
|
build={() => <SysInfoRouteInner info={info!} />}
|
||||||
|
errMsg="Failed to load system info"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SysInfoRouteInner(p: {
|
||||||
|
info: ServerSystemInfo;
|
||||||
|
}): React.ReactElement {
|
||||||
|
return <>todo</>;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { mdiDisc, mdiHome, mdiLanPending } from "@mdi/js";
|
import { mdiDisc, mdiHome, mdiInformation, mdiLanPending } from "@mdi/js";
|
||||||
import Icon from "@mdi/react";
|
import Icon from "@mdi/react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
@ -54,6 +54,11 @@ export function BaseAuthenticatedPage(): React.ReactElement {
|
|||||||
uri="/iso"
|
uri="/iso"
|
||||||
icon={<Icon path={mdiDisc} size={1} />}
|
icon={<Icon path={mdiDisc} size={1} />}
|
||||||
/>
|
/>
|
||||||
|
<NavLink
|
||||||
|
label="Sysinfo"
|
||||||
|
uri="/sysinfo"
|
||||||
|
icon={<Icon path={mdiInformation} size={1} />}
|
||||||
|
/>
|
||||||
</List>
|
</List>
|
||||||
<div style={{ flex: 1 }}>
|
<div style={{ flex: 1 }}>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
Loading…
Reference in New Issue
Block a user