1use std::fmt;
9use std::str::FromStr;
10
11use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
20#[serde(rename_all = "kebab-case")]
21pub enum BuilderBackendKind {
22 BuildahCli,
23 BuildahSidecar,
24 Sandbox,
25 Hcs,
26}
27
28impl BuilderBackendKind {
29 #[must_use]
31 pub const fn as_str(self) -> &'static str {
32 match self {
33 Self::BuildahCli => "buildah-cli",
34 Self::BuildahSidecar => "buildah-sidecar",
35 Self::Sandbox => "sandbox",
36 Self::Hcs => "hcs",
37 }
38 }
39}
40
41impl fmt::Display for BuilderBackendKind {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 f.write_str(self.as_str())
44 }
45}
46
47impl FromStr for BuilderBackendKind {
48 type Err = String;
49
50 fn from_str(s: &str) -> Result<Self, Self::Err> {
51 match s.trim().to_ascii_lowercase().as_str() {
52 "buildah-cli" | "buildah" | "cli" => Ok(Self::BuildahCli),
53 "buildah-sidecar" | "sidecar" | "buildd" => Ok(Self::BuildahSidecar),
54 "sandbox" | "macos-sandbox" => Ok(Self::Sandbox),
55 "hcs" | "windows-hcs" => Ok(Self::Hcs),
56 other => Err(format!(
57 "unknown builder backend kind: {other:?} (expected one of: \
58 buildah-cli, buildah-sidecar, sandbox, hcs)"
59 )),
60 }
61 }
62}
63
64#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
71pub struct SidecarConfig {
72 #[serde(skip_serializing_if = "Option::is_none")]
75 pub addr: Option<String>,
76
77 #[serde(skip_serializing_if = "Option::is_none")]
80 pub tls_dir: Option<std::path::PathBuf>,
81
82 #[serde(default = "SidecarConfig::default_idle_secs")]
86 pub idle_secs: u64,
87
88 #[serde(default, skip_serializing_if = "Option::is_none")]
91 pub storage_graph_root: Option<std::path::PathBuf>,
92
93 #[serde(default, skip_serializing_if = "Option::is_none")]
95 pub storage_run_root: Option<std::path::PathBuf>,
96
97 #[serde(default, skip_serializing_if = "Option::is_none")]
100 pub storage_driver: Option<String>,
101
102 #[serde(default, skip_serializing_if = "Option::is_none")]
115 pub context_mount: Option<(std::path::PathBuf, std::path::PathBuf)>,
116}
117
118impl SidecarConfig {
119 pub const DEFAULT_IDLE_SECS: u64 = 30;
120
121 #[must_use]
122 pub fn default_idle_secs() -> u64 {
123 Self::DEFAULT_IDLE_SECS
124 }
125}
126
127impl Default for SidecarConfig {
128 fn default() -> Self {
129 Self {
130 addr: None,
131 tls_dir: None,
132 idle_secs: Self::DEFAULT_IDLE_SECS,
133 storage_graph_root: None,
134 storage_run_root: None,
135 storage_driver: None,
136 context_mount: None,
137 }
138 }
139}
140
141#[derive(Debug, Clone, Default, Serialize, Deserialize)]
147#[allow(clippy::struct_excessive_bools)]
148pub struct BuildSidecarRequest {
149 pub context_dir: String,
150 pub dockerfile_paths: Vec<String>,
151 pub tags: Vec<String>,
152 pub platforms: Vec<String>,
153 pub build_args: std::collections::BTreeMap<String, String>,
154 pub secrets: Vec<String>,
155 pub ssh: Vec<String>,
156 pub target_stage: Option<String>,
157 pub host_network: bool,
158 pub cache_from: Option<String>,
159 pub cache_to: Option<String>,
160 pub no_cache: bool,
161 pub squash: bool,
162 pub layers: bool,
163 pub format: Option<String>,
164 pub pull_policy: Option<String>,
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
172#[serde(tag = "type", rename_all = "snake_case")]
173pub enum BuildSidecarEvent {
174 StageStarted {
175 index: u32,
176 name: Option<String>,
177 base_image: String,
178 },
179 StageFinished {
180 index: u32,
181 },
182 InstructionStarted {
183 stage: u32,
184 index: u32,
185 instruction: String,
186 },
187 InstructionFinished {
188 stage: u32,
189 index: u32,
190 cached: bool,
191 },
192 Log {
193 line: String,
194 is_stderr: bool,
195 },
196 Warning {
197 message: String,
198 },
199 Finished {
200 image_id: String,
201 manifest_ref: Option<String>,
202 },
203 Error {
204 message: String,
205 },
206}
207
208#[cfg(test)]
209mod tests {
210 use super::*;
211
212 #[test]
213 fn backend_kind_round_trips_through_as_str() {
214 for kind in [
215 BuilderBackendKind::BuildahCli,
216 BuilderBackendKind::BuildahSidecar,
217 BuilderBackendKind::Sandbox,
218 BuilderBackendKind::Hcs,
219 ] {
220 assert_eq!(BuilderBackendKind::from_str(kind.as_str()).unwrap(), kind);
221 }
222 }
223
224 #[test]
225 fn backend_kind_accepts_aliases() {
226 assert_eq!(
227 BuilderBackendKind::from_str("buildah").unwrap(),
228 BuilderBackendKind::BuildahCli
229 );
230 assert_eq!(
231 BuilderBackendKind::from_str("sidecar").unwrap(),
232 BuilderBackendKind::BuildahSidecar
233 );
234 assert_eq!(
235 BuilderBackendKind::from_str("BUILDAH-SIDECAR").unwrap(),
236 BuilderBackendKind::BuildahSidecar
237 );
238 }
239
240 #[test]
241 fn sidecar_config_idle_default() {
242 let cfg = SidecarConfig::default();
243 assert_eq!(cfg.idle_secs, 30);
244 assert!(cfg.addr.is_none());
245 assert!(cfg.tls_dir.is_none());
246 assert!(cfg.storage_graph_root.is_none());
247 assert!(cfg.storage_run_root.is_none());
248 assert!(cfg.storage_driver.is_none());
249 }
250}