use crate::GlobalsFinal;
use anyhow::Result as AResult;
use serde::Deserialize;
use std::collections::HashMap;
use std::iter::Iterator;
use std::path::{Path, PathBuf};
#[derive(Deserialize)]
struct RawConfig {
sandbox: SandBoxConfig,
}
#[derive(Deserialize)]
struct SandBoxConfig {
command: String,
#[serde(rename = "tmpfs-size")]
tmpfs_size: Option<usize>,
mounts: MountConfig,
}
#[derive(Deserialize)]
struct MountConfig {
repos: HashMap<String, String>,
files: Option<Vec<FileMounts>>,
}
#[derive(Deserialize)]
struct FileMounts {
src: String,
dest: String,
}
#[derive(Debug)]
pub(super) struct ModConfig {
pub(super) command: String,
pub(super) tmpfs_size: usize,
repos: Vec<(PathBuf, PathBuf)>,
files: Vec<(PathBuf, PathBuf)>,
}
impl ModConfig {
pub(super) fn new(globals: &GlobalsFinal) -> AResult<Self> {
let repopath = Path::new("/var/db/repos");
let raw: RawConfig = toml::from_str(globals.text())?;
let command = raw.sandbox.command;
let tmpfs_size = raw.sandbox.tmpfs_size.unwrap_or_default();
let repos = raw
.sandbox
.mounts
.repos
.into_iter()
.map(|(key, val)| (globals.resolve_path(&val), repopath.join(key)))
.collect();
let files = raw
.sandbox
.mounts
.files
.unwrap_or_default()
.into_iter()
.map(|file| {
(
globals.resolve_path(&file.src),
globals.resolve_path(&file.dest),
)
})
.collect();
Ok(Self {
command,
tmpfs_size,
repos,
files,
})
}
pub(super) fn mountpaths(&self) -> AResult<impl Iterator<Item = &(PathBuf, PathBuf)> + '_> {
for (src, _) in &self.repos {
anyhow::ensure!(src.is_dir(), "Repository {} not found", src.display());
}
for (src, _) in &self.files {
anyhow::ensure!(src.is_file(), "Source file {} not found", src.display());
}
let itr = self.repos.iter().chain(self.files.iter());
Ok(itr)
}
}