Can resize disk image when adding a new disk image to a VM
	
		
			
	
		
	
	
		
	
		
			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:
		@@ -394,6 +394,40 @@ impl DiskFileInfo {
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Get disk virtual size, if available
 | 
			
		||||
    pub fn virtual_size(&self) -> Option<FileSize> {
 | 
			
		||||
        match self.format {
 | 
			
		||||
            DiskFileFormat::Raw { .. } => Some(self.file_size),
 | 
			
		||||
            DiskFileFormat::QCow2 { virtual_size } => Some(virtual_size),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Resize disk
 | 
			
		||||
    pub fn resize(&self, new_size: FileSize) -> anyhow::Result<()> {
 | 
			
		||||
        let mut cmd = Command::new(constants::PROGRAM_QEMU_IMAGE);
 | 
			
		||||
        cmd.arg("resize")
 | 
			
		||||
            .arg("-f")
 | 
			
		||||
            .arg(match self.format {
 | 
			
		||||
                DiskFileFormat::QCow2 { .. } => "qcow2",
 | 
			
		||||
                DiskFileFormat::Raw { .. } => "raw",
 | 
			
		||||
                f => anyhow::bail!("Unsupported disk format for resize: {f:?}"),
 | 
			
		||||
            })
 | 
			
		||||
            .arg(&self.file_path)
 | 
			
		||||
            .arg(new_size.as_bytes().to_string());
 | 
			
		||||
 | 
			
		||||
        let output = cmd.output()?;
 | 
			
		||||
        if !output.status.success() {
 | 
			
		||||
            anyhow::bail!(
 | 
			
		||||
                "{} info failed, status: {}, stderr: {}",
 | 
			
		||||
                constants::PROGRAM_QEMU_IMAGE,
 | 
			
		||||
                output.status,
 | 
			
		||||
                String::from_utf8_lossy(&output.stderr)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize)]
 | 
			
		||||
 
 | 
			
		||||
@@ -44,6 +44,9 @@ pub struct VMFileDisk {
 | 
			
		||||
    /// When creating a new disk, specify the disk image template to use
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    pub from_image: Option<String>,
 | 
			
		||||
    /// Set this variable to true to resize disk image
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    pub resize: Option<bool>,
 | 
			
		||||
    /// Set this variable to true to delete the disk
 | 
			
		||||
    pub delete: bool,
 | 
			
		||||
}
 | 
			
		||||
@@ -78,6 +81,7 @@ impl VMFileDisk {
 | 
			
		||||
 | 
			
		||||
            delete: false,
 | 
			
		||||
            from_image: None,
 | 
			
		||||
            resize: None,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -144,28 +148,40 @@ impl VMFileDisk {
 | 
			
		||||
 | 
			
		||||
        if file.exists() {
 | 
			
		||||
            log::debug!("File {file:?} does not exists, so it was not touched");
 | 
			
		||||
            return Ok(());
 | 
			
		||||
        }
 | 
			
		||||
        // Create disk if required
 | 
			
		||||
        else {
 | 
			
		||||
            // Determine file format
 | 
			
		||||
            let format = match self.format {
 | 
			
		||||
                VMDiskFormat::Raw { is_sparse } => DiskFileFormat::Raw { is_sparse },
 | 
			
		||||
                VMDiskFormat::QCow2 => DiskFileFormat::QCow2 {
 | 
			
		||||
                    virtual_size: self.size,
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Create / Restore disk file
 | 
			
		||||
            match &self.from_image {
 | 
			
		||||
                // Create disk file
 | 
			
		||||
                None => {
 | 
			
		||||
                    DiskFileInfo::create(&file, format, self.size)?;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Restore disk image template
 | 
			
		||||
                Some(disk_img) => {
 | 
			
		||||
                    let src_file =
 | 
			
		||||
                        DiskFileInfo::load_file(&AppConfig::get().disk_images_file_path(disk_img))?;
 | 
			
		||||
                    src_file.convert(&file, format)?;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let format = match self.format {
 | 
			
		||||
            VMDiskFormat::Raw { is_sparse } => DiskFileFormat::Raw { is_sparse },
 | 
			
		||||
            VMDiskFormat::QCow2 => DiskFileFormat::QCow2 {
 | 
			
		||||
                virtual_size: self.size,
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
        // Resize disk file if requested
 | 
			
		||||
        if self.resize == Some(true) {
 | 
			
		||||
            let disk = DiskFileInfo::load_file(&file)?;
 | 
			
		||||
 | 
			
		||||
        // Create / Restore disk file
 | 
			
		||||
        match &self.from_image {
 | 
			
		||||
            // Create disk file
 | 
			
		||||
            None => {
 | 
			
		||||
                DiskFileInfo::create(&file, format, self.size)?;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Restore disk image template
 | 
			
		||||
            Some(disk_img) => {
 | 
			
		||||
                let src_file =
 | 
			
		||||
                    DiskFileInfo::load_file(&AppConfig::get().disk_images_file_path(disk_img))?;
 | 
			
		||||
                src_file.convert(&file, format)?;
 | 
			
		||||
            // Can only increase disk size
 | 
			
		||||
            if let Err(e) = disk.resize(self.size) {
 | 
			
		||||
                log::error!("Failed to resize disk file {}: {e:?}", self.name);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user