From 5814b0ab6ab3445d3177c176862505f52936a370 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Tue, 27 May 2025 21:42:46 +0200 Subject: [PATCH] Clarify disk structures names --- .../src/libvirt_rest_structures/vm.rs | 10 +++--- virtweb_backend/src/utils/file_disks_utils.rs | 34 ++++++++++--------- virtweb_frontend/src/api/DiskImageApi.ts | 20 +++++++++-- .../src/routes/DiskImagesRoute.tsx | 1 + 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/virtweb_backend/src/libvirt_rest_structures/vm.rs b/virtweb_backend/src/libvirt_rest_structures/vm.rs index 2404f76..3222d10 100644 --- a/virtweb_backend/src/libvirt_rest_structures/vm.rs +++ b/virtweb_backend/src/libvirt_rest_structures/vm.rs @@ -4,7 +4,7 @@ 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_disks_utils::{DiskFormat, FileDisk}; +use crate::utils::file_disks_utils::{VMDiskFormat, VMFileDisk}; use crate::utils::files_utils; use crate::utils::files_utils::convert_size_unit_to_mb; use lazy_regex::regex; @@ -79,7 +79,7 @@ pub struct VMInfo { /// Attach ISO file(s) pub iso_files: Vec, /// File Storage - https://access.redhat.com/documentation/fr-fr/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sect-virtualization-virtualized_block_devices-adding_storage_devices_to_guests#sect-Virtualization-Adding_storage_devices_to_guests-Adding_file_based_storage_to_a_guest - pub file_disks: Vec, + pub file_disks: Vec, /// Network cards pub networks: Vec, /// Add a TPM v2.0 module @@ -289,8 +289,8 @@ impl VMInfo { driver: DiskDriverXML { name: "qemu".to_string(), r#type: match disk.format { - DiskFormat::Raw { .. } => "raw".to_string(), - DiskFormat::QCow2 => "qcow2".to_string(), + VMDiskFormat::Raw { .. } => "raw".to_string(), + VMDiskFormat::QCow2 => "qcow2".to_string(), }, cache: "none".to_string(), }, @@ -467,7 +467,7 @@ impl VMInfo { .disks .iter() .filter(|d| d.device == "disk") - .map(|d| FileDisk::load_from_file(&d.source.file).unwrap()) + .map(|d| VMFileDisk::load_from_file(&d.source.file).unwrap()) .collect(), networks: domain diff --git a/virtweb_backend/src/utils/file_disks_utils.rs b/virtweb_backend/src/utils/file_disks_utils.rs index 32f5b47..fa477df 100644 --- a/virtweb_backend/src/utils/file_disks_utils.rs +++ b/virtweb_backend/src/utils/file_disks_utils.rs @@ -20,7 +20,7 @@ enum DisksError { /// Type of disk allocation #[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize)] -pub enum DiskAllocType { +pub enum VMDiskAllocType { Fixed, Sparse, } @@ -28,28 +28,28 @@ pub enum DiskAllocType { /// Disk allocation type #[derive(serde::Serialize, serde::Deserialize)] #[serde(tag = "format")] -pub enum DiskFormat { +pub enum VMDiskFormat { Raw { /// Type of disk allocation - alloc_type: DiskAllocType, + alloc_type: VMDiskAllocType, }, QCow2, } #[derive(serde::Serialize, serde::Deserialize)] -pub struct FileDisk { +pub struct VMFileDisk { /// Disk name pub name: String, /// Disk size, in bytes pub size: usize, /// Disk format #[serde(flatten)] - pub format: DiskFormat, + pub format: VMDiskFormat, /// Set this variable to true to delete the disk pub delete: bool, } -impl FileDisk { +impl VMFileDisk { pub fn load_from_file(path: &str) -> anyhow::Result { let file = Path::new(path); @@ -66,13 +66,13 @@ impl FileDisk { }, format: match info.format { - DiskFileFormat::Raw { is_sparse } => DiskFormat::Raw { + DiskFileFormat::Raw { is_sparse } => VMDiskFormat::Raw { alloc_type: match is_sparse { - true => DiskAllocType::Sparse, - false => DiskAllocType::Fixed, + true => VMDiskAllocType::Sparse, + false => VMDiskAllocType::Fixed, }, }, - DiskFileFormat::QCow2 { .. } => DiskFormat::QCow2, + DiskFileFormat::QCow2 { .. } => VMDiskFormat::QCow2, _ => anyhow::bail!("Unsupported image format: {:?}", info.format), }, delete: false, @@ -102,8 +102,8 @@ impl FileDisk { pub fn disk_path(&self, id: XMLUuid) -> PathBuf { let domain_dir = AppConfig::get().vm_storage_path(id); let file_name = match self.format { - DiskFormat::Raw { .. } => self.name.to_string(), - DiskFormat::QCow2 => format!("{}.qcow2", self.name), + VMDiskFormat::Raw { .. } => self.name.to_string(), + VMDiskFormat::QCow2 => format!("{}.qcow2", self.name), }; domain_dir.join(&file_name) } @@ -134,15 +134,15 @@ impl FileDisk { // Prepare command to create file let res = match self.format { - DiskFormat::Raw { alloc_type } => { + VMDiskFormat::Raw { alloc_type } => { let mut cmd = Command::new("/usr/bin/dd"); cmd.arg("if=/dev/zero") .arg(format!("of={}", file.to_string_lossy())) .arg("bs=1M"); match alloc_type { - DiskAllocType::Fixed => cmd.arg(format!("count={}", self.size_mb())), - DiskAllocType::Sparse => { + VMDiskAllocType::Fixed => cmd.arg(format!("count={}", self.size_mb())), + VMDiskAllocType::Sparse => { cmd.arg(format!("seek={}", self.size_mb())).arg("count=0") } }; @@ -150,7 +150,7 @@ impl FileDisk { cmd.output()? } - DiskFormat::QCow2 => { + VMDiskFormat::QCow2 => { let mut cmd = Command::new(constants::QEMU_IMAGE_PROGRAM); cmd.arg("create") .arg("-f") @@ -182,6 +182,7 @@ impl FileDisk { } #[derive(Debug, serde::Serialize)] +#[serde(tag = "format")] pub enum DiskFileFormat { Raw { is_sparse: bool }, QCow2 { virtual_size: usize }, @@ -193,6 +194,7 @@ pub enum DiskFileFormat { #[derive(serde::Serialize)] pub struct DiskFileInfo { file_size: usize, + #[serde(flatten)] format: DiskFileFormat, file_name: String, name: String, diff --git a/virtweb_frontend/src/api/DiskImageApi.ts b/virtweb_frontend/src/api/DiskImageApi.ts index 9b36a51..b4f248c 100644 --- a/virtweb_frontend/src/api/DiskImageApi.ts +++ b/virtweb_frontend/src/api/DiskImageApi.ts @@ -1,6 +1,16 @@ import { APIClient } from "./ApiClient"; -export interface DiskImage {} +export type DiskImage = { + file_size: number; + file_name: string; + name: string; + created: number; +} & ( + | { format: "Raw"; is_sparse: boolean } + | { format: "QCow2"; virtual_size: number } + | { format: "CompressedQCow2" } + | { format: "CompressedRaw" } +); export class DiskImageApi { /** @@ -25,7 +35,11 @@ export class DiskImageApi { * Get the list of disk images */ static async GetList(): Promise { - // TODO - return []; + return ( + await APIClient.exec({ + method: "GET", + uri: "/disk_images/list", + }) + ).data; } } diff --git a/virtweb_frontend/src/routes/DiskImagesRoute.tsx b/virtweb_frontend/src/routes/DiskImagesRoute.tsx index 10cd9ec..d1d0b18 100644 --- a/virtweb_frontend/src/routes/DiskImagesRoute.tsx +++ b/virtweb_frontend/src/routes/DiskImagesRoute.tsx @@ -86,6 +86,7 @@ function UploadDiskImageCard(p: { if ( newValue && + newValue.type.length > 0 && !ServerApi.Config.disk_images_mimetypes.includes(newValue.type) ) { alert(`Selected file mimetype is not allowed! (${newValue.type})`);