Simplify RAM management
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		@@ -36,11 +36,11 @@ pub const ALLOWED_DISK_IMAGES_MIME_TYPES: [&str; 2] =
 | 
			
		||||
/// Disk image max size
 | 
			
		||||
pub const DISK_IMAGE_MAX_SIZE: FileSize = FileSize::from_gb(10 * 1000);
 | 
			
		||||
 | 
			
		||||
/// Min VM memory size (MB)
 | 
			
		||||
pub const MIN_VM_MEMORY: usize = 100;
 | 
			
		||||
/// Min VM memory size
 | 
			
		||||
pub const MIN_VM_MEMORY: FileSize = FileSize::from_mb(100);
 | 
			
		||||
 | 
			
		||||
/// Max VM memory size (MB)
 | 
			
		||||
pub const MAX_VM_MEMORY: usize = 64000;
 | 
			
		||||
/// Max VM memory size
 | 
			
		||||
pub const MAX_VM_MEMORY: FileSize = FileSize::from_gb(64);
 | 
			
		||||
 | 
			
		||||
/// Disk name min length
 | 
			
		||||
pub const DISK_NAME_MIN_LEN: usize = 2;
 | 
			
		||||
 
 | 
			
		||||
@@ -80,8 +80,8 @@ pub async fn static_config(local_auth: LocalAuthEnabled) -> impl Responder {
 | 
			
		||||
            vm_title_size: LenConstraints { min: 0, max: 50 },
 | 
			
		||||
            group_id_size: LenConstraints { min: 3, max: 50 },
 | 
			
		||||
            memory_size: LenConstraints {
 | 
			
		||||
                min: constants::MIN_VM_MEMORY,
 | 
			
		||||
                max: constants::MAX_VM_MEMORY,
 | 
			
		||||
                min: constants::MIN_VM_MEMORY.as_bytes(),
 | 
			
		||||
                max: constants::MAX_VM_MEMORY.as_bytes(),
 | 
			
		||||
            },
 | 
			
		||||
            disk_name_size: LenConstraints {
 | 
			
		||||
                min: DISK_NAME_MIN_LEN,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,8 @@ use crate::libvirt_lib_structures::XMLUuid;
 | 
			
		||||
use crate::libvirt_lib_structures::domain::*;
 | 
			
		||||
use crate::libvirt_rest_structures::LibVirtStructError;
 | 
			
		||||
use crate::libvirt_rest_structures::LibVirtStructError::StructureExtraction;
 | 
			
		||||
use crate::utils::file_size_utils::FileSize;
 | 
			
		||||
use crate::utils::files_utils;
 | 
			
		||||
use crate::utils::files_utils::convert_size_unit_to_mb;
 | 
			
		||||
use crate::utils::vm_file_disks_utils::{VMDiskFormat, VMFileDisk};
 | 
			
		||||
use lazy_regex::regex;
 | 
			
		||||
use num::Integer;
 | 
			
		||||
@@ -70,8 +70,8 @@ pub struct VMInfo {
 | 
			
		||||
    pub group: Option<VMGroupId>,
 | 
			
		||||
    pub boot_type: BootType,
 | 
			
		||||
    pub architecture: VMArchitecture,
 | 
			
		||||
    /// VM allocated memory, in megabytes
 | 
			
		||||
    pub memory: usize,
 | 
			
		||||
    /// VM allocated RAM memory
 | 
			
		||||
    pub memory: FileSize,
 | 
			
		||||
    /// Number of vCPU for the VM
 | 
			
		||||
    pub number_vcpu: usize,
 | 
			
		||||
    /// Enable VNC access through admin console
 | 
			
		||||
@@ -380,7 +380,7 @@ impl VMInfo {
 | 
			
		||||
 | 
			
		||||
            memory: DomainMemoryXML {
 | 
			
		||||
                unit: "MB".to_string(),
 | 
			
		||||
                memory: self.memory,
 | 
			
		||||
                memory: self.memory.as_mb(),
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            vcpu: DomainVCPUXML {
 | 
			
		||||
@@ -452,7 +452,7 @@ impl VMInfo {
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            number_vcpu: domain.vcpu.body,
 | 
			
		||||
            memory: convert_size_unit_to_mb(&domain.memory.unit, domain.memory.memory)?,
 | 
			
		||||
            memory: FileSize::from_size_unit(&domain.memory.unit, domain.memory.memory)?,
 | 
			
		||||
            vnc_access: domain.devices.graphics.is_some(),
 | 
			
		||||
            iso_files: domain
 | 
			
		||||
                .devices
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,12 @@
 | 
			
		||||
use std::ops::Mul;
 | 
			
		||||
 | 
			
		||||
#[derive(thiserror::Error, Debug)]
 | 
			
		||||
enum FilesSizeUtilsError {
 | 
			
		||||
    #[error("UnitConvertError: {0}")]
 | 
			
		||||
    UnitConvert(String),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Holds a data size, convertible in any form
 | 
			
		||||
#[derive(
 | 
			
		||||
    serde::Serialize,
 | 
			
		||||
    serde::Deserialize,
 | 
			
		||||
@@ -25,6 +34,30 @@ impl FileSize {
 | 
			
		||||
        Self(gb * 1000 * 1000 * 1000)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Convert size unit to MB
 | 
			
		||||
    pub fn from_size_unit(unit: &str, value: usize) -> anyhow::Result<Self> {
 | 
			
		||||
        let fact = match unit {
 | 
			
		||||
            "bytes" | "b" => 1f64,
 | 
			
		||||
            "KB" => 1000f64,
 | 
			
		||||
            "MB" => 1000f64 * 1000f64,
 | 
			
		||||
            "GB" => 1000f64 * 1000f64 * 1000f64,
 | 
			
		||||
            "TB" => 1000f64 * 1000f64 * 1000f64 * 1000f64,
 | 
			
		||||
 | 
			
		||||
            "k" | "KiB" => 1024f64,
 | 
			
		||||
            "M" | "MiB" => 1024f64 * 1024f64,
 | 
			
		||||
            "G" | "GiB" => 1024f64 * 1024f64 * 1024f64,
 | 
			
		||||
            "T" | "TiB" => 1024f64 * 1024f64 * 1024f64 * 1024f64,
 | 
			
		||||
 | 
			
		||||
            _ => {
 | 
			
		||||
                return Err(
 | 
			
		||||
                    FilesSizeUtilsError::UnitConvert(format!("Unknown size unit: {unit}")).into(),
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        Ok(Self((value as f64).mul(fact) as usize))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Get file size as bytes
 | 
			
		||||
    pub fn as_bytes(&self) -> usize {
 | 
			
		||||
        self.0
 | 
			
		||||
@@ -35,3 +68,24 @@ impl FileSize {
 | 
			
		||||
        self.0 / (1000 * 1000)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
    use crate::utils::file_size_utils::FileSize;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn convert_units_mb() {
 | 
			
		||||
        assert_eq!(FileSize::from_size_unit("MB", 1).unwrap().as_mb(), 1);
 | 
			
		||||
        assert_eq!(FileSize::from_size_unit("MB", 1000).unwrap().as_mb(), 1000);
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            FileSize::from_size_unit("GB", 1000).unwrap().as_mb(),
 | 
			
		||||
            1000 * 1000
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(FileSize::from_size_unit("GB", 1).unwrap().as_mb(), 1000);
 | 
			
		||||
        assert_eq!(FileSize::from_size_unit("GiB", 3).unwrap().as_mb(), 3221);
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            FileSize::from_size_unit("KiB", 488281).unwrap().as_mb(),
 | 
			
		||||
            499
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,6 @@
 | 
			
		||||
use std::ops::{Div, Mul};
 | 
			
		||||
use std::os::unix::fs::PermissionsExt;
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
 | 
			
		||||
#[derive(thiserror::Error, Debug)]
 | 
			
		||||
enum FilesUtilsError {
 | 
			
		||||
    #[error("UnitConvertError: {0}")]
 | 
			
		||||
    UnitConvert(String),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const INVALID_CHARS: [&str; 19] = [
 | 
			
		||||
    "@", "\\", "/", ":", ",", "<", ">", "%", "'", "\"", "?", "{", "}", "$", "*", "|", ";", "=",
 | 
			
		||||
    "\t",
 | 
			
		||||
@@ -35,31 +28,9 @@ pub fn set_file_permission<P: AsRef<Path>>(path: P, mode: u32) -> anyhow::Result
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Convert size unit to MB
 | 
			
		||||
pub fn convert_size_unit_to_mb(unit: &str, value: usize) -> anyhow::Result<usize> {
 | 
			
		||||
    let fact = match unit {
 | 
			
		||||
        "bytes" | "b" => 1f64,
 | 
			
		||||
        "KB" => 1000f64,
 | 
			
		||||
        "MB" => 1000f64 * 1000f64,
 | 
			
		||||
        "GB" => 1000f64 * 1000f64 * 1000f64,
 | 
			
		||||
        "TB" => 1000f64 * 1000f64 * 1000f64 * 1000f64,
 | 
			
		||||
 | 
			
		||||
        "k" | "KiB" => 1024f64,
 | 
			
		||||
        "M" | "MiB" => 1024f64 * 1024f64,
 | 
			
		||||
        "G" | "GiB" => 1024f64 * 1024f64 * 1024f64,
 | 
			
		||||
        "T" | "TiB" => 1024f64 * 1024f64 * 1024f64 * 1024f64,
 | 
			
		||||
 | 
			
		||||
        _ => {
 | 
			
		||||
            return Err(FilesUtilsError::UnitConvert(format!("Unknown size unit: {unit}")).into());
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Ok((value as f64).mul(fact.div((1000 * 1000) as f64)).ceil() as usize)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test {
 | 
			
		||||
    use crate::utils::files_utils::{check_file_name, convert_size_unit_to_mb};
 | 
			
		||||
    use crate::utils::files_utils::check_file_name;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn empty_file_name() {
 | 
			
		||||
@@ -85,14 +56,4 @@ mod test {
 | 
			
		||||
    fn valid_file_name() {
 | 
			
		||||
        assert!(check_file_name("test.iso"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn convert_units_mb() {
 | 
			
		||||
        assert_eq!(convert_size_unit_to_mb("MB", 1).unwrap(), 1);
 | 
			
		||||
        assert_eq!(convert_size_unit_to_mb("MB", 1000).unwrap(), 1000);
 | 
			
		||||
        assert_eq!(convert_size_unit_to_mb("GB", 1000).unwrap(), 1000 * 1000);
 | 
			
		||||
        assert_eq!(convert_size_unit_to_mb("GB", 1).unwrap(), 1000);
 | 
			
		||||
        assert_eq!(convert_size_unit_to_mb("GiB", 3).unwrap(), 3222);
 | 
			
		||||
        assert_eq!(convert_size_unit_to_mb("KiB", 488281).unwrap(), 500);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user