Skip to main content

vm_rs/driver/
mod.rs

1//! VmDriver trait — platform-agnostic VM lifecycle.
2//!
3//! Two implementations:
4//! - `AppleVzDriver` — macOS via Apple Virtualization.framework
5//! - `CloudHvDriver` — Linux via Cloud Hypervisor REST API
6
7#[cfg(target_os = "macos")]
8pub mod apple_vz;
9
10#[cfg(target_os = "linux")]
11pub mod cloud_hv;
12
13#[cfg(target_os = "windows")]
14pub mod boot;
15
16#[cfg(target_os = "windows")]
17pub mod whp;
18
19#[cfg(any(target_os = "macos", target_os = "linux"))]
20mod ready;
21
22use crate::config::{VmConfig, VmHandle, VmState};
23#[cfg(any(target_os = "macos", target_os = "linux"))]
24pub(crate) use ready::{check_ready_marker, ReadyMarkerCache};
25
26/// Platform-agnostic VM lifecycle.
27///
28/// Apple VZ on macOS, Cloud Hypervisor on Linux.
29/// Each driver manages the hypervisor-specific details of booting,
30/// stopping, and querying VMs.
31pub trait VmDriver: Send + Sync {
32    /// Boot a VM with the given configuration.
33    ///
34    /// Returns a handle that can be used to query state, stop, or kill the VM.
35    /// The VM may still be in `Starting` state when this returns — use
36    /// `state()` to poll for `Running`/`Ready`.
37    fn boot(&self, config: &VmConfig) -> Result<VmHandle, VmError>;
38
39    /// Stop a running VM gracefully.
40    ///
41    /// Sends a shutdown signal and waits for the guest to power off.
42    fn stop(&self, handle: &VmHandle) -> Result<(), VmError>;
43
44    /// Force-kill a VM immediately.
45    ///
46    /// Does not wait for graceful shutdown. Use as a last resort.
47    fn kill(&self, handle: &VmHandle) -> Result<(), VmError>;
48
49    /// Query current VM state.
50    fn state(&self, handle: &VmHandle) -> Result<VmState, VmError>;
51
52    /// Pause a running VM (suspend execution, preserve state).
53    ///
54    /// Not all drivers support pause. The default returns an error.
55    fn pause(&self, handle: &VmHandle) -> Result<(), VmError> {
56        Err(VmError::Hypervisor(format!(
57            "pause is not supported by this driver for VM '{}'",
58            handle.name
59        )))
60    }
61
62    /// Resume a paused VM.
63    ///
64    /// Not all drivers support resume. The default returns an error.
65    fn resume(&self, handle: &VmHandle) -> Result<(), VmError> {
66        Err(VmError::Hypervisor(format!(
67            "resume is not supported by this driver for VM '{}'",
68            handle.name
69        )))
70    }
71}
72
73/// VM operation errors.
74#[derive(Debug, thiserror::Error)]
75pub enum VmError {
76    /// VM boot failed.
77    #[error("boot failed for '{name}': {detail}")]
78    BootFailed { name: String, detail: String },
79
80    /// VM not found (already stopped/destroyed, or never existed).
81    #[error("VM '{name}' not found")]
82    NotFound { name: String },
83
84    /// Stop/kill failed.
85    #[error("failed to stop '{name}': {detail}")]
86    StopFailed { name: String, detail: String },
87
88    /// State query failed.
89    #[error("failed to query state for '{name}': {detail}")]
90    StateFailed { name: String, detail: String },
91
92    /// Hypervisor-specific error (e.g., Apple VZ framework error, Cloud Hypervisor API error).
93    #[error("hypervisor error: {0}")]
94    Hypervisor(String),
95
96    /// I/O error (disk, network, file operations).
97    #[error("I/O error: {0}")]
98    Io(#[from] std::io::Error),
99
100    /// Configuration error.
101    #[error("invalid config: {0}")]
102    InvalidConfig(String),
103}
104
105impl From<crate::oci::registry::OciError> for VmError {
106    fn from(e: crate::oci::registry::OciError) -> Self {
107        VmError::Hypervisor(format!("OCI error: {}", e))
108    }
109}
110
111impl From<crate::setup::SetupError> for VmError {
112    fn from(e: crate::setup::SetupError) -> Self {
113        VmError::Hypervisor(format!("setup error: {}", e))
114    }
115}