Can change VM groups
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Pierre HUBERT 2024-11-02 18:02:03 +01:00
parent c908d00c62
commit 20e6d7931e
6 changed files with 76 additions and 2 deletions

View File

@ -40,6 +40,7 @@ struct ServerConstraints {
vnc_token_duration: u64,
vm_name_size: LenConstraints,
vm_title_size: LenConstraints,
group_id_size: LenConstraints,
memory_size: LenConstraints,
disk_name_size: LenConstraints,
disk_size: LenConstraints,
@ -72,6 +73,7 @@ pub async fn static_config(local_auth: LocalAuthEnabled) -> impl Responder {
vm_name_size: LenConstraints { min: 2, max: 50 },
vm_title_size: LenConstraints { min: 0, max: 50 },
group_id_size: LenConstraints { min: 3, max: 50 },
memory_size: LenConstraints {
min: constants::MIN_VM_MEMORY,
max: constants::MAX_VM_MEMORY,

View File

@ -211,7 +211,7 @@ async fn main() -> std::io::Result<()> {
)
.route("/api/vnc", web::get().to(vm_controller::vnc))
// Groups controller
.route("/api/groups/list", web::get().to(groups_controller::list))
.route("/api/group/list", web::get().to(groups_controller::list))
// Network controller
.route(
"/api/network/create",

View File

@ -0,0 +1,15 @@
import { APIClient } from "./ApiClient";
export class GroupApi {
/**
* Get the entire list of networks
*/
static async GetList(): Promise<string[]> {
return (
await APIClient.exec({
method: "GET",
uri: "/group/list",
})
).data;
}
}

View File

@ -16,6 +16,7 @@ export interface ServerConstraints {
vnc_token_duration: number;
vm_name_size: LenConstraint;
vm_title_size: LenConstraint;
group_id_size: LenConstraint;
memory_size: LenConstraint;
disk_name_size: LenConstraint;
disk_size: LenConstraint;

View File

@ -63,6 +63,7 @@ interface VMInfoInterface {
genid?: string;
title?: string;
description?: string;
group?: string;
boot_type: "UEFI" | "UEFISecureBoot";
architecture: "i686" | "x86_64";
memory: number;
@ -80,6 +81,7 @@ export class VMInfo implements VMInfoInterface {
genid?: string;
title?: string;
description?: string;
group?: string;
boot_type: "UEFI" | "UEFISecureBoot";
architecture: "i686" | "x86_64";
number_vcpu: number;
@ -96,6 +98,7 @@ export class VMInfo implements VMInfoInterface {
this.genid = int.genid;
this.title = int.title;
this.description = int.description;
this.group = int.group;
this.boot_type = int.boot_type;
this.architecture = int.architecture;
this.number_vcpu = int.number_vcpu;

View File

@ -1,8 +1,11 @@
import { Button } from "@mui/material";
import AddIcon from "@mui/icons-material/Add";
import ListIcon from "@mui/icons-material/List";
import { Button, IconButton, Tooltip } from "@mui/material";
import Grid from "@mui/material/Grid2";
import React from "react";
import { useNavigate } from "react-router-dom";
import { validate as validateUUID } from "uuid";
import { GroupApi } from "../../api/GroupApi";
import { IsoFile, IsoFilesApi } from "../../api/IsoFilesApi";
import { NWFilter, NWFilterApi } from "../../api/NWFilterApi";
import { NetworkApi, NetworkInfo } from "../../api/NetworksApi";
@ -32,6 +35,7 @@ interface DetailsProps {
}
export function VMDetails(p: DetailsProps): React.ReactElement {
const [groupsList, setGroupsList] = React.useState<string[] | any>();
const [isoList, setIsoList] = React.useState<IsoFile[] | any>();
const [vcpuCombinations, setVCPUCombinations] = React.useState<
number[] | any
@ -42,6 +46,7 @@ export function VMDetails(p: DetailsProps): React.ReactElement {
>();
const load = async () => {
setGroupsList(await GroupApi.GetList());
setIsoList(await IsoFilesApi.GetList());
setVCPUCombinations(await ServerApi.NumberVCPUs());
setNetworksList(await NetworkApi.GetList());
@ -55,6 +60,7 @@ export function VMDetails(p: DetailsProps): React.ReactElement {
errMsg="Failed to load the list of ISO files"
build={() => (
<VMDetailsInner
groupsList={groupsList}
isoList={isoList}
vcpuCombinations={vcpuCombinations}
networksList={networksList}
@ -75,6 +81,7 @@ enum VMTab {
}
type DetailsInnerProps = DetailsProps & {
groupsList: string[];
isoList: IsoFile[];
vcpuCombinations: number[];
networksList: NetworkInfo[];
@ -117,6 +124,8 @@ function VMDetailsInner(p: DetailsInnerProps): React.ReactElement {
}
function VMDetailsTabGeneral(p: DetailsInnerProps): React.ReactElement {
const [addGroup, setAddGroup] = React.useState(false);
return (
<Grid container spacing={2}>
{
@ -175,6 +184,50 @@ function VMDetailsTabGeneral(p: DetailsInnerProps): React.ReactElement {
}}
multiline={true}
/>
<div style={{ display: "flex" }}>
{addGroup ? (
<TextInput
label="Group"
editable={p.editable}
value={p.vm.group}
onValueChange={(v) => {
p.vm.group = v;
p.onChange?.();
}}
size={ServerApi.Config.constraints.group_id_size}
/>
) : (
<SelectInput
editable={p.editable}
label="Group"
onValueChange={(v) => {
p.vm.group = v! as any;
p.onChange?.();
}}
value={p.vm.group}
options={[
{ label: "None" },
...p.groupsList.map((g) => {
return { value: g, label: g };
}),
]}
/>
)}
{p.editable && (
<Tooltip
title={
addGroup
? "Use an existing group"
: "Add a new group instead of using existing one"
}
>
<IconButton onClick={() => setAddGroup(!addGroup)}>
{addGroup ? <ListIcon /> : <AddIcon />}
</IconButton>
</Tooltip>
)}
</div>
</EditSection>
{/* General section */}