Compare commits
	
		
			20 Commits
		
	
	
		
			20250618
			...
			049ff90ee4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 049ff90ee4 | |||
| ddc8b65f8a | |||
| 0b67659efa | |||
| 0601d9cad9 | |||
| a1b6ebd9f5 | |||
| b8eedaab51 | |||
| 0afc3252c6 | |||
| 685f1bc502 | |||
| 3e642dd638 | |||
| 22ad68e43e | |||
| 1dd86807fd | |||
| 96747bda89 | |||
| e15514dd4f | |||
| 7556ee2c06 | |||
| 992a902590 | |||
| 100f12e7c1 | |||
| 3de66a5873 | |||
| 49360188f5 | |||
| 35c48ba846 | |||
| 1ad4262086 | 
							
								
								
									
										25
									
								
								virtweb_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										25
									
								
								virtweb_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -1930,6 +1930,17 @@ dependencies = [
 | 
				
			|||||||
 "syn",
 | 
					 "syn",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "io-uring"
 | 
				
			||||||
 | 
					version = "0.7.8"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bitflags 2.9.1",
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "ipnet"
 | 
					name = "ipnet"
 | 
				
			||||||
version = "2.11.0"
 | 
					version = "2.11.0"
 | 
				
			||||||
@@ -2938,9 +2949,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "reqwest"
 | 
					name = "reqwest"
 | 
				
			||||||
version = "0.12.20"
 | 
					version = "0.12.22"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813"
 | 
					checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "base64 0.22.1",
 | 
					 "base64 0.22.1",
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
@@ -3421,9 +3432,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "sysinfo"
 | 
					name = "sysinfo"
 | 
				
			||||||
version = "0.35.1"
 | 
					version = "0.35.2"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "79251336d17c72d9762b8b54be4befe38d2db56fbbc0241396d70f173c39d47a"
 | 
					checksum = "3c3ffa3e4ff2b324a57f7aeb3c349656c7b127c3c189520251a648102a92496e"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
@@ -3581,17 +3592,19 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tokio"
 | 
					name = "tokio"
 | 
				
			||||||
version = "1.45.0"
 | 
					version = "1.46.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
 | 
					checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "backtrace",
 | 
					 "backtrace",
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "io-uring",
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "mio",
 | 
					 "mio",
 | 
				
			||||||
 "parking_lot",
 | 
					 "parking_lot",
 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 "signal-hook-registry",
 | 
					 "signal-hook-registry",
 | 
				
			||||||
 | 
					 "slab",
 | 
				
			||||||
 "socket2",
 | 
					 "socket2",
 | 
				
			||||||
 "tokio-macros",
 | 
					 "tokio-macros",
 | 
				
			||||||
 "windows-sys 0.52.0",
 | 
					 "windows-sys 0.52.0",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,16 +28,16 @@ futures-util = "0.3.31"
 | 
				
			|||||||
anyhow = "1.0.98"
 | 
					anyhow = "1.0.98"
 | 
				
			||||||
actix-multipart = "0.7.2"
 | 
					actix-multipart = "0.7.2"
 | 
				
			||||||
tempfile = "3.20.0"
 | 
					tempfile = "3.20.0"
 | 
				
			||||||
reqwest = { version = "0.12.20", features = ["stream"] }
 | 
					reqwest = { version = "0.12.22", features = ["stream"] }
 | 
				
			||||||
url = "2.5.4"
 | 
					url = "2.5.4"
 | 
				
			||||||
virt = "0.4.2"
 | 
					virt = "0.4.2"
 | 
				
			||||||
sysinfo = { version = "0.35.1", features = ["serde"] }
 | 
					sysinfo = { version = "0.35.2", features = ["serde"] }
 | 
				
			||||||
uuid = { version = "1.16.0", features = ["v4", "serde"] }
 | 
					uuid = { version = "1.16.0", features = ["v4", "serde"] }
 | 
				
			||||||
lazy-regex = "3.4.1"
 | 
					lazy-regex = "3.4.1"
 | 
				
			||||||
thiserror = "2.0.12"
 | 
					thiserror = "2.0.12"
 | 
				
			||||||
image = "0.25.6"
 | 
					image = "0.25.6"
 | 
				
			||||||
rand = "0.9.1"
 | 
					rand = "0.9.1"
 | 
				
			||||||
tokio = { version = "1.45.0", features = ["rt", "time", "macros"] }
 | 
					tokio = { version = "1.46.1", features = ["rt", "time", "macros"] }
 | 
				
			||||||
futures = "0.3.31"
 | 
					futures = "0.3.31"
 | 
				
			||||||
ipnetwork = { version = "0.21.1", features = ["serde"] }
 | 
					ipnetwork = { version = "0.21.1", features = ["serde"] }
 | 
				
			||||||
num = "0.4.3"
 | 
					num = "0.4.3"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,10 +27,7 @@ impl LibVirtActor {
 | 
				
			|||||||
    /// Connect to hypervisor
 | 
					    /// Connect to hypervisor
 | 
				
			||||||
    pub async fn connect() -> anyhow::Result<Self> {
 | 
					    pub async fn connect() -> anyhow::Result<Self> {
 | 
				
			||||||
        let hypervisor_uri = AppConfig::get().hypervisor_uri.as_deref().unwrap_or("");
 | 
					        let hypervisor_uri = AppConfig::get().hypervisor_uri.as_deref().unwrap_or("");
 | 
				
			||||||
        log::info!(
 | 
					        log::info!("Will connect to hypvervisor at address '{hypervisor_uri}'",);
 | 
				
			||||||
            "Will connect to hypvervisor at address '{}'",
 | 
					 | 
				
			||||||
            hypervisor_uri
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        let conn = Connect::open(Some(hypervisor_uri))?;
 | 
					        let conn = Connect::open(Some(hypervisor_uri))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(Self { m: conn })
 | 
					        Ok(Self { m: conn })
 | 
				
			||||||
@@ -102,7 +99,7 @@ impl Handler<GetDomainXMLReq> for LibVirtActor {
 | 
				
			|||||||
        log::debug!("Get domain XML:\n{}", msg.0.as_string());
 | 
					        log::debug!("Get domain XML:\n{}", msg.0.as_string());
 | 
				
			||||||
        let domain = Domain::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
 | 
					        let domain = Domain::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
 | 
				
			||||||
        let xml = domain.get_xml_desc(VIR_DOMAIN_XML_SECURE)?;
 | 
					        let xml = domain.get_xml_desc(VIR_DOMAIN_XML_SECURE)?;
 | 
				
			||||||
        log::debug!("XML = {}", xml);
 | 
					        log::debug!("XML = {xml}");
 | 
				
			||||||
        DomainXML::parse_xml(&xml)
 | 
					        DomainXML::parse_xml(&xml)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -131,7 +128,7 @@ impl Handler<DefineDomainReq> for LibVirtActor {
 | 
				
			|||||||
    fn handle(&mut self, mut msg: DefineDomainReq, _ctx: &mut Self::Context) -> Self::Result {
 | 
					    fn handle(&mut self, mut msg: DefineDomainReq, _ctx: &mut Self::Context) -> Self::Result {
 | 
				
			||||||
        let xml = msg.1.as_xml()?;
 | 
					        let xml = msg.1.as_xml()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        log::debug!("Define domain:\n{}", xml);
 | 
					        log::debug!("Define domain:\n{xml}");
 | 
				
			||||||
        let domain = Domain::define_xml(&self.m, &xml)?;
 | 
					        let domain = Domain::define_xml(&self.m, &xml)?;
 | 
				
			||||||
        let uuid = XMLUuid::parse_from_str(&domain.get_uuid_string()?)?;
 | 
					        let uuid = XMLUuid::parse_from_str(&domain.get_uuid_string()?)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -446,7 +443,7 @@ impl Handler<GetNetworkXMLReq> for LibVirtActor {
 | 
				
			|||||||
        log::debug!("Get network XML:\n{}", msg.0.as_string());
 | 
					        log::debug!("Get network XML:\n{}", msg.0.as_string());
 | 
				
			||||||
        let network = Network::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
 | 
					        let network = Network::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
 | 
				
			||||||
        let xml = network.get_xml_desc(0)?;
 | 
					        let xml = network.get_xml_desc(0)?;
 | 
				
			||||||
        log::debug!("XML = {}", xml);
 | 
					        log::debug!("XML = {xml}");
 | 
				
			||||||
        NetworkXML::parse_xml(&xml)
 | 
					        NetworkXML::parse_xml(&xml)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -602,7 +599,7 @@ impl Handler<GetNWFilterXMLReq> for LibVirtActor {
 | 
				
			|||||||
        log::debug!("Get network filter XML:\n{}", msg.0.as_string());
 | 
					        log::debug!("Get network filter XML:\n{}", msg.0.as_string());
 | 
				
			||||||
        let filter = NWFilter::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
 | 
					        let filter = NWFilter::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
 | 
				
			||||||
        let xml = filter.get_xml_desc(0)?;
 | 
					        let xml = filter.get_xml_desc(0)?;
 | 
				
			||||||
        log::debug!("XML = {}", xml);
 | 
					        log::debug!("XML = {xml}");
 | 
				
			||||||
        NetworkFilterXML::parse_xml(xml)
 | 
					        NetworkFilterXML::parse_xml(xml)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -617,7 +614,7 @@ impl Handler<DefineNWFilterReq> for LibVirtActor {
 | 
				
			|||||||
    fn handle(&mut self, mut msg: DefineNWFilterReq, _ctx: &mut Self::Context) -> Self::Result {
 | 
					    fn handle(&mut self, mut msg: DefineNWFilterReq, _ctx: &mut Self::Context) -> Self::Result {
 | 
				
			||||||
        let xml = msg.1.into_xml()?;
 | 
					        let xml = msg.1.into_xml()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        log::debug!("Define network filter:\n{}", xml);
 | 
					        log::debug!("Define network filter:\n{xml}");
 | 
				
			||||||
        let filter = NWFilter::define_xml(&self.m, &xml)?;
 | 
					        let filter = NWFilter::define_xml(&self.m, &xml)?;
 | 
				
			||||||
        let uuid = XMLUuid::parse_from_str(&filter.get_uuid_string()?)?;
 | 
					        let uuid = XMLUuid::parse_from_str(&filter.get_uuid_string()?)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -280,7 +280,7 @@ impl AppConfig {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Get VM vnc sockets path for domain
 | 
					    /// Get VM vnc sockets path for domain
 | 
				
			||||||
    pub fn vnc_socket_for_domain(&self, name: &str) -> PathBuf {
 | 
					    pub fn vnc_socket_for_domain(&self, name: &str) -> PathBuf {
 | 
				
			||||||
        self.vnc_sockets_path().join(format!("vnc-{}", name))
 | 
					        self.vnc_sockets_path().join(format!("vnc-{name}"))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Get VM root disks storage directory
 | 
					    /// Get VM root disks storage directory
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,8 +34,7 @@ pub async fn upload(MultipartForm(mut form): MultipartForm<UploadDiskImageForm>)
 | 
				
			|||||||
    if let Some(mime_type) = file.content_type {
 | 
					    if let Some(mime_type) = file.content_type {
 | 
				
			||||||
        if !constants::ALLOWED_DISK_IMAGES_MIME_TYPES.contains(&mime_type.as_ref()) {
 | 
					        if !constants::ALLOWED_DISK_IMAGES_MIME_TYPES.contains(&mime_type.as_ref()) {
 | 
				
			||||||
            return Ok(HttpResponse::BadRequest().json(format!(
 | 
					            return Ok(HttpResponse::BadRequest().json(format!(
 | 
				
			||||||
                "Unsupported file type for disk upload: {}",
 | 
					                "Unsupported file type for disk upload: {mime_type}"
 | 
				
			||||||
                mime_type
 | 
					 | 
				
			||||||
            )));
 | 
					            )));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,7 +52,7 @@ pub async fn upload_file(MultipartForm(mut form): MultipartForm<UploadIsoForm>)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let dest_file = AppConfig::get().iso_storage_path().join(file_name);
 | 
					    let dest_file = AppConfig::get().iso_storage_path().join(file_name);
 | 
				
			||||||
    log::info!("Will save ISO file {:?}", dest_file);
 | 
					    log::info!("Will save ISO file {dest_file:?}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if dest_file.exists() {
 | 
					    if dest_file.exists() {
 | 
				
			||||||
        log::error!("Conflict with uploaded iso file name!");
 | 
					        log::error!("Conflict with uploaded iso file name!");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,7 @@ impl actix_web::error::ResponseError for HttpErr {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn error_response(&self) -> HttpResponse<BoxBody> {
 | 
					    fn error_response(&self) -> HttpResponse<BoxBody> {
 | 
				
			||||||
        log::error!("Error while processing request! {}", self);
 | 
					        log::error!("Error while processing request! {self}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        HttpResponse::InternalServerError().body("Failed to execute request!")
 | 
					        HttpResponse::InternalServerError().body("Failed to execute request!")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,7 +109,7 @@ fn extract_ip_mask<const V: usize>(n: Option<u8>) -> anyhow::Result<Option<u8>>
 | 
				
			|||||||
fn extract_nw_filter_comment(n: &Option<String>) -> anyhow::Result<Option<String>> {
 | 
					fn extract_nw_filter_comment(n: &Option<String>) -> anyhow::Result<Option<String>> {
 | 
				
			||||||
    if let Some(comment) = n {
 | 
					    if let Some(comment) = n {
 | 
				
			||||||
        if comment.len() > 256 || comment.contains('\"') || comment.contains('\n') {
 | 
					        if comment.len() > 256 || comment.contains('\"') || comment.contains('\n') {
 | 
				
			||||||
            return Err(NetworkFilterExtraction(format!("Invalid comment! {}", comment)).into());
 | 
					            return Err(NetworkFilterExtraction(format!("Invalid comment! {comment}")).into());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,8 +69,7 @@ where
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if !AppConfig::get().is_allowed_ip(remote_ip.0) {
 | 
					            if !AppConfig::get().is_allowed_ip(remote_ip.0) {
 | 
				
			||||||
                log::error!(
 | 
					                log::error!(
 | 
				
			||||||
                    "An attempt to access VirtWeb from an unauthorized network has been intercepted! {:?}",
 | 
					                    "An attempt to access VirtWeb from an unauthorized network has been intercepted! {remote_ip:?}"
 | 
				
			||||||
                    remote_ip
 | 
					 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
                return Ok(req
 | 
					                return Ok(req
 | 
				
			||||||
                    .into_response(
 | 
					                    .into_response(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,10 +81,10 @@ impl CloudInitConfig {
 | 
				
			|||||||
        // Process metadata
 | 
					        // Process metadata
 | 
				
			||||||
        let mut metadatas = vec![];
 | 
					        let mut metadatas = vec![];
 | 
				
			||||||
        if let Some(inst_id) = &self.instance_id {
 | 
					        if let Some(inst_id) = &self.instance_id {
 | 
				
			||||||
            metadatas.push(format!("instance-id: {}", inst_id));
 | 
					            metadatas.push(format!("instance-id: {inst_id}"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if let Some(local_hostname) = &self.local_hostname {
 | 
					        if let Some(local_hostname) = &self.local_hostname {
 | 
				
			||||||
            metadatas.push(format!("local-hostname: {}", local_hostname));
 | 
					            metadatas.push(format!("local-hostname: {local_hostname}"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if let Some(dsmode) = &self.dsmode {
 | 
					        if let Some(dsmode) = &self.dsmode {
 | 
				
			||||||
            metadatas.push(format!(
 | 
					            metadatas.push(format!(
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1667
									
								
								virtweb_frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1667
									
								
								virtweb_frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -11,15 +11,15 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@emotion/react": "^11.14.0",
 | 
					    "@emotion/react": "^11.14.0",
 | 
				
			||||||
    "@emotion/styled": "^11.14.0",
 | 
					    "@emotion/styled": "^11.14.1",
 | 
				
			||||||
    "@fontsource/roboto": "^5.2.6",
 | 
					    "@fontsource/roboto": "^5.2.6",
 | 
				
			||||||
    "@mdi/js": "^7.4.47",
 | 
					    "@mdi/js": "^7.4.47",
 | 
				
			||||||
    "@mdi/react": "^1.6.1",
 | 
					    "@mdi/react": "^1.6.1",
 | 
				
			||||||
    "@monaco-editor/react": "^4.7.0",
 | 
					    "@monaco-editor/react": "^4.7.0",
 | 
				
			||||||
    "@mui/icons-material": "^7.1.1",
 | 
					    "@mui/icons-material": "^7.1.2",
 | 
				
			||||||
    "@mui/material": "^7.1.1",
 | 
					    "@mui/material": "^7.1.2",
 | 
				
			||||||
    "@mui/x-charts": "^8.3.1",
 | 
					    "@mui/x-charts": "^8.3.1",
 | 
				
			||||||
    "@mui/x-data-grid": "^8.3.1",
 | 
					    "@mui/x-data-grid": "^8.7.0",
 | 
				
			||||||
    "date-and-time": "^3.6.0",
 | 
					    "date-and-time": "^3.6.0",
 | 
				
			||||||
    "filesize": "^10.1.6",
 | 
					    "filesize": "^10.1.6",
 | 
				
			||||||
    "humanize-duration": "^3.32.2",
 | 
					    "humanize-duration": "^3.32.2",
 | 
				
			||||||
@@ -27,7 +27,7 @@
 | 
				
			|||||||
    "monaco-yaml": "^5.4.0",
 | 
					    "monaco-yaml": "^5.4.0",
 | 
				
			||||||
    "react": "^19.1.0",
 | 
					    "react": "^19.1.0",
 | 
				
			||||||
    "react-dom": "^19.1.0",
 | 
					    "react-dom": "^19.1.0",
 | 
				
			||||||
    "react-router-dom": "^7.6.2",
 | 
					    "react-router-dom": "^7.6.3",
 | 
				
			||||||
    "react-syntax-highlighter": "^15.6.1",
 | 
					    "react-syntax-highlighter": "^15.6.1",
 | 
				
			||||||
    "react-vnc": "^3.1.0",
 | 
					    "react-vnc": "^3.1.0",
 | 
				
			||||||
    "uuid": "^11.1.0",
 | 
					    "uuid": "^11.1.0",
 | 
				
			||||||
@@ -42,12 +42,12 @@
 | 
				
			|||||||
    "@types/react-dom": "^19.1.6",
 | 
					    "@types/react-dom": "^19.1.6",
 | 
				
			||||||
    "@types/react-syntax-highlighter": "^15.5.13",
 | 
					    "@types/react-syntax-highlighter": "^15.5.13",
 | 
				
			||||||
    "@types/uuid": "^10.0.0",
 | 
					    "@types/uuid": "^10.0.0",
 | 
				
			||||||
    "@vitejs/plugin-react": "^4.4.1",
 | 
					    "@vitejs/plugin-react": "^4.6.0",
 | 
				
			||||||
    "eslint": "^9.27.0",
 | 
					    "eslint": "^9.30.1",
 | 
				
			||||||
    "eslint-plugin-react-dom": "^1.49.0",
 | 
					    "eslint-plugin-react-dom": "^1.52.2",
 | 
				
			||||||
    "eslint-plugin-react-hooks": "^5.2.0",
 | 
					    "eslint-plugin-react-hooks": "^5.2.0",
 | 
				
			||||||
    "eslint-plugin-react-refresh": "^0.4.20",
 | 
					    "eslint-plugin-react-refresh": "^0.4.20",
 | 
				
			||||||
    "eslint-plugin-react-x": "^1.49.0",
 | 
					    "eslint-plugin-react-x": "^1.52.2",
 | 
				
			||||||
    "globals": "^16.1.0",
 | 
					    "globals": "^16.1.0",
 | 
				
			||||||
    "typescript": "^5.8.3",
 | 
					    "typescript": "^5.8.3",
 | 
				
			||||||
    "typescript-eslint": "^8.32.1",
 | 
					    "typescript-eslint": "^8.32.1",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -319,7 +319,7 @@ function DiskDetailsTable(p: { disks: DiskInfo[] }): React.ReactElement {
 | 
				
			|||||||
          {p.disks.map((e, c) => (
 | 
					          {p.disks.map((e, c) => (
 | 
				
			||||||
            <TableRow hover key={c}>
 | 
					            <TableRow hover key={c}>
 | 
				
			||||||
              <TableCell>{e.name}</TableCell>
 | 
					              <TableCell>{e.name}</TableCell>
 | 
				
			||||||
              <TableCell>{e.DiskKind}</TableCell>
 | 
					              <TableCell>{String(e.DiskKind)}</TableCell>
 | 
				
			||||||
              <TableCell>{e.mount_point}</TableCell>
 | 
					              <TableCell>{e.mount_point}</TableCell>
 | 
				
			||||||
              <TableCell>{filesize(e.total_space)}</TableCell>
 | 
					              <TableCell>{filesize(e.total_space)}</TableCell>
 | 
				
			||||||
              <TableCell>{filesize(e.available_space)}</TableCell>
 | 
					              <TableCell>{filesize(e.available_space)}</TableCell>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user