photoncloud-monorepo/plasmavmc/crates/plasmavmc-hypervisor/src/backend.rs

145 lines
4.3 KiB
Rust

//! Hypervisor backend trait
use async_trait::async_trait;
use plasmavmc_types::{
AttachedDisk, DiskBus, HypervisorType, NetworkSpec, NicModel, Result, VirtualMachine, VmHandle,
VmSpec, VmStatus,
};
use std::time::Duration;
/// Console type for VM access
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConsoleType {
/// VNC graphical console
Vnc,
/// Serial text console
Serial,
}
/// Reason a feature is not supported
#[derive(Debug, Clone)]
pub enum UnsupportedReason {
/// Disk bus type not supported
DiskBus(DiskBus),
/// NIC model not supported
NicModel(NicModel),
/// Feature not available
Feature(String),
}
/// Backend capabilities
#[derive(Debug, Clone)]
pub struct BackendCapabilities {
/// Supports live migration
pub live_migration: bool,
/// Supports CPU hot-plug
pub hot_plug_cpu: bool,
/// Supports memory hot-plug
pub hot_plug_memory: bool,
/// Supports disk hot-plug
pub hot_plug_disk: bool,
/// Supports NIC hot-plug
pub hot_plug_nic: bool,
/// Supports VNC console
pub vnc_console: bool,
/// Supports serial console
pub serial_console: bool,
/// Supports nested virtualization
pub nested_virtualization: bool,
/// Supports GPU passthrough
pub gpu_passthrough: bool,
/// Maximum vCPUs
pub max_vcpus: u32,
/// Maximum memory in GiB
pub max_memory_gib: u64,
/// Supported disk bus types
pub supported_disk_buses: Vec<DiskBus>,
/// Supported NIC models
pub supported_nic_models: Vec<NicModel>,
}
impl Default for BackendCapabilities {
fn default() -> Self {
Self {
live_migration: false,
hot_plug_cpu: false,
hot_plug_memory: false,
hot_plug_disk: false,
hot_plug_nic: false,
vnc_console: false,
serial_console: true,
nested_virtualization: false,
gpu_passthrough: false,
max_vcpus: 128,
max_memory_gib: 1024,
supported_disk_buses: vec![DiskBus::Virtio],
supported_nic_models: vec![NicModel::VirtioNet],
}
}
}
/// Hypervisor backend trait
///
/// This trait defines the interface that all hypervisor backends must implement.
/// Each backend (KVM, Firecracker, mvisor) provides its own implementation.
#[async_trait]
pub trait HypervisorBackend: Send + Sync {
/// Get the backend type identifier
fn backend_type(&self) -> HypervisorType;
/// Get backend capabilities
fn capabilities(&self) -> BackendCapabilities;
/// Check if this backend supports the given VM spec
fn supports(&self, spec: &VmSpec) -> std::result::Result<(), UnsupportedReason>;
/// Create VM resources (disk, network) without starting
async fn create(&self, vm: &VirtualMachine, disks: &[AttachedDisk]) -> Result<VmHandle>;
/// Start the VM
async fn start(&self, handle: &VmHandle) -> Result<()>;
/// Stop the VM (graceful shutdown)
async fn stop(&self, handle: &VmHandle, timeout: Duration) -> Result<()>;
/// Force stop the VM
async fn kill(&self, handle: &VmHandle) -> Result<()>;
/// Reboot the VM
async fn reboot(&self, handle: &VmHandle) -> Result<()>;
/// Live migrate the VM to a destination URI
async fn migrate(
&self,
handle: &VmHandle,
destination_uri: &str,
timeout: Duration,
wait: bool,
) -> Result<()>;
/// Prepare an incoming migration listener and return a handle
async fn prepare_incoming(
&self,
vm: &VirtualMachine,
listen_uri: &str,
disks: &[AttachedDisk],
) -> Result<VmHandle>;
/// Delete VM and cleanup resources
async fn delete(&self, handle: &VmHandle) -> Result<()>;
/// Get current VM status
async fn status(&self, handle: &VmHandle) -> Result<VmStatus>;
/// Attach a disk to running VM
async fn attach_disk(&self, handle: &VmHandle, disk: &AttachedDisk) -> Result<()>;
/// Detach a disk from running VM
async fn detach_disk(&self, handle: &VmHandle, disk_id: &str) -> Result<()>;
/// Attach a network interface
async fn attach_nic(&self, handle: &VmHandle, nic: &NetworkSpec) -> Result<()>;
/// Detach a network interface
async fn detach_nic(&self, handle: &VmHandle, nic_id: &str) -> Result<()>;
}