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    pub fn device(mut self, name: impl Into<String>) -> Self {
43        self.device = Some(name.into());
44        self
45    }
46    pub fn pool(mut self, pool: impl Into<String>) -> Self {
47        self.pool = Some(pool.into());
48        self
49    }
50    /// Named volumes: do not seed an empty volume from the image.
51    pub fn nocopy(mut self, nocopy: bool) -> Self {
52        self.volume.nocopy = nocopy;
53        self
54    }
55    pub fn option(mut self, k: impl Into<String>, v: impl Into<String>) -> Self {
56        self.options.insert(k.into(), v.into());
57        self
58    }
59}
60
61/// Port binding builders.
62pub struct PortBinding;
63
64impl PortBinding {
65    /// Publish a guest port on the host: host listens on `listen`, connects to
66    /// `connect` in the guest. Addresses are `tcp:IP:PORT`.
67    pub fn host(listen: impl Into<String>, connect: impl Into<String>) -> PortSpec {
68        PortSpec {
69            bind: PortBind::Host,
70            listen: listen.into(),
71            connect: connect.into(),
72            ..Default::default()
73        }
74    }
75
76    /// Reach a host service from the guest: guest listens on `listen`, host connects to `connect`.
77    pub fn guest(listen: impl Into<String>, connect: impl Into<String>) -> PortSpec {
78        PortSpec {
79            bind: PortBind::Guest,
80            listen: listen.into(),
81            connect: connect.into(),
82            ..Default::default()
83        }
84    }
85}
86
87impl PortSpec {
88    pub fn name(mut self, n: impl Into<String>) -> Self {
89        self.name = Some(n.into());
90        self
91    }
92    pub fn search(mut self, n: u16) -> Self {
93        self.search = Some(n);
94        self
95    }
96}
97
98impl SandboxSpec {
99    pub fn new(name: impl Into<String>, image: impl Into<String>) -> Self {
100        SandboxSpec {
101            name: Some(name.into()),
102            image: image.into(),
103            ..Default::default()
104        }
105    }
106    pub fn cpus(mut self, cpus: impl ToString) -> Self {
107        self.cpus = Some(cpus.to_string());
108        self
109    }
110    pub fn cpuset(mut self, set: impl Into<String>) -> Self {
111        self.cpuset = Some(set.into());
112        self
113    }
114    pub fn memory(mut self, m: impl Into<String>) -> Self {
115        self.memory = Some(m.into());
116        self
117    }
118    pub fn storage(mut self, pool: impl Into<String>) -> Self {
119        self.storage = Some(pool.into());
120        self
121    }
122    pub fn idmap(mut self, idmap: IdmapSpec) -> Self {
123        self.idmap = Some(idmap);
124        self
125    }
126    pub fn privileged(mut self, p: bool) -> Self {
127        self.privileged = Some(p);
128        self
129    }
130    pub fn label(mut self, k: impl Into<String>, v: impl Into<String>) -> Self {
131        self.labels.insert(k.into(), v.into());
132        self
133    }
134    pub fn env(mut self, k: impl Into<String>, v: impl Into<String>) -> Self {
135        self.env.insert(k.into(), v.into());
136        self
137    }
138    /// Restrict the sandbox's network: see [`crate::egress::EgressSpec`].
139    pub fn egress(mut self, e: crate::egress::EgressSpec) -> Self {
140        self.egress = Some(e);
141        self
142    }
143    /// Mount `vol` at `guest_path`.
144    pub fn volume(mut self, guest_path: impl Into<String>, mut vol: VolumeSpec) -> Self {
145        vol.target = guest_path.into();
146        self.volumes.push(vol);
147        self
148    }
149    pub fn port(mut self, p: PortSpec) -> Self {
150        self.ports.push(p);
151        self
152    }
153    pub fn ready(mut self, checks: Vec<ReadyCheck>) -> Self {
154        self.ready = Some(checks);
155        self
156    }
157    pub fn ready_timeout(mut self, t: impl Into<String>) -> Self {
158        self.ready_timeout = Some(t.into());
159        self
160    }
161    pub fn user(mut self, u: impl Into<String>) -> Self {
162        self.user = Some(u.into());
163        self
164    }
165    pub fn working_dir(mut self, c: impl Into<String>) -> Self {
166        self.working_dir = Some(c.into());
167        self
168    }
169    pub fn raw_config(mut self, k: impl Into<String>, v: impl Into<String>) -> Self {
170        self.raw_config.insert(k.into(), v.into());
171        self
172    }
173    pub fn raw_device(mut self, name: impl Into<String>, props: BTreeMap<String, String>) -> Self {
174        self.raw_devices.insert(name.into(), props);
175        self
176    }
177}