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