1use std::collections::BTreeMap;
2use std::path::PathBuf;
3
4use indexmap::IndexMap;
5use serde::Deserialize;
6
7#[derive(Debug, Clone, Deserialize)]
8pub struct Config {
9 pub version: u32,
10
11 #[serde(default)]
12 pub runtime: Option<RuntimeConfig>,
13
14 #[serde(default)]
15 pub workspace: Option<WorkspaceConfig>,
16
17 #[serde(default)]
18 pub identity: Option<IdentityConfig>,
19
20 #[serde(default)]
21 pub image: Option<ImageConfig>,
22
23 #[serde(default)]
24 pub environment: Option<EnvironmentConfig>,
25
26 #[serde(default)]
27 pub mounts: Vec<MountConfig>,
28
29 #[serde(default)]
30 pub caches: Vec<CacheConfig>,
31
32 #[serde(default)]
33 pub secrets: Vec<SecretConfig>,
34
35 #[serde(default)]
36 pub profiles: IndexMap<String, ProfileConfig>,
37
38 #[serde(default)]
39 pub dispatch: IndexMap<String, DispatchRule>,
40
41 #[serde(default)]
42 pub package_manager: Option<PackageManagerConfig>,
43}
44
45#[derive(Debug, Clone, Deserialize)]
48pub struct PackageManagerConfig {
49 pub name: String,
51
52 #[serde(default)]
54 pub install_writable: Option<Vec<String>>,
55
56 #[serde(default)]
58 pub build_writable: Option<Vec<String>>,
59
60 #[serde(default)]
62 pub network_allow: Option<Vec<String>>,
63
64 #[serde(default)]
66 pub pre_run: Option<Vec<String>>,
67}
68
69#[derive(Debug, Clone, Deserialize)]
70#[serde(rename_all = "kebab-case")]
71pub enum BackendKind {
72 Podman,
73 Docker,
74}
75
76#[derive(Debug, Clone, Deserialize)]
77#[serde(rename_all = "kebab-case")]
78pub enum PullPolicy {
79 IfMissing,
80 Always,
81 Never,
82}
83
84#[derive(Debug, Clone, Deserialize)]
85pub struct RuntimeConfig {
86 pub backend: Option<BackendKind>,
87 pub rootless: Option<bool>,
88 pub strict_security: Option<bool>,
89 pub reuse_container: Option<bool>,
90 pub container_name: Option<String>,
91 pub pull_policy: Option<PullPolicy>,
92 pub require_pinned_image: Option<bool>,
93}
94
95#[derive(Debug, Clone, Deserialize)]
96pub struct WorkspaceConfig {
97 pub root: Option<PathBuf>,
98 pub mount: Option<String>,
99 pub writable: Option<bool>,
100 #[serde(default)]
101 pub writable_paths: Vec<String>,
102 #[serde(default)]
105 pub exclude_paths: Vec<String>,
106}
107
108#[derive(Debug, Clone, Deserialize)]
109pub struct IdentityConfig {
110 pub map_user: Option<bool>,
111 pub uid: Option<u32>,
112 pub gid: Option<u32>,
113}
114
115#[derive(Debug, Clone, Deserialize)]
116pub struct ImageConfig {
117 #[serde(rename = "ref")]
118 pub reference: Option<String>,
119 pub build: Option<PathBuf>,
120 pub preset: Option<String>,
121 pub digest: Option<String>,
122 pub verify_signature: Option<bool>,
123 pub pull_policy: Option<PullPolicy>,
124 pub tag: Option<String>,
125}
126
127#[derive(Debug, Clone, Deserialize, Default)]
128pub struct EnvironmentConfig {
129 #[serde(default)]
130 pub pass_through: Vec<String>,
131
132 #[serde(default)]
133 pub set: BTreeMap<String, String>,
134
135 #[serde(default)]
136 pub deny: Vec<String>,
137}
138
139#[derive(Debug, Clone, Deserialize)]
140#[serde(rename_all = "lowercase")]
141pub enum MountType {
142 Bind,
143 Tmpfs,
144}
145
146#[derive(Debug, Clone, Deserialize)]
147pub struct MountConfig {
148 pub source: Option<PathBuf>,
149 pub target: Option<String>,
150 #[serde(rename = "type")]
151 pub mount_type: MountType,
152 pub read_only: Option<bool>,
153 pub create: Option<bool>,
154}
155
156#[derive(Debug, Clone, Deserialize)]
157pub struct CacheConfig {
158 pub name: String,
159 pub target: String,
160 pub source: Option<String>,
161 pub read_only: Option<bool>,
162}
163
164#[derive(Debug, Clone, Deserialize)]
165pub struct SecretConfig {
166 pub name: String,
167 pub source: String,
168 pub target: String,
169
170 #[serde(default)]
173 pub when_profiles: Vec<String>,
174
175 #[serde(default)]
179 pub deny_roles: Vec<ProfileRole>,
180}
181
182#[derive(Debug, Clone, Deserialize)]
183#[serde(rename_all = "lowercase")]
184pub enum ExecutionMode {
185 Host,
186 Sandbox,
187}
188
189#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
191#[serde(rename_all = "kebab-case")]
192pub enum ProfileRole {
193 Install,
194 Run,
195 Build,
196}
197
198#[derive(Debug, Clone, Deserialize, Default)]
200pub struct CapabilitiesConfig {
201 #[serde(default)]
202 pub drop: Vec<String>,
203 #[serde(default)]
204 pub add: Vec<String>,
205}
206
207#[derive(Debug, Clone, Deserialize)]
212#[serde(untagged)]
213pub enum CapabilitiesSpec {
214 Structured(CapabilitiesConfig),
215 List(Vec<String>),
216 Keyword(String),
217}
218
219#[derive(Debug, Clone, Deserialize)]
220pub struct ProfileConfig {
221 pub mode: ExecutionMode,
222 #[serde(default)]
223 pub image: Option<ImageConfig>,
224 pub network: Option<String>,
225 pub writable: Option<bool>,
226 pub require_pinned_image: Option<bool>,
227 pub require_lockfile: Option<bool>,
228
229 pub role: Option<ProfileRole>,
232
233 #[serde(default)]
236 pub lockfile_files: Vec<String>,
237
238 #[serde(default)]
241 pub pre_run: Vec<String>,
242
243 #[serde(default)]
244 pub ports: Vec<String>,
245
246 #[serde(default)]
251 pub network_allow: Vec<String>,
252
253 pub capabilities: Option<CapabilitiesSpec>,
254 pub no_new_privileges: Option<bool>,
255 pub read_only_rootfs: Option<bool>,
256 pub reuse_container: Option<bool>,
257 pub shell: Option<String>,
258
259 pub writable_paths: Option<Vec<String>>,
262}
263
264#[derive(Debug, Clone, Deserialize)]
265pub struct DispatchRule {
266 #[serde(rename = "match", default)]
267 pub patterns: Vec<String>,
268 pub profile: String,
269}