summaryrefslogtreecommitdiff
path: root/src/image.rs
blob: 62f80f773c44e92f952d49e449e54d2b8265a717 (plain)
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
//! 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),

    /// I/O error.
    #[error(transparent)]
    IoError(#[from] 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)?;
        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()?;
        if !r.status.success() {
            let stderr = String::from_utf8(r.stderr)?;
            return Err(ImageError::ResizeError(stderr));
        }
        Ok(())
    }
}