Skip to main content

isb_core/spec/
builder.rs

1//! The builder API: `SandboxSpec::new(..).cpus(..)`, `Volume::bind(..)`.
2
3use super::*;
4
5/// Mount builders: `Volume::bind(host)`, `Volume::named(name)`.
6pub struct Volume;
7
8impl Volume {
9    /// Bind-mount a host path. The target is set by [`SandboxSpec::volume`].
10    pub fn bind(host_path: impl Into<String>) -> VolumeSpec {
11        VolumeSpec {
12            mount_type: MountType::Bind,
13            source: host_path.into(),
14            ..Default::default()
15        }
16    }
17
18    /// Mount a named custom volume (created if missing).
19    pub fn named(name: impl Into<String>) -> VolumeSpec {
20        VolumeSpec {
21            mount_type: MountType::Volume,
22            source: name.into(),
23            ..Default::default()
24        }
25    }
26}
27
28impl VolumeSpec {
29    /// Named volumes: the volume must already exist; isb never creates it.
30    pub fn external(mut self, external: bool) -> Self {
31        self.external = external;
32        self
33    }
34    pub fn read_only(mut self, ro: bool) -> Self {
35        self.read_only = ro;
36        self
37    }
38    pub fn owner(mut self, owner: impl Into<String>) -> Self {
39        self.owner = Some(owner.into());
40        self
41    }
42    /// The mount point's octal mode (`"0770"`).
43    pub fn mode(mut self, mode: impl Into<String>) -> Self {
44        self.mode = Some(mode.into());
45        self
46    }
47    pub fn device(mut self, name: impl Into<String>) -> Self {
48        self.device = Some(name.into());
49        self
50    }
51    pub fn pool(mut self, pool: impl Into<String>) -> Self {
52        self.pool = Some(pool.into());
53        self
54    }
55    /// Named volumes: do not seed an empty volume from the image.
56    pub fn nocopy(mut self, nocopy: bool) -> Self {
57        self.volume.nocopy = nocopy;
58        self
59    }
60    pub fn option(mut self, k: impl Into<String>, v: impl Into<String>) -> Self {
61        self.options.insert(k.into(), v.into());
62        self
63    }
64}
65
66/// Port binding builders.
67pub struct PortBinding;
68
69impl PortBinding {
70    /// Publish a guest port on the host: host listens on `listen`, connects to
71    /// `connect` in the guest. Addresses are `tcp:IP:PORT`.
72    pub fn host(listen: impl Into<String>, connect: impl Into<String>) -> PortSpec {
73        PortSpec {
74            bind: PortBind::Host,
75            listen: listen.into(),
76            connect: connect.into(),
77            ..Default::default()
78        }
79    }
80
81    /// Reach a host service from the guest: guest listens on `listen`, host connects to `connect`.
82    pub fn guest(listen: impl Into<String>, connect: impl Into<String>) -> PortSpec {
83        PortSpec {
84            bind: PortBind::Guest,
85            listen: listen.into(),
86            connect: connect.into(),
87            ..Default::default()
88        }
89    }
90}
91
92impl PortSpec {
93    pub fn name(mut self, n: impl Into<String>) -> Self {
94        self.name = Some(n.into());
95        self
96    }
97    pub fn search(mut self, n: u16) -> Self {
98        self.search = Some(n);
99        self
100    }
101}
102
103impl SandboxSpec {
104    pub fn new(name: impl Into<String>, image: impl Into<String>) -> Self {
105        SandboxSpec {
106            name: Some(name.into()),
107            image: image.into(),
108            ..Default::default()
109        }
110    }
111    pub fn cpus(mut self, cpus: impl ToString) -> Self {
112        self.cpus = Some(cpus.to_string());
113        self
114    }
115    pub fn cpuset(mut self, set: impl Into<String>) -> Self {
116        self.cpuset = Some(set.into());
117        self
118    }
119    pub fn memory(mut self, m: impl Into<String>) -> Self {
120        self.memory = Some(m.into());
121        self
122    }
123    pub fn storage(mut self, pool: impl Into<String>) -> Self {
124        self.storage = Some(pool.into());
125        self
126    }
127    pub fn idmap(mut self, idmap: IdmapSpec) -> Self {
128        self.idmap = Some(idmap);
129        self
130    }
131    pub fn privileged(mut self, p: bool) -> Self {
132        self.privileged = Some(p);
133        self
134    }
135    pub fn label(mut self, k: impl Into<String>, v: impl Into<String>) -> Self {
136        self.labels.insert(k.into(), v.into());
137        self
138    }
139    pub fn env(mut self, k: impl Into<String>, v: impl Into<String>) -> Self {
140        self.env.insert(k.into(), v.into());
141        self
142    }
143    /// Restrict the sandbox's network: see [`crate::egress::EgressSpec`].
144    pub fn egress(mut self, e: crate::egress::EgressSpec) -> Self {
145        self.egress = Some(e);
146        self
147    }
148    /// Mount `vol` at `guest_path`.
149    pub fn volume(mut self, guest_path: impl Into<String>, mut vol: VolumeSpec) -> Self {
150        vol.target = guest_path.into();
151        self.volumes.push(vol);
152        self
153    }
154    pub fn port(mut self, p: PortSpec) -> Self {
155        self.ports.push(p);
156        self
157    }
158    pub fn ready(mut self, checks: Vec<ReadyCheck>) -> Self {
159        self.ready = Some(checks);
160        self
161    }
162    pub fn ready_timeout(mut self, t: impl Into<String>) -> Self {
163        self.ready_timeout = Some(t.into());
164        self
165    }
166    pub fn user(mut self, u: impl Into<String>) -> Self {
167        self.user = Some(u.into());
168        self
169    }
170    pub fn working_dir(mut self, c: impl Into<String>) -> Self {
171        self.working_dir = Some(c.into());
172        self
173    }
174    pub fn raw_config(mut self, k: impl Into<String>, v: impl Into<String>) -> Self {
175        self.raw_config.insert(k.into(), v.into());
176        self
177    }
178    pub fn raw_device(mut self, name: impl Into<String>, props: BTreeMap<String, String>) -> Self {
179        self.raw_devices.insert(name.into(), props);
180        self
181    }
182}