Ready to build sysinfo route screen

This commit is contained in:
Pierre HUBERT 2023-09-08 09:45:41 +02:00
parent bd5ea1fb23
commit f14e8a8e58
7 changed files with 236 additions and 4 deletions

View File

@ -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",

View File

@ -27,3 +27,4 @@ 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"] }

View File

@ -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,
})) }))
} }

View File

@ -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>
) : ( ) : (

View File

@ -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",

View 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</>;
}

View File

@ -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 />