sbox/
container.rs

1use std::fs::create_dir_all;
2use std::path::PathBuf;
3use std::sync::Arc;
4
5use crate::{Cgroup, Mount, NetworkManager, UserMapper};
6
7pub type Error = Box<dyn std::error::Error + Send + Sync>;
8
9#[derive(Clone, Debug, Default)]
10pub struct ContainerOptions {
11    rootfs: Option<PathBuf>,
12    cgroup: Option<Cgroup>,
13    user_mapper: Option<Arc<dyn UserMapper>>,
14    network_manager: Option<Arc<dyn NetworkManager>>,
15    mounts: Vec<Arc<dyn Mount>>,
16    hostname: String,
17}
18
19impl ContainerOptions {
20    pub fn new() -> Self {
21        Default::default()
22    }
23
24    pub fn rootfs(mut self, rootfs: PathBuf) -> Self {
25        self.rootfs = Some(rootfs);
26        self
27    }
28
29    pub fn cgroup(mut self, cgroup: Cgroup) -> Self {
30        self.cgroup = Some(cgroup);
31        self
32    }
33
34    pub fn user_mapper<T: UserMapper + 'static>(mut self, user_mapper: T) -> Self {
35        self.user_mapper = Some(Arc::new(user_mapper));
36        self
37    }
38
39    pub fn network_manager<T: NetworkManager + 'static>(mut self, network_manager: T) -> Self {
40        self.network_manager = Some(Arc::new(network_manager));
41        self
42    }
43
44    pub fn add_mount<T: Mount + 'static>(mut self, mount: T) -> Self {
45        self.mounts.push(Arc::new(mount));
46        self
47    }
48
49    pub fn hostname<T: ToString>(mut self, hostname: T) -> Self {
50        self.hostname = hostname.to_string();
51        self
52    }
53
54    pub fn create(self) -> Result<Container, Error> {
55        let rootfs = self.rootfs.ok_or("Container rootfs should specified")?;
56        let cgroup = self.cgroup.ok_or("Container cgroup should specified")?;
57        let user_mapper = self
58            .user_mapper
59            .ok_or("Container user mapper should specified")?;
60        let network_manager = self.network_manager;
61        let mounts = self.mounts;
62        let hostname = self.hostname;
63        create_dir_all(&rootfs)?;
64        cgroup.create()?;
65        Ok(Container {
66            rootfs,
67            cgroup,
68            user_mapper,
69            network_manager,
70            mounts,
71            hostname,
72        })
73    }
74}
75
76pub struct Container {
77    pub(super) rootfs: PathBuf,
78    pub(super) cgroup: Cgroup,
79    pub(super) user_mapper: Arc<dyn UserMapper>,
80    pub(super) network_manager: Option<Arc<dyn NetworkManager>>,
81    pub(super) mounts: Vec<Arc<dyn Mount>>,
82    pub(super) hostname: String,
83}
84
85impl Container {
86    pub fn options() -> ContainerOptions {
87        ContainerOptions::new()
88    }
89}