Add the logic which will call disk image conversion from disk image route
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is failing
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	continuous-integration/drone/push Build is failing
				
			This commit is contained in:
		@@ -1,7 +1,7 @@
 | 
			
		||||
use crate::app_config::AppConfig;
 | 
			
		||||
use crate::constants;
 | 
			
		||||
use crate::controllers::HttpResult;
 | 
			
		||||
use crate::utils::file_disks_utils::DiskFileInfo;
 | 
			
		||||
use crate::utils::file_disks_utils::{DiskFileFormat, DiskFileInfo};
 | 
			
		||||
use crate::utils::files_utils;
 | 
			
		||||
use actix_files::NamedFile;
 | 
			
		||||
use actix_multipart::form::MultipartForm;
 | 
			
		||||
@@ -91,6 +91,59 @@ pub async fn download(p: web::Path<DiskFilePath>, req: HttpRequest) -> HttpResul
 | 
			
		||||
    Ok(NamedFile::open(file_path)?.into_response(&req))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize)]
 | 
			
		||||
pub struct ConvertDiskImageRequest {
 | 
			
		||||
    dest_file_name: String,
 | 
			
		||||
    #[serde(flatten)]
 | 
			
		||||
    format: DiskFileFormat,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Convert disk image into a new format
 | 
			
