Can set the number of VCPUs
This commit is contained in:
		
							
								
								
									
										47
									
								
								virtweb_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										47
									
								
								virtweb_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -1624,6 +1624,40 @@ dependencies = [
 | 
				
			|||||||
 "winapi",
 | 
					 "winapi",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "num"
 | 
				
			||||||
 | 
					version = "0.4.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "num-bigint",
 | 
				
			||||||
 | 
					 "num-complex",
 | 
				
			||||||
 | 
					 "num-integer",
 | 
				
			||||||
 | 
					 "num-iter",
 | 
				
			||||||
 | 
					 "num-rational",
 | 
				
			||||||
 | 
					 "num-traits",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "num-bigint"
 | 
				
			||||||
 | 
					version = "0.4.4"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "autocfg",
 | 
				
			||||||
 | 
					 "num-integer",
 | 
				
			||||||
 | 
					 "num-traits",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "num-complex"
 | 
				
			||||||
 | 
					version = "0.4.4"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "num-traits",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "num-integer"
 | 
					name = "num-integer"
 | 
				
			||||||
version = "0.1.45"
 | 
					version = "0.1.45"
 | 
				
			||||||
@@ -1634,6 +1668,17 @@ dependencies = [
 | 
				
			|||||||
 "num-traits",
 | 
					 "num-traits",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "num-iter"
 | 
				
			||||||
 | 
					version = "0.1.43"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "autocfg",
 | 
				
			||||||
 | 
					 "num-integer",
 | 
				
			||||||
 | 
					 "num-traits",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "num-rational"
 | 
					name = "num-rational"
 | 
				
			||||||
version = "0.4.1"
 | 
					version = "0.4.1"
 | 
				
			||||||
@@ -1641,6 +1686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			|||||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
 | 
					checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "autocfg",
 | 
					 "autocfg",
 | 
				
			||||||
 | 
					 "num-bigint",
 | 
				
			||||||
 "num-integer",
 | 
					 "num-integer",
 | 
				
			||||||
 "num-traits",
 | 
					 "num-traits",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -2583,6 +2629,7 @@ dependencies = [
 | 
				
			|||||||
 "lazy_static",
 | 
					 "lazy_static",
 | 
				
			||||||
 "light-openid",
 | 
					 "light-openid",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
 | 
					 "num",
 | 
				
			||||||
 "rand",
 | 
					 "rand",
 | 
				
			||||||
 "reqwest",
 | 
					 "reqwest",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,3 +40,4 @@ bytes = "1.5.0"
 | 
				
			|||||||
tokio = "1.32.0"
 | 
					tokio = "1.32.0"
 | 
				
			||||||
futures = "0.3.28"
 | 
					futures = "0.3.28"
 | 
				
			||||||
ipnetwork = "0.20.0"
 | 
					ipnetwork = "0.20.0"
 | 
				
			||||||
 | 
					num = "0.4.1"
 | 
				
			||||||
@@ -91,6 +91,23 @@ pub async fn server_info(client: LibVirtReq) -> HttpResult {
 | 
				
			|||||||
    }))
 | 
					    }))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn number_vcpus() -> HttpResult {
 | 
				
			||||||
 | 
					    let mut system = System::new();
 | 
				
			||||||
 | 
					    system.refresh_cpu();
 | 
				
			||||||
 | 
					    let number_cpus = system.cpus().len();
 | 
				
			||||||
 | 
					    assert_ne!(number_cpus, 0, "Got invlid number of CPU!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut possible_numbers = vec![1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if number_cpus > 1 {
 | 
				
			||||||
 | 
					        for i in 0..(number_cpus / 2) {
 | 
				
			||||||
 | 
					            possible_numbers.push(2 + 2 * i);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().json(possible_numbers))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn networks_list() -> HttpResult {
 | 
					pub async fn networks_list() -> HttpResult {
 | 
				
			||||||
    let mut system = System::new();
 | 
					    let mut system = System::new();
 | 
				
			||||||
    system.refresh_networks_list();
 | 
					    system.refresh_networks_list();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -192,6 +192,13 @@ pub struct DomainCPUTopology {
 | 
				
			|||||||
    pub threads: usize,
 | 
					    pub threads: usize,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
 | 
					#[serde(rename = "cpu")]
 | 
				
			||||||
 | 
					pub struct DomainVCPUXML {
 | 
				
			||||||
 | 
					    #[serde(rename = "$value")]
 | 
				
			||||||
 | 
					    pub body: usize,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(serde::Serialize, serde::Deserialize)]
 | 
					#[derive(serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
#[serde(rename = "cpu")]
 | 
					#[serde(rename = "cpu")]
 | 
				
			||||||
pub struct DomainCPUXML {
 | 
					pub struct DomainCPUXML {
 | 
				
			||||||
@@ -221,6 +228,9 @@ pub struct DomainXML {
 | 
				
			|||||||
    /// The maximum allocation of memory for the guest at boot time
 | 
					    /// The maximum allocation of memory for the guest at boot time
 | 
				
			||||||
    pub memory: DomainMemoryXML,
 | 
					    pub memory: DomainMemoryXML,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Number of vCPU
 | 
				
			||||||
 | 
					    pub vcpu: DomainVCPUXML,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// CPU information
 | 
					    /// CPU information
 | 
				
			||||||
    pub cpu: DomainCPUXML,
 | 
					    pub cpu: DomainCPUXML,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,15 +2,17 @@ use crate::app_config::AppConfig;
 | 
				
			|||||||
use crate::constants;
 | 
					use crate::constants;
 | 
				
			||||||
use crate::libvirt_lib_structures::{
 | 
					use crate::libvirt_lib_structures::{
 | 
				
			||||||
    DevicesXML, DiskBootXML, DiskDriverXML, DiskReadOnlyXML, DiskSourceXML, DiskTargetXML, DiskXML,
 | 
					    DevicesXML, DiskBootXML, DiskDriverXML, DiskReadOnlyXML, DiskSourceXML, DiskTargetXML, DiskXML,
 | 
				
			||||||
    DomainCPUTopology, DomainCPUXML, DomainMemoryXML, DomainXML, FeaturesXML, GraphicsXML,
 | 
					    DomainCPUTopology, DomainCPUXML, DomainMemoryXML, DomainVCPUXML, DomainXML, FeaturesXML,
 | 
				
			||||||
    NetworkDHCPRangeXML, NetworkDHCPXML, NetworkDNSForwarderXML, NetworkDNSXML, NetworkDomainXML,
 | 
					    GraphicsXML, NetworkDHCPRangeXML, NetworkDHCPXML, NetworkDNSForwarderXML, NetworkDNSXML,
 | 
				
			||||||
    NetworkForwardXML, NetworkIPXML, NetworkXML, OSLoaderXML, OSTypeXML, XMLUuid, ACPIXML, OSXML,
 | 
					    NetworkDomainXML, NetworkForwardXML, NetworkIPXML, NetworkXML, OSLoaderXML, OSTypeXML, XMLUuid,
 | 
				
			||||||
 | 
					    ACPIXML, OSXML,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use crate::libvirt_rest_structures::LibVirtStructError::StructureExtraction;
 | 
					use crate::libvirt_rest_structures::LibVirtStructError::StructureExtraction;
 | 
				
			||||||
use crate::utils::disks_utils::Disk;
 | 
					use crate::utils::disks_utils::Disk;
 | 
				
			||||||
use crate::utils::files_utils;
 | 
					use crate::utils::files_utils;
 | 
				
			||||||
use ipnetwork::{Ipv4Network, Ipv6Network};
 | 
					use ipnetwork::{Ipv4Network, Ipv6Network};
 | 
				
			||||||
use lazy_regex::regex;
 | 
					use lazy_regex::regex;
 | 
				
			||||||
 | 
					use num::Integer;
 | 
				
			||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
 | 
					use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
 | 
				
			||||||
use std::ops::{Div, Mul};
 | 
					use std::ops::{Div, Mul};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,6 +76,8 @@ pub struct VMInfo {
 | 
				
			|||||||
    pub architecture: VMArchitecture,
 | 
					    pub architecture: VMArchitecture,
 | 
				
			||||||
    /// VM allocated memory, in megabytes
 | 
					    /// VM allocated memory, in megabytes
 | 
				
			||||||
    pub memory: usize,
 | 
					    pub memory: usize,
 | 
				
			||||||
 | 
					    /// Number of vCPU for the VM
 | 
				
			||||||
 | 
					    pub number_vcpu: usize,
 | 
				
			||||||
    /// Enable VNC access through admin console
 | 
					    /// Enable VNC access through admin console
 | 
				
			||||||
    pub vnc_access: bool,
 | 
					    pub vnc_access: bool,
 | 
				
			||||||
    /// Attach an ISO file
 | 
					    /// Attach an ISO file
 | 
				
			||||||
@@ -81,7 +85,6 @@ pub struct VMInfo {
 | 
				
			|||||||
    /// Storage - https://access.redhat.com/documentation/fr-fr/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sect-virtualization-virtualized_block_devices-adding_storage_devices_to_guests#sect-Virtualization-Adding_storage_devices_to_guests-Adding_file_based_storage_to_a_guest
 | 
					    /// Storage - https://access.redhat.com/documentation/fr-fr/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sect-virtualization-virtualized_block_devices-adding_storage_devices_to_guests#sect-Virtualization-Adding_storage_devices_to_guests-Adding_file_based_storage_to_a_guest
 | 
				
			||||||
    pub disks: Vec<Disk>,
 | 
					    pub disks: Vec<Disk>,
 | 
				
			||||||
    // TODO : network interfaces
 | 
					    // TODO : network interfaces
 | 
				
			||||||
    // TODO : number of CPUs
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl VMInfo {
 | 
					impl VMInfo {
 | 
				
			||||||
@@ -116,6 +119,10 @@ impl VMInfo {
 | 
				
			|||||||
            return Err(StructureExtraction("VM memory is invalid!").into());
 | 
					            return Err(StructureExtraction("VM memory is invalid!").into());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.number_vcpu == 0 || (self.number_vcpu != 1 && self.number_vcpu.is_odd()) {
 | 
				
			||||||
 | 
					            return Err(StructureExtraction("Invalid number of vCPU specified!").into());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut disks = vec![];
 | 
					        let mut disks = vec![];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if let Some(iso_file) = &self.iso_file {
 | 
					        if let Some(iso_file) = &self.iso_file {
 | 
				
			||||||
@@ -245,12 +252,22 @@ impl VMInfo {
 | 
				
			|||||||
                memory: self.memory,
 | 
					                memory: self.memory,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            vcpu: DomainVCPUXML {
 | 
				
			||||||
 | 
					                body: self.number_vcpu,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            cpu: DomainCPUXML {
 | 
					            cpu: DomainCPUXML {
 | 
				
			||||||
                mode: "host-passthrough".to_string(),
 | 
					                mode: "host-passthrough".to_string(),
 | 
				
			||||||
                topology: Some(DomainCPUTopology {
 | 
					                topology: Some(DomainCPUTopology {
 | 
				
			||||||
                    sockets: 1,
 | 
					                    sockets: 1,
 | 
				
			||||||
                    cores: 1,
 | 
					                    cores: match self.number_vcpu {
 | 
				
			||||||
                    threads: 1,
 | 
					                        1 => 1,
 | 
				
			||||||
 | 
					                        v => v / 2,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    threads: match self.number_vcpu {
 | 
				
			||||||
 | 
					                        1 => 1,
 | 
				
			||||||
 | 
					                        _ => 2,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
                }),
 | 
					                }),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -285,6 +302,7 @@ impl VMInfo {
 | 
				
			|||||||
                    .into());
 | 
					                    .into());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            number_vcpu: domain.vcpu.body,
 | 
				
			||||||
            memory: convert_to_mb(&domain.memory.unit, domain.memory.memory)?,
 | 
					            memory: convert_to_mb(&domain.memory.unit, domain.memory.memory)?,
 | 
				
			||||||
            vnc_access: domain.devices.graphics.is_some(),
 | 
					            vnc_access: domain.devices.graphics.is_some(),
 | 
				
			||||||
            iso_file: domain
 | 
					            iso_file: domain
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -102,6 +102,10 @@ async fn main() -> std::io::Result<()> {
 | 
				
			|||||||
                "/api/server/info",
 | 
					                "/api/server/info",
 | 
				
			||||||
                web::get().to(server_controller::server_info),
 | 
					                web::get().to(server_controller::server_info),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            .route(
 | 
				
			||||||
 | 
					                "/api/server/number_vcpus",
 | 
				
			||||||
 | 
					                web::get().to(server_controller::number_vcpus),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
            .route(
 | 
					            .route(
 | 
				
			||||||
                "/api/server/networks",
 | 
					                "/api/server/networks",
 | 
				
			||||||
                web::get().to(server_controller::networks_list),
 | 
					                web::get().to(server_controller::networks_list),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -172,6 +172,18 @@ export class ServerApi {
 | 
				
			|||||||
    ).data;
 | 
					    ).data;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Get host supported vCPUs configurations
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  static async NumberVCPUs(): Promise<number[]> {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      await APIClient.exec({
 | 
				
			||||||
 | 
					        method: "GET",
 | 
				
			||||||
 | 
					        uri: "/server/number_vcpus",
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    ).data;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Get host networks card list
 | 
					   * Get host networks card list
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,6 +39,7 @@ interface VMInfoInterface {
 | 
				
			|||||||
  boot_type: "UEFI" | "UEFISecureBoot";
 | 
					  boot_type: "UEFI" | "UEFISecureBoot";
 | 
				
			||||||
  architecture: "i686" | "x86_64";
 | 
					  architecture: "i686" | "x86_64";
 | 
				
			||||||
  memory: number;
 | 
					  memory: number;
 | 
				
			||||||
 | 
					  number_vcpu: number;
 | 
				
			||||||
  vnc_access: boolean;
 | 
					  vnc_access: boolean;
 | 
				
			||||||
  iso_file?: string;
 | 
					  iso_file?: string;
 | 
				
			||||||
  disks: VMDisk[];
 | 
					  disks: VMDisk[];
 | 
				
			||||||
@@ -52,6 +53,7 @@ export class VMInfo implements VMInfoInterface {
 | 
				
			|||||||
  description?: string;
 | 
					  description?: string;
 | 
				
			||||||
  boot_type: "UEFI" | "UEFISecureBoot";
 | 
					  boot_type: "UEFI" | "UEFISecureBoot";
 | 
				
			||||||
  architecture: "i686" | "x86_64";
 | 
					  architecture: "i686" | "x86_64";
 | 
				
			||||||
 | 
					  number_vcpu: number;
 | 
				
			||||||
  memory: number;
 | 
					  memory: number;
 | 
				
			||||||
  vnc_access: boolean;
 | 
					  vnc_access: boolean;
 | 
				
			||||||
  iso_file?: string;
 | 
					  iso_file?: string;
 | 
				
			||||||
@@ -65,6 +67,7 @@ export class VMInfo implements VMInfoInterface {
 | 
				
			|||||||
    this.description = int.description;
 | 
					    this.description = int.description;
 | 
				
			||||||
    this.boot_type = int.boot_type;
 | 
					    this.boot_type = int.boot_type;
 | 
				
			||||||
    this.architecture = int.architecture;
 | 
					    this.architecture = int.architecture;
 | 
				
			||||||
 | 
					    this.number_vcpu = int.number_vcpu;
 | 
				
			||||||
    this.memory = int.memory;
 | 
					    this.memory = int.memory;
 | 
				
			||||||
    this.vnc_access = int.vnc_access;
 | 
					    this.vnc_access = int.vnc_access;
 | 
				
			||||||
    this.iso_file = int.iso_file;
 | 
					    this.iso_file = int.iso_file;
 | 
				
			||||||
@@ -77,6 +80,7 @@ export class VMInfo implements VMInfoInterface {
 | 
				
			|||||||
      boot_type: "UEFI",
 | 
					      boot_type: "UEFI",
 | 
				
			||||||
      architecture: "x86_64",
 | 
					      architecture: "x86_64",
 | 
				
			||||||
      memory: 1024,
 | 
					      memory: 1024,
 | 
				
			||||||
 | 
					      number_vcpu: 1,
 | 
				
			||||||
      vnc_access: true,
 | 
					      vnc_access: true,
 | 
				
			||||||
      disks: [],
 | 
					      disks: [],
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,7 @@ function VNCInner(p: { vm: VMInfo }): React.ReactElement {
 | 
				
			|||||||
      }}
 | 
					      }}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <VncScreen
 | 
					      <VncScreen
 | 
				
			||||||
        url={token!.url}
 | 
					        url={token.url}
 | 
				
			||||||
        onDisconnect={() => {
 | 
					        onDisconnect={() => {
 | 
				
			||||||
          console.info("VNC disconnected " + token?.url);
 | 
					          console.info("VNC disconnected " + token?.url);
 | 
				
			||||||
          disconnected();
 | 
					          disconnected();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,10 +22,14 @@ interface DetailsProps {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function VMDetails(p: DetailsProps): React.ReactElement {
 | 
					export function VMDetails(p: DetailsProps): React.ReactElement {
 | 
				
			||||||
  const [list, setList] = React.useState<IsoFile[] | any>();
 | 
					  const [isoList, setIsoList] = React.useState<IsoFile[] | any>();
 | 
				
			||||||
 | 
					  const [vcpuCombinations, setVCPUCombinations] = React.useState<
 | 
				
			||||||
 | 
					    number[] | any
 | 
				
			||||||
 | 
					  >();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const load = async () => {
 | 
					  const load = async () => {
 | 
				
			||||||
    setList(await IsoFilesApi.GetList());
 | 
					    setIsoList(await IsoFilesApi.GetList());
 | 
				
			||||||
 | 
					    setVCPUCombinations(await ServerApi.NumberVCPUs());
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@@ -33,13 +37,19 @@ export function VMDetails(p: DetailsProps): React.ReactElement {
 | 
				
			|||||||
      loadKey={"1"}
 | 
					      loadKey={"1"}
 | 
				
			||||||
      load={load}
 | 
					      load={load}
 | 
				
			||||||
      errMsg="Failed to load the list of ISO files"
 | 
					      errMsg="Failed to load the list of ISO files"
 | 
				
			||||||
      build={() => <VMDetailsInner isoList={list} {...p} />}
 | 
					      build={() => (
 | 
				
			||||||
 | 
					        <VMDetailsInner
 | 
				
			||||||
 | 
					          isoList={isoList}
 | 
				
			||||||
 | 
					          vcpuCombinations={vcpuCombinations}
 | 
				
			||||||
 | 
					          {...p}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
    />
 | 
					    />
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function VMDetailsInner(
 | 
					function VMDetailsInner(
 | 
				
			||||||
  p: DetailsProps & { isoList: IsoFile[] }
 | 
					  p: DetailsProps & { isoList: IsoFile[]; vcpuCombinations: number[] }
 | 
				
			||||||
): React.ReactElement {
 | 
					): React.ReactElement {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Grid container spacing={2}>
 | 
					    <Grid container spacing={2}>
 | 
				
			||||||
@@ -146,6 +156,19 @@ function VMDetailsInner(
 | 
				
			|||||||
          }
 | 
					          }
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <SelectInput
 | 
				
			||||||
 | 
					          editable={p.editable}
 | 
				
			||||||
 | 
					          label="Number of vCPU"
 | 
				
			||||||
 | 
					          options={p.vcpuCombinations.map((v) => {
 | 
				
			||||||
 | 
					            return { label: v.toString(), value: v.toString() };
 | 
				
			||||||
 | 
					          })}
 | 
				
			||||||
 | 
					          value={p.vm.number_vcpu.toString()}
 | 
				
			||||||
 | 
					          onValueChange={(v) => {
 | 
				
			||||||
 | 
					            p.vm.number_vcpu = Number(v ?? "0");
 | 
				
			||||||
 | 
					            p.onChange?.();
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <CheckboxInput
 | 
					        <CheckboxInput
 | 
				
			||||||
          editable={p.editable}
 | 
					          editable={p.editable}
 | 
				
			||||||
          label="Enable VNC access"
 | 
					          label="Enable VNC access"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user