use crate::containerization::strings;
use crate::error::Error;
use crate::platform;
use crate::platform::ffi;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum RuntimeOptions {
Virtioblk(Vec<String>),
Virtiofs(Vec<String>),
Shared,
Any(Vec<String>),
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Mount {
pub r#type: String,
pub source: String,
pub destination: String,
pub options: Vec<String>,
pub runtime_options: RuntimeOptions,
}
impl Mount {
pub fn share(
source: impl Into<String>,
destination: impl Into<String>,
options: &[&str],
runtime_options: &[&str],
) -> Self {
Self {
r#type: "virtiofs".to_string(),
source: source.into(),
destination: destination.into(),
options: strings(options),
runtime_options: RuntimeOptions::Virtiofs(strings(runtime_options)),
}
}
pub fn block(
format: impl Into<String>,
source: impl Into<String>,
destination: impl Into<String>,
options: &[&str],
runtime_options: &[&str],
) -> Self {
Self {
r#type: format.into(),
source: source.into(),
destination: destination.into(),
options: strings(options),
runtime_options: RuntimeOptions::Virtioblk(strings(runtime_options)),
}
}
pub fn any(
r#type: impl Into<String>,
source: impl Into<String>,
destination: impl Into<String>,
options: &[&str],
runtime_options: &[&str],
) -> Self {
Self {
r#type: r#type.into(),
source: source.into(),
destination: destination.into(),
options: strings(options),
runtime_options: RuntimeOptions::Any(strings(runtime_options)),
}
}
pub fn shared_mount(name: impl Into<String>, destination: impl Into<String>, options: &[&str]) -> Self {
Self {
r#type: "none".to_string(),
source: name.into(),
destination: destination.into(),
options: strings(options),
runtime_options: RuntimeOptions::Shared,
}
}
pub fn clone_to(&self, to: &str) -> Result<Self, Error> {
platform::outcome(
ffi::cz_mount_clone(self.clone(), to),
format!("copy {} to {to}", self.source),
)
.map(|outcome| outcome.mount())
}
pub fn is_block(&self) -> bool {
matches!(self.runtime_options, RuntimeOptions::Virtioblk(_))
}
pub fn tag_hash(&self) -> Result<String, Error> {
platform::outcome(ffi::cz_mount_tag_hash(self.clone()), format!("hash {}", self.source))
.map(|outcome| outcome.text())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builds_mounts_of_each_kind() {
let share = Mount::share("/Users/user/workspace", "/workspace", &["ro"], &[]);
assert_eq!(share.r#type, "virtiofs");
assert_eq!(share.options, ["ro"]);
assert_eq!(share.runtime_options, RuntimeOptions::Virtiofs(vec![]));
assert_eq!(
Mount::block("ext4", "/images/data.ext4", "/data", &[], &["vda"]).runtime_options,
RuntimeOptions::Virtioblk(vec!["vda".into()])
);
assert_eq!(
Mount::any("tmpfs", "tmpfs", "/scratch", &[], &[]).runtime_options,
RuntimeOptions::Any(vec![])
);
}
}