		||||
pub async fn convert(
 | 
			
		||||
    p: web::Path<DiskFilePath>,
 | 
			
		||||
    req: web::Json<ConvertDiskImageRequest>,
 | 
			
		||||
) -> HttpResult {
 | 
			
		||||
    if !files_utils::check_file_name(&p.filename) {
 | 
			
		||||
        return Ok(HttpResponse::BadRequest().json("Invalid src file name!"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if !files_utils::check_file_name(&req.dest_file_name) {
 | 
			
		||||
        return Ok(HttpResponse::BadRequest().json("Invalid destination file name!"));
 | 
			
		||||
    }
 | 
			
		||||
    if !req
 | 
			
		||||
        .format
 | 
			
		||||
        .ext()
 | 
			
		||||
        .iter()
 | 
			
		||||
        .any(|e| req.dest_file_name.ends_with(e))
 | 
			
		||||
    {
 | 
			
		||||
        return Ok(HttpResponse::BadRequest().json("Invalid destination file extension!"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let src_file_path = AppConfig::get()
 | 
			
		||||
        .disk_images_storage_path()
 | 
			
		||||
        .join(&p.filename);
 | 
			
		||||
 | 
			
		||||
    let src = DiskFileInfo::load_file(&src_file_path)?;
 | 
			
		||||
 | 
			
		||||
    let dst_file_path = AppConfig::get()
 | 
			
		||||
        .disk_images_storage_path()
 | 
			
		||||
        .join(&req.dest_file_name);
 | 
			
		||||
 | 
			
		||||
    if dst_file_path.exists() {
 | 
			
		||||
        return Ok(HttpResponse::Conflict().json("Specified destination file already exists!"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Perform conversion
 | 
			
		||||
    if let Err(e) = src.convert(&dst_file_path, req.format) {
 | 
			
		||||
        log::error!("Disk file conversion error: {e}");
 | 
			
		||||
        return Ok(
 | 
			
		||||
            HttpResponse::InternalServerError().json(format!("Disk file conversion error: {e}"))
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(HttpResponse::Ok().json(src))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Delete a disk image
 | 
			
		||||
pub async fn delete(p: web::Path<DiskFilePath>) -> HttpResult {
 | 
			
		||||
    if !files_utils::check_file_name(&p.filename) {
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,7 @@ struct ServerConstraints {
 | 
			
		||||
    memory_size: LenConstraints,
 | 
			
		||||
    disk_name_size: LenConstraints,
 | 
			
		||||
    disk_size: LenConstraints,
 | 
			
		||||
    disk_image_name_size: LenConstraints,
 | 
			
		||||
    net_name_size: LenConstraints,
 | 
			
		||||
    net_title_size: LenConstraints,
 | 
			
		||||
    net_nat_comment_size: LenConstraints,
 | 
			
		||||
@@ -91,6 +92,8 @@ pub async fn static_config(local_auth: LocalAuthEnabled) -> impl Responder {
 | 
			
		||||
                max: DISK_SIZE_MAX.as_bytes(),
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            disk_image_name_size: LenConstraints { min: 5, max: 220 },
 | 
			
		||||
 | 
			
		||||
            net_name_size: LenConstraints { min: 2, max: 50 },
 | 
			
		||||
            net_title_size: LenConstraints { min: 0, max: 50 },
 | 
			
		||||
            net_nat_comment_size: LenConstraints {
 | 
			
		||||
 
 | 
			
		||||
@@ -349,6 +349,10 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
                "/api/disk_images/{filename}",
 | 
			
		||||
                web::get().to(disk_images_controller::download),
 | 
			
		||||
            )
 | 
			
		||||
            .route(
 | 
			
		||||
                "/api/disk_images/{filename}/convert",
 | 
			
		||||
                web::post().to(disk_images_controller::convert),
 | 
			
		||||
            )
 | 
			
		||||
            .route(
 | 
			
		||||
                "/api/disk_images/{filename}",
 | 
			
		||||
                web::delete().to(disk_images_controller::delete),
 | 
			
		||||
 
 | 
			
		||||
@@ -13,15 +13,32 @@ enum DisksError {
 | 
			
		||||
    Create,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, serde::Serialize)]
 | 
			
		||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Copy, Clone)]
 | 
			
		||||
#[serde(tag = "format")]
 | 
			
		||||
pub enum DiskFileFormat {
 | 
			
		||||
    Raw { is_sparse: bool },
 | 
			
		||||
    QCow2 { virtual_size: FileSize },
 | 
			
		||||
    Raw {
 | 
			
		||||
        #[serde(default)]
 | 
			
		||||
        is_sparse: bool,
 | 
			
		||||
    },
 | 
			
		||||
    QCow2 {
 | 
			
		||||
        #[serde(default)]
 | 
			
		||||
        virtual_size: FileSize,
 | 
			
		||||
    },
 | 
			
		||||
    CompressedRaw,
 | 
			
		||||
    CompressedQCow2,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl DiskFileFormat {
 | 
			
		||||
    pub fn ext(&self) -> &'static [&'static str] {
 | 
			
		||||
        match self {
 | 
			
		||||
            DiskFileFormat::Raw { .. } => &["", "raw"],
 | 
			
		||||
            DiskFileFormat::QCow2 { .. } => &["qcow2"],
 | 
			
		||||
            DiskFileFormat::CompressedRaw => &["raw.gz"],
 | 
			
		||||
            DiskFileFormat::CompressedQCow2 => &["qcow2.gz"],
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Disk file information
 | 
			
		||||
#[derive(serde::Serialize)]
 | 
			
		||||
pub struct DiskFileInfo {
 | 
			
		||||
@@ -125,6 +142,11 @@ impl DiskFileInfo {
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Copy / convert file disk image into a new destination with optionally a new file format
 | 
			
		||||
    pub fn convert(&self, dest_file: &Path, dest_format: DiskFileFormat) -> anyhow::Result<()> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize)]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,14 @@
 | 
			
		||||
#[derive(
 | 
			
		||||
    serde::Serialize, serde::Deserialize, Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord,
 | 
			
		||||
    serde::Serialize,
 | 
			
		||||
    serde::Deserialize,
 | 
			
		||||
    Copy,
 | 
			
		||||
    Clone,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Eq,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    PartialOrd,
 | 
			
		||||
    Ord,
 | 
			
		||||
    Default,
 | 
			
		||||
)]
 | 
			
		||||
pub struct FileSize(usize);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user