Can query hypervisor information
This commit is contained in:
		
							
								
								
									
										23
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								README.md
									
									
									
									
									
								
							@@ -1,2 +1,25 @@
 | 
				
			|||||||
# VirtWEB
 | 
					# VirtWEB
 | 
				
			||||||
WIP project
 | 
					WIP project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Development requirements
 | 
				
			||||||
 | 
					1. The `libvirt-dev` package must be installed:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					sudo apt install libvirt-dev
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Libvirt must also be installed:
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					sudo apt install qemu-kvm libvirt-daemon-system
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Allow the current user to manage VMs:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					sudo adduser $USER libvirt
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> Note: You will need to login again for this change to take effect.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Production requirements
 | 
				
			||||||
 | 
					TODO
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										77
									
								
								virtweb_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										77
									
								
								virtweb_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -2,6 +2,31 @@
 | 
				
			|||||||
# It is not intended for manual editing.
 | 
					# It is not intended for manual editing.
 | 
				
			||||||
version = 3
 | 
					version = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "actix"
 | 
				
			||||||
 | 
					version = "0.13.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "cba56612922b907719d4a01cf11c8d5b458e7d3dba946d0435f20f58d6795ed2"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "actix-macros",
 | 
				
			||||||
 | 
					 "actix-rt",
 | 
				
			||||||
 | 
					 "actix_derive",
 | 
				
			||||||
 | 
					 "bitflags 2.4.0",
 | 
				
			||||||
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "crossbeam-channel",
 | 
				
			||||||
 | 
					 "futures-core",
 | 
				
			||||||
 | 
					 "futures-sink",
 | 
				
			||||||
 | 
					 "futures-task",
 | 
				
			||||||
 | 
					 "futures-util",
 | 
				
			||||||
 | 
					 "log",
 | 
				
			||||||
 | 
					 "once_cell",
 | 
				
			||||||
 | 
					 "parking_lot",
 | 
				
			||||||
 | 
					 "pin-project-lite",
 | 
				
			||||||
 | 
					 "smallvec",
 | 
				
			||||||
 | 
					 "tokio",
 | 
				
			||||||
 | 
					 "tokio-util",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "actix-codec"
 | 
					name = "actix-codec"
 | 
				
			||||||
version = "0.5.1"
 | 
					version = "0.5.1"
 | 
				
			||||||
