Compare commits
18 Commits
20250618
...
renovate/e
Author | SHA1 | Date | |
---|---|---|---|
d4c7231438 | |||
0601d9cad9 | |||
a1b6ebd9f5 | |||
b8eedaab51 | |||
0afc3252c6 | |||
685f1bc502 | |||
3e642dd638 | |||
22ad68e43e | |||
1dd86807fd | |||
96747bda89 | |||
e15514dd4f | |||
7556ee2c06 | |||
992a902590 | |||
100f12e7c1 | |||
3de66a5873 | |||
49360188f5 | |||
35c48ba846 | |||
1ad4262086 |
virtweb_backend
virtweb_frontend
8
virtweb_backend/Cargo.lock
generated
8
virtweb_backend/Cargo.lock
generated
@ -2938,9 +2938,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 +3421,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",
|
||||||
|
@ -28,10 +28,10 @@ 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"
|
||||||
|
@ -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!(
|
||||||
|
1674
virtweb_frontend/package-lock.json
generated
1674
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",
|
||||||
@ -35,19 +35,19 @@
|
|||||||
"yaml": "^2.8.0"
|
"yaml": "^2.8.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.27.0",
|
"@eslint/js": "^9.30.1",
|
||||||
"@types/humanize-duration": "^3.27.4",
|
"@types/humanize-duration": "^3.27.4",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/react": "^19.1.8",
|
"@types/react": "^19.1.8",
|
||||||
"@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.29.0",
|
||||||
"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