1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
//! Virtual machine image handling.
use std::fs::copy;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::result::Result;
/// Errors from this module.
#[derive(Debug, thiserror::Error)]
pub enum ImageError {
/// Error resizing image.
#[error("qemu-img resize failed: {0}")]
ResizeError(String),
/// Base image copy error.
#[error("could not copy base image {0} to {1}")]
BaseImageCopy(PathBuf, PathBuf, #[source] std::io::Error),
/// Could not execute command.
#[error("couldn't execute {0}: {1}")]
CommandError(String, #[source] std::io::Error),
/// Error parsing a string as UTF8.
#[error(transparent)]
StringError(#[from] std::string::FromUtf8Error),
}
/// A virtual machine image.
#[derive(Debug, Clone)]
pub struct VirtualMachineImage {
filename: PathBuf,
}
impl VirtualMachineImage {
/// Create new image from a base image.
pub fn new_from_base(base_image: &Path, image: &Path) -> Result<Self, ImageError> {
copy(base_image, image).map_err(|err| {
ImageError::BaseImageCopy(base_image.to_path_buf(), image.to_path_buf(), err)
})?;
Ok(Self {
filename: image.to_path_buf(),
})
}
/// Filename of the image.
pub fn filename(&self) -> &Path {
&self.filename
}
/// Change size of image.
pub fn resize(&self, new_size: u64) -> Result<(), ImageError> {
let r = Command::new("qemu-img")
.arg("resize")
.arg(self.filename())
.arg(format!("{}", new_size))
.output()
.map_err(|err| ImageError::CommandError("qemu-img resize".to_string(), err))?;
if !r.status.success() {
let stderr = String::from_utf8(r.stderr)?;
return Err(ImageError::ResizeError(stderr));
}
Ok(())
}
}
|