@@ -301,6 +326,17 @@ dependencies = [
 | 
				
			|||||||
 "syn 2.0.29",
 | 
					 "syn 2.0.29",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "actix_derive"
 | 
				
			||||||
 | 
					version = "0.6.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "syn 1.0.109",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "addr2line"
 | 
					name = "addr2line"
 | 
				
			||||||
version = "0.21.0"
 | 
					version = "0.21.0"
 | 
				
			||||||
@@ -703,6 +739,25 @@ dependencies = [
 | 
				
			|||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "crossbeam-channel"
 | 
				
			||||||
 | 
					version = "0.5.8"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 | 
					 "crossbeam-utils",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "crossbeam-utils"
 | 
				
			||||||
 | 
					version = "0.8.16"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "crypto-common"
 | 
					name = "crypto-common"
 | 
				
			||||||
version = "0.1.6"
 | 
					version = "0.1.6"
 | 
				
			||||||
@@ -2042,6 +2097,26 @@ version = "0.9.4"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 | 
					checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "virt"
 | 
				
			||||||
 | 
					version = "0.3.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "9316a0df71f1ec209e7ef8ab07097e4181945b245d3348f57de07a3e811e53cf"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "virt-sys",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "virt-sys"
 | 
				
			||||||
 | 
					version = "0.2.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "cd39f6e0d0ab3fe7c371fac05c9b6ca72e186f06a2e666fb3b95441091eba2db"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "pkg-config",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "virtue"
 | 
					name = "virtue"
 | 
				
			||||||
version = "0.0.13"
 | 
					version = "0.0.13"
 | 
				
			||||||
@@ -2052,6 +2127,7 @@ checksum = "9dcc60c0624df774c82a0ef104151231d37da4962957d691c011c852b2473314"
 | 
				
			|||||||
name = "virtweb_backend"
 | 
					name = "virtweb_backend"
 | 
				
			||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "actix",
 | 
				
			||||||
 "actix-cors",
 | 
					 "actix-cors",
 | 
				
			||||||
 "actix-files",
 | 
					 "actix-files",
 | 
				
			||||||
 "actix-identity",
 | 
					 "actix-identity",
 | 
				
			||||||
@@ -2071,6 +2147,7 @@ dependencies = [
 | 
				
			|||||||
 "serde_json",
 | 
					 "serde_json",
 | 
				
			||||||
 "tempfile",
 | 
					 "tempfile",
 | 
				
			||||||
 "url",
 | 
					 "url",
 | 
				
			||||||
 | 
					 "virt",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ env_logger = "0.10.0"
 | 
				
			|||||||
clap = { version = "4.3.19", features = ["derive", "env"] }
 | 
					clap = { version = "4.3.19", features = ["derive", "env"] }
 | 
				
			||||||
light-openid = { version = "1.0.1", features = ["crypto-wrapper"] }
 | 
					light-openid = { version = "1.0.1", features = ["crypto-wrapper"] }
 | 
				
			||||||
lazy_static = "1.4.0"
 | 
					lazy_static = "1.4.0"
 | 
				
			||||||
 | 
					actix = "0.13.1"
 | 
				
			||||||
actix-web = "4"
 | 
					actix-web = "4"
 | 
				
			||||||
actix-remote-ip = "0.1.0"
 | 
					actix-remote-ip = "0.1.0"
 | 
				
			||||||
actix-session = { version = "0.7.2", features = ["cookie-session"] }
 | 
					actix-session = { version = "0.7.2", features = ["cookie-session"] }
 | 
				
			||||||
@@ -25,3 +26,4 @@ actix-multipart = "0.6.1"
 | 
				
			|||||||
tempfile = "3.8.0"
 | 
					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"
 | 
				
			||||||
							
								
								
									
										79
									
								
								virtweb_backend/src/actors/libvirt_actor.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								virtweb_backend/src/actors/libvirt_actor.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					use crate::app_config::AppConfig;
 | 
				
			||||||
 | 
					use actix::{Actor, Context, Handler, Message};
 | 
				
			||||||
 | 
					use virt::connect::Connect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct LibVirtActor {
 | 
				
			||||||
 | 
					    m: Connect,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl LibVirtActor {
 | 
				
			||||||
 | 
					    /// Connect to hypervisor
 | 
				
			||||||
 | 
					    pub async fn connect() -> anyhow::Result<Self> {
 | 
				
			||||||
 | 
					        let hypervisor_uri = AppConfig::get().hypervisor_uri.as_deref().unwrap_or("");
 | 
				
			||||||
 | 
					        log::info!(
 | 
				
			||||||
 | 
					            "Will connect to hypvervisor at address '{}'",
 | 
				
			||||||
 | 
					            hypervisor_uri
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        let conn = Connect::open(hypervisor_uri)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(Self { m: conn })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Actor for LibVirtActor {
 | 
				
			||||||
 | 
					    type Context = Context<Self>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Message)]
 | 
				
			||||||
 | 
					#[rtype(result = "anyhow::Result<HypervisorInfo>")]
 | 
				
			||||||
 | 
					pub struct GetHypervisorInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Serialize)]
 | 
				
			||||||
 | 
					pub struct HypervisorInfo {
 | 
				
			||||||
 | 
					    pub r#type: String,
 | 
				
			||||||
 | 
					    pub hyp_version: u32,
 | 
				
			||||||
 | 
					    pub lib_version: u32,
 | 
				
			||||||
 | 
					    pub capabilities: String,
 | 
				
			||||||
 | 
					    pub free_memory: u64,
 | 
				
			||||||
 | 
					    pub hostname: String,
 | 
				
			||||||
 | 
					    pub node: HypervisorNodeInfo,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Serialize)]
 | 
				
			||||||
 | 
					pub struct HypervisorNodeInfo {
 | 
				
			||||||
 | 
					    pub cpu_model: String,
 | 
				
			||||||
 | 
					    /// Memory size in kilobytes
 | 
				
			||||||
 | 
					    pub memory_size: u64,
 | 
				
			||||||
 | 
					    pub number_of_active_cpus: u32,
 | 
				
			||||||
 | 
					    pub cpu_frequency_mhz: u32,
 | 
				
			||||||
 | 
					    pub number_of_numa_cell: u32,
 | 
				
			||||||
 | 
					    pub number_of_cpu_socket_per_node: u32,
 | 
				
			||||||
 | 
					    pub number_of_core_per_sockets: u32,
 | 
				
			||||||
 | 
					    pub number_of_threads_per_sockets: u32,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Handler<GetHypervisorInfo> for LibVirtActor {
 | 
				
			||||||
 | 
					    type Result = anyhow::Result<HypervisorInfo>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn handle(&mut self, _msg: GetHypervisorInfo, _ctx: &mut Self::Context) -> Self::Result {
 | 
				
			||||||
 | 
					        let node = self.m.get_node_info()?;
 | 
				
			||||||
 | 
					        Ok(HypervisorInfo {
 | 
				
			||||||
 | 
					            r#type: self.m.get_type()?,
 | 
				
			||||||
 | 
					            hyp_version: self.m.get_hyp_version()?,
 | 
				
			||||||
 | 
					            lib_version: self.m.get_lib_version()?,
 | 
				
			||||||
 | 
					            capabilities: self.m.get_capabilities()?,
 | 
				
			||||||
 | 
					            free_memory: self.m.get_free_memory()?,
 | 
				
			||||||
 | 
					            hostname: self.m.get_hostname()?,
 | 
				
			||||||
 | 
					            node: HypervisorNodeInfo {
 | 
				
			||||||
 | 
					                cpu_model: node.model,
 | 
				
			||||||
 | 
					                memory_size: node.memory,
 | 
				
			||||||
 | 
					                number_of_active_cpus: node.cpus,
 | 
				
			||||||
 | 
					                cpu_frequency_mhz: node.mhz,
 | 
				
			||||||
 | 
					                number_of_numa_cell: node.nodes,
 | 
				
			||||||
 | 
					                number_of_cpu_socket_per_node: node.sockets,
 | 
				
			||||||
 | 
					                number_of_core_per_sockets: node.cores,
 | 
				
			||||||
 | 
					                number_of_threads_per_sockets: node.threads,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								virtweb_backend/src/actors/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								virtweb_backend/src/actors/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					pub mod libvirt_actor;
 | 
				
			||||||
@@ -72,6 +72,10 @@ pub struct AppConfig {
 | 
				
			|||||||
    /// Directory where temporary files are stored
 | 
					    /// Directory where temporary files are stored
 | 
				
			||||||
    #[arg(long, env, default_value = "/tmp")]
 | 
					    #[arg(long, env, default_value = "/tmp")]
 | 
				
			||||||
    pub temp_dir: String,
 | 
					    pub temp_dir: String,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Hypervisor URI. If not specified, "" will be used instead
 | 
				
			||||||
 | 
					    #[arg(long, env)]
 | 
				
			||||||
 | 
					    pub hypervisor_uri: Option<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lazy_static::lazy_static! {
 | 
					lazy_static::lazy_static! {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
 | 
					use crate::libvirt_client::LibVirtClient;
 | 
				
			||||||
use actix_web::body::BoxBody;
 | 
					use actix_web::body::BoxBody;
 | 
				
			||||||
use actix_web::HttpResponse;
 | 
					use actix_web::{web, HttpResponse};
 | 
				
			||||||
use std::error::Error;
 | 
					use std::error::Error;
 | 
				
			||||||
use std::fmt::{Display, Formatter};
 | 
					use std::fmt::{Display, Formatter};
 | 
				
			||||||
use std::io::ErrorKind;
 | 
					use std::io::ErrorKind;
 | 
				
			||||||
@@ -78,3 +79,5 @@ impl From<reqwest::header::ToStrError> for HttpErr {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type HttpResult = Result<HttpResponse, HttpErr>;
 | 
					pub type HttpResult = Result<HttpResponse, HttpErr>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub type LibVirtReq = web::Data<LibVirtClient>;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
 | 
					use crate::actors::libvirt_actor::HypervisorInfo;
 | 
				
			||||||
use crate::app_config::AppConfig;
 | 
					use crate::app_config::AppConfig;
 | 
				
			||||||
use crate::constants;
 | 
					use crate::constants;
 | 
				
			||||||
 | 
					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};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,3 +25,14 @@ pub async fn static_config(local_auth: LocalAuthEnabled) -> impl Responder {
 | 
				
			|||||||
        iso_max_size: constants::ISO_MAX_SIZE,
 | 
					        iso_max_size: constants::ISO_MAX_SIZE,
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Serialize)]
 | 
				
			||||||
 | 
					struct ServerInfo {
 | 
				
			||||||
 | 
					    hypervisor: HypervisorInfo,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn server_info(client: LibVirtReq) -> HttpResult {
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().json(ServerInfo {
 | 
				
			||||||
 | 
					        hypervisor: client.get_info().await?,
 | 
				
			||||||
 | 
					    }))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
 | 
					pub mod actors;
 | 
				
			||||||
pub mod app_config;
 | 
					pub mod app_config;
 | 
				
			||||||
pub mod constants;
 | 
					pub mod constants;
 | 
				
			||||||
pub mod controllers;
 | 
					pub mod controllers;
 | 
				
			||||||
pub mod extractors;
 | 
					pub mod extractors;
 | 
				
			||||||
 | 
					pub mod libvirt_client;
 | 
				
			||||||
pub mod middlewares;
 | 
					pub mod middlewares;
 | 
				
			||||||
pub mod utils;
 | 
					pub mod utils;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								virtweb_backend/src/libvirt_client.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								virtweb_backend/src/libvirt_client.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					use crate::actors::libvirt_actor;
 | 
				
			||||||
 | 
					use crate::actors::libvirt_actor::{HypervisorInfo, LibVirtActor};
 | 
				
			||||||
 | 
					use actix::Addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone)]
 | 
				
			||||||
 | 
					pub struct LibVirtClient(pub Addr<LibVirtActor>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl LibVirtClient {
 | 
				
			||||||
 | 
					    /// Get hypervisor info
 | 
				
			||||||
 | 
					    pub async fn get_info(&self) -> anyhow::Result<HypervisorInfo> {
 | 
				
			||||||
 | 
					        self.0.send(libvirt_actor::GetHypervisorInfo).await?
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					use actix::Actor;
 | 
				
			||||||
use actix_cors::Cors;
 | 
					use actix_cors::Cors;
 | 
				
			||||||
use actix_identity::config::LogoutBehaviour;
 | 
					use actix_identity::config::LogoutBehaviour;
 | 
				
			||||||
use actix_identity::IdentityMiddleware;
 | 
					use actix_identity::IdentityMiddleware;
 | 
				
			||||||
@@ -13,12 +14,14 @@ use actix_web::web::Data;
 | 
				
			|||||||
use actix_web::{web, App, HttpServer};
 | 
					use actix_web::{web, App, HttpServer};
 | 
				
			||||||
use light_openid::basic_state_manager::BasicStateManager;
 | 
					use light_openid::basic_state_manager::BasicStateManager;
 | 
				
			||||||
use std::time::Duration;
 | 
					use std::time::Duration;
 | 
				
			||||||
 | 
					use virtweb_backend::actors::libvirt_actor::LibVirtActor;
 | 
				
			||||||
use virtweb_backend::app_config::AppConfig;
 | 
					use virtweb_backend::app_config::AppConfig;
 | 
				
			||||||
use virtweb_backend::constants;
 | 
					use virtweb_backend::constants;
 | 
				
			||||||
use virtweb_backend::constants::{
 | 
					use virtweb_backend::constants::{
 | 
				
			||||||
    MAX_INACTIVITY_DURATION, MAX_SESSION_DURATION, SESSION_COOKIE_NAME,
 | 
					    MAX_INACTIVITY_DURATION, MAX_SESSION_DURATION, SESSION_COOKIE_NAME,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use virtweb_backend::controllers::{auth_controller, iso_controller, server_controller};
 | 
					use virtweb_backend::controllers::{auth_controller, iso_controller, server_controller};
 | 
				
			||||||
 | 
					use virtweb_backend::libvirt_client::LibVirtClient;
 | 
				
			||||||
use virtweb_backend::middlewares::auth_middleware::AuthChecker;
 | 
					use virtweb_backend::middlewares::auth_middleware::AuthChecker;
 | 
				
			||||||
use virtweb_backend::utils::files_utils;
 | 
					use virtweb_backend::utils::files_utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,6 +32,13 @@ async fn main() -> std::io::Result<()> {
 | 
				
			|||||||
    log::debug!("Create required directory, if missing");
 | 
					    log::debug!("Create required directory, if missing");
 | 
				
			||||||
    files_utils::create_directory_if_missing(&AppConfig::get().iso_storage_path()).unwrap();
 | 
					    files_utils::create_directory_if_missing(&AppConfig::get().iso_storage_path()).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let conn = Data::new(LibVirtClient(
 | 
				
			||||||
 | 
					        LibVirtActor::connect()
 | 
				
			||||||
 | 
					            .await
 | 
				
			||||||
 | 
					            .expect("Failed to connect to hypervisor!")
 | 
				
			||||||
 | 
					            .start(),
 | 
				
			||||||
 | 
					    ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log::info!("Start to listen on {}", AppConfig::get().listen_address);
 | 
					    log::info!("Start to listen on {}", AppConfig::get().listen_address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let state_manager = Data::new(BasicStateManager::new());
 | 
					    let state_manager = Data::new(BasicStateManager::new());
 | 
				
			||||||
@@ -69,6 +79,7 @@ async fn main() -> std::io::Result<()> {
 | 
				
			|||||||
            .app_data(Data::new(RemoteIPConfig {
 | 
					            .app_data(Data::new(RemoteIPConfig {
 | 
				
			||||||
                proxy: AppConfig::get().proxy_ip.clone(),
 | 
					                proxy: AppConfig::get().proxy_ip.clone(),
 | 
				
			||||||
            }))
 | 
					            }))
 | 
				
			||||||
 | 
					            .app_data(conn.clone())
 | 
				
			||||||
            // Uploaded files
 | 
					            // Uploaded files
 | 
				
			||||||
            .app_data(MultipartFormConfig::default().total_limit(constants::ISO_MAX_SIZE))
 | 
					            .app_data(MultipartFormConfig::default().total_limit(constants::ISO_MAX_SIZE))
 | 
				
			||||||
            .app_data(TempFileConfig::default().directory(&AppConfig::get().temp_dir))
 | 
					            .app_data(TempFileConfig::default().directory(&AppConfig::get().temp_dir))
 | 
				
			||||||
@@ -78,6 +89,10 @@ async fn main() -> std::io::Result<()> {
 | 
				
			|||||||
                "/api/server/static_config",
 | 
					                "/api/server/static_config",
 | 
				
			||||||
                web::get().to(server_controller::static_config),
 | 
					                web::get().to(server_controller::static_config),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            .route(
 | 
				
			||||||
 | 
					                "/api/server/info",
 | 
				
			||||||
 | 
					                web::get().to(server_controller::server_info),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
            // Auth controller
 | 
					            // Auth controller
 | 
				
			||||||
            .route(
 | 
					            .route(
 | 
				
			||||||
                "/api/auth/local",
 | 
					                "/api/auth/local",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,8 @@ export interface ServerConfig {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
let config: ServerConfig | null = null;
 | 
					let config: ServerConfig | null = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ServerInfo {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class ServerApi {
 | 
					export class ServerApi {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Get server configuration
 | 
					   * Get server configuration
 | 
				
			||||||
@@ -29,4 +31,16 @@ export class ServerApi {
 | 
				
			|||||||
    if (config === null) throw new Error("Missing configuration!");
 | 
					    if (config === null) throw new Error("Missing configuration!");
 | 
				
			||||||
    return config;
 | 
					    return config;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Get server information
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  static async SystemInfo(): Promise<ServerInfo> {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      await APIClient.exec({
 | 
				
			||||||
 | 
					        method: "GET",
 | 
				
			||||||
 | 
					        uri: "/server/info",
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    ).data;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,11 +11,10 @@ import {
 | 
				
			|||||||
} from "@mui/material";
 | 
					} from "@mui/material";
 | 
				
			||||||
import Box from "@mui/material/Box";
 | 
					import Box from "@mui/material/Box";
 | 
				
			||||||
import Button from "@mui/material/Button";
 | 
					import Button from "@mui/material/Button";
 | 
				
			||||||
import Grid from "@mui/material/Grid";
 | 
					 | 
				
			||||||
import TextField from "@mui/material/TextField";
 | 
					import TextField from "@mui/material/TextField";
 | 
				
			||||||
import Typography from "@mui/material/Typography";
 | 
					import Typography from "@mui/material/Typography";
 | 
				
			||||||
import * as React from "react";
 | 
					import * as React from "react";
 | 
				
			||||||
import { Link, useNavigate } from "react-router-dom";
 | 
					import { useNavigate } from "react-router-dom";
 | 
				
			||||||
import { useAuth } from "../../App";
 | 
					import { useAuth } from "../../App";
 | 
				
			||||||
import { AuthApi } from "../../api/AuthApi";
 | 
					import { AuthApi } from "../../api/AuthApi";
 | 
				
			||||||
import { ServerApi } from "../../api/ServerApi";
 | 
					import { ServerApi } from "../../api/ServerApi";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					import { mdiDisc, mdiHome, mdiLanPending } from "@mdi/js";
 | 
				
			||||||
 | 
					import Icon from "@mdi/react";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Box,
 | 
					  Box,
 | 
				
			||||||
  List,
 | 
					  List,
 | 
				
			||||||
@@ -5,13 +7,10 @@ import {
 | 
				
			|||||||
  ListItemIcon,
 | 
					  ListItemIcon,
 | 
				
			||||||
  ListItemSecondaryAction,
 | 
					  ListItemSecondaryAction,
 | 
				
			||||||
  ListItemText,
 | 
					  ListItemText,
 | 
				
			||||||
  ListSubheader,
 | 
					 | 
				
			||||||
} from "@mui/material";
 | 
					} from "@mui/material";
 | 
				
			||||||
import { VirtWebAppBar } from "./VirtWebAppBar";
 | 
					 | 
				
			||||||
import { RouterLink } from "./RouterLink";
 | 
					 | 
				
			||||||
import { Outlet, useLocation } from "react-router-dom";
 | 
					import { Outlet, useLocation } from "react-router-dom";
 | 
				
			||||||
import Icon from "@mdi/react";
 | 
					import { RouterLink } from "./RouterLink";
 | 
				
			||||||
import { mdiDisc, mdiHome, mdiLanPending } from "@mdi/js";
 | 
					import { VirtWebAppBar } from "./VirtWebAppBar";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function BaseAuthenticatedPage(): React.ReactElement {
 | 
					export function BaseAuthenticatedPage(): React.ReactElement {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user