use super::AttachedFilesystem;
use super::VirtiofsLayout;
use super::VirtualMachineInstanceState;
use super::VsockListener;
use crate::containerization::container::Mount;
use crate::error::Error;
use crate::platform;
use crate::platform::ffi;
use std::collections::BTreeMap;
use std::fmt;
use std::os::fd::FromRawFd;
use std::os::fd::OwnedFd;
pub struct VzVirtualMachineInstance {
pub(crate) handle: ffi::CzVirtualMachineInstance,
}
unsafe impl Send for VzVirtualMachineInstance {}
unsafe impl Sync for VzVirtualMachineInstance {}
impl VzVirtualMachineInstance {
pub fn state(&self) -> VirtualMachineInstanceState {
self.handle.state().into()
}
pub fn mounts(&self) -> BTreeMap<String, Vec<AttachedFilesystem>> {
self.handle.mounts().attached_filesystems_by_id()
}
pub fn virtiofs_layout(&self) -> VirtiofsLayout {
self.handle.virtiofs_layout().into()
}
pub fn start(&self) -> Result<(), Error> {
platform::outcome(self.handle.start(), "start the virtual machine").map(drop)
}
pub fn stop(&self) -> Result<(), Error> {
platform::outcome(self.handle.stop(), "stop the virtual machine").map(drop)
}
pub fn pause(&self) -> Result<(), Error> {
platform::outcome(self.handle.pause(), "pause the virtual machine").map(drop)
}
pub fn resume(&self) -> Result<(), Error> {
platform::outcome(self.handle.resume(), "resume the virtual machine").map(drop)
}
pub fn dial(&self, port: u32) -> Result<OwnedFd, Error> {
platform::outcome(self.handle.dial(port), format!("dial vsock port {port}"))
.map(|outcome| unsafe { OwnedFd::from_raw_fd(outcome.int32()) })
}
pub fn listen(&self, port: u32) -> Result<VsockListener, Error> {
platform::outcome(self.handle.listen(port), format!("listen on vsock port {port}")).map(|outcome| VsockListener {
handle: outcome.vsock_listener(),
})
}
pub fn hotplug(&self, block: Mount, id: &str) -> Result<AttachedFilesystem, Error> {
platform::outcome(self.handle.hotplug(block, id), format!("hotplug a block for {id}"))
.map(|outcome| outcome.attached_filesystem())
}
pub fn register_mounts(
&self,
id: &str,
rootfs: AttachedFilesystem,
additional_mounts: Vec<Mount>,
) -> Result<(), Error> {
platform::outcome(
self.handle.register_mounts(id, rootfs, additional_mounts),
format!("register {id}'s mounts"),
)
.map(drop)
}
pub fn release_hotplug(&self, id: &str) -> Result<(), Error> {
platform::outcome(self.handle.release_hotplug(id), format!("release {id}'s hotplug")).map(drop)
}
pub fn hotplug_virtio_fs(&self, mounts: Vec<Mount>, id: &str) -> Result<(), Error> {
platform::outcome(
self.handle.hotplug_virtio_fs(mounts, id),
format!("hotplug {id}'s shares"),
)
.map(drop)
}
pub fn release_virtio_fs(&self, id: &str) -> Result<(), Error> {
platform::outcome(self.handle.release_virtio_fs(id), format!("release {id}'s shares")).map(drop)
}
pub fn install_rosetta() -> Result<(), Error> {
platform::outcome(ffi::cz_install_rosetta(), "install Rosetta").map(drop)
}
}
impl fmt::Debug for VzVirtualMachineInstance {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("VzVirtualMachineInstance")
.field("state", &self.state())
.finish_non_exhaustive()
}
}