//! 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, /// Supported NIC models pub supported_nic_models: Vec, } 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; /// 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; /// Delete VM and cleanup resources async fn delete(&self, handle: &VmHandle) -> Result<()>; /// Get current VM status async fn status(&self, handle: &VmHandle) -> Result; /// 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<()>; }