use super::GIB;
use super::Image;
use super::ImageStore;
use super::Kernel;
use super::LinuxContainer;
use super::Mount;
use super::VmResources;
use super::linux_container;
use crate::error::Error;
use crate::platform;
use crate::platform::ffi;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct CreateOptions {
pub rootfs_size_in_bytes: u64,
pub writable_layer_size_in_bytes: Option<u64>,
pub read_only: bool,
pub networking: bool,
pub vm: VmResources,
}
impl Default for CreateOptions {
fn default() -> Self {
Self {
rootfs_size_in_bytes: 8 * GIB,
writable_layer_size_in_bytes: None,
read_only: false,
networking: true,
vm: VmResources::default(),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RootfsCreateOptions {
pub writable_layer: Option<Mount>,
pub networking: bool,
pub vm: VmResources,
}
impl Default for RootfsCreateOptions {
fn default() -> Self {
Self {
writable_layer: None,
networking: true,
vm: VmResources::default(),
}
}
}
pub struct ContainerManager {
handle: ffi::CzContainerManager,
}
unsafe impl Send for ContainerManager {}
unsafe impl Sync for ContainerManager {}
impl ContainerManager {
pub fn new(
kernel: &Kernel,
initfs: &Mount,
image_store: &ImageStore,
rosetta: bool,
nested_virtualization: bool,
) -> Result<Self, Error> {
let outcome = platform::outcome(
image_store
.handle
.container_manager(kernel.clone(), initfs.clone(), rosetta, nested_virtualization),
"make a container manager",
)?;
Ok(Self {
handle: outcome.container_manager(),
})
}
pub fn with_initfs_reference(
kernel: &Kernel,
initfs_reference: &str,
image_store: &ImageStore,
rosetta: bool,
nested_virtualization: bool,
) -> Result<Self, Error> {
let outcome = platform::outcome(
image_store.handle.container_manager_with_initfs_reference(
kernel.clone(),
initfs_reference,
rosetta,
nested_virtualization,
),
format!("make a container manager booting {initfs_reference}"),
)?;
Ok(Self {
handle: outcome.container_manager(),
})
}
pub fn create(
&mut self,
id: &str,
image: &Image,
options: CreateOptions,
configuration: impl FnOnce(&mut linux_container::Configuration) + Send + 'static,
) -> Result<LinuxContainer, Error> {
let outcome = self.handle.create(
id,
image.handle.duplicate(),
options,
linux_container::Configuration::default(),
platform::Configure::new(configuration),
);
platform::outcome(outcome, format!("create {id}")).map(|outcome| LinuxContainer {
handle: outcome.linux_container(),
})
}
pub fn create_with_rootfs(
&mut self,
id: &str,
image: &Image,
rootfs: Mount,
options: RootfsCreateOptions,
configuration: impl FnOnce(&mut linux_container::Configuration) + Send + 'static,
) -> Result<LinuxContainer, Error> {
let outcome = self.handle.create_with_rootfs(
id,
image.handle.duplicate(),
rootfs,
options,
linux_container::Configuration::default(),
platform::Configure::new(configuration),
);
platform::outcome(outcome, format!("create {id}")).map(|outcome| LinuxContainer {
handle: outcome.linux_container(),
})
}
pub fn delete(&mut self, id: &str) -> Result<(), Error> {
platform::outcome(self.handle.delete(id), format!("delete {id}")).map(|_| ())
}
}