Skip to main content

a3s_box_sdk/bridge/
request.rs

1use std::collections::BTreeMap;
2
3use serde::Deserialize;
4
5use crate::{RegistryCredentials, RegistryProtocol, SignaturePolicy};
6
7use super::{default_depth, default_network_subnet, default_true, BridgeSandboxCreateRequest};
8
9/// Operations supported by this bridge protocol implementation.
10///
11/// Language SDKs use `sdk_capabilities` to fail closed when paired with an
12/// older runtime rather than discovering a missing operation after mutation.
13pub const BRIDGE_OPERATIONS: &[&str] = &[
14    "sdk_capabilities",
15    "runtime_diagnostics",
16    "runtime_disk_usage",
17    "image_build",
18    "image_pull",
19    "image_get",
20    "image_list",
21    "image_inspect",
22    "image_history",
23    "image_tag",
24    "image_push",
25    "image_remove",
26    "image_evict",
27    "volume_create",
28    "volume_get",
29    "volume_list",
30    "volume_remove",
31    "volume_prune",
32    "network_create",
33    "network_get",
34    "network_list",
35    "network_remove",
36    "network_prune",
37    "sandbox_list",
38    "sandbox_get",
39    "sandbox_create",
40    "sandbox_inspect",
41    "sandbox_stop",
42    "sandbox_restart",
43    "sandbox_remove",
44    "sandbox_kill",
45    "sandbox_pause",
46    "sandbox_resume",
47    "sandbox_logs",
48    "sandbox_stats",
49    "sandbox_snapshot_create",
50    "filesystem_snapshot_list",
51    "filesystem_snapshot_get",
52    "filesystem_snapshot_size",
53    "filesystem_snapshot_delete",
54    "command_run",
55    "file_write",
56    "file_read",
57    "filesystem_stat",
58    "filesystem_list",
59    "filesystem_make_dir",
60    "filesystem_move",
61    "filesystem_remove",
62];
63
64#[derive(Debug, Deserialize, PartialEq, Eq)]
65#[serde(tag = "operation", rename_all = "snake_case")]
66pub enum BridgeRequest {
67    SdkCapabilities,
68    RuntimeDiagnostics,
69    RuntimeDiskUsage,
70    ImageBuild {
71        context_dir: String,
72        #[serde(default)]
73        dockerfile: Option<String>,
74        #[serde(default)]
75        tag: Option<String>,
76        #[serde(default)]
77        build_args: BTreeMap<String, String>,
78        #[serde(default = "default_true")]
79        quiet: bool,
80        #[serde(default)]
81        platforms: Vec<String>,
82        #[serde(default)]
83        target: Option<String>,
84        #[serde(default)]
85        no_cache: bool,
86    },
87    ImagePull {
88        reference: String,
89        #[serde(default)]
90        force: bool,
91        #[serde(default)]
92        platform: Option<String>,
93        #[serde(default)]
94        credentials: Option<BridgeRegistryCredentials>,
95        #[serde(default)]
96        signature_policy: BridgeSignaturePolicy,
97    },
98    ImageGet {
99        reference: String,
100    },
101    ImageList,
102    ImageInspect {
103        reference: String,
104    },
105    ImageHistory {
106        reference: String,
107    },
108    ImageTag {
109        source: String,
110        target: String,
111    },
112    ImagePush {
113        source: String,
114        target: String,
115        #[serde(default)]
116        credentials: Option<BridgeRegistryCredentials>,
117        #[serde(default)]
118        registry_protocol: Option<BridgeRegistryProtocol>,
119    },
120    ImageRemove {
121        reference: String,
122    },
123    ImageEvict,
124    VolumeCreate {
125        name: String,
126        #[serde(default)]
127        labels: BTreeMap<String, String>,
128        #[serde(default)]
129        size_limit: u64,
130    },
131    VolumeGet {
132        name: String,
133    },
134    VolumeList,
135    VolumeRemove {
136        name: String,
137        #[serde(default)]
138        force: bool,
139    },
140    VolumePrune,
141    NetworkCreate {
142        name: String,
143        #[serde(default = "default_network_subnet")]
144        subnet: String,
145        #[serde(default)]
146        labels: BTreeMap<String, String>,
147    },
148    NetworkGet {
149        name: String,
150    },
151    NetworkList,
152    NetworkRemove {
153        name: String,
154    },
155    NetworkPrune,
156    SandboxList {
157        #[serde(default = "default_true")]
158        all: bool,
159    },
160    SandboxGet {
161        query: String,
162    },
163    SandboxCreate(Box<BridgeSandboxCreateRequest>),
164    SandboxInspect {
165        sandbox_id: String,
166    },
167    SandboxStop {
168        sandbox_id: String,
169        generation: u64,
170    },
171    SandboxRestart {
172        sandbox_id: String,
173        generation: u64,
174        operation_id: String,
175        #[serde(default)]
176        stop_timeout_seconds: Option<u64>,
177    },
178    SandboxRemove {
179        sandbox_id: String,
180        generation: u64,
181    },
182    SandboxKill {
183        sandbox_id: String,
184        generation: u64,
185    },
186    SandboxPause {
187        sandbox_id: String,
188        generation: u64,
189        #[serde(default = "default_true")]
190        keep_memory: bool,
191    },
192    SandboxResume {
193        sandbox_id: String,
194        generation: u64,
195    },
196    SandboxLogs {
197        sandbox_id: String,
198        generation: u64,
199        #[serde(default = "default_log_tail")]
200        tail: usize,
201    },
202    SandboxStats {
203        sandbox_id: String,
204        generation: u64,
205    },
206    SandboxSnapshotCreate {
207        sandbox_id: String,
208        generation: u64,
209        snapshot_id: String,
210    },
211    FilesystemSnapshotList,
212    FilesystemSnapshotGet {
213        snapshot_id: String,
214    },
215    FilesystemSnapshotSize {
216        snapshot_id: String,
217    },
218    FilesystemSnapshotDelete {
219        snapshot_id: String,
220    },
221    CommandRun {
222        sandbox_id: String,
223        generation: u64,
224        argv: Vec<String>,
225        #[serde(default)]
226        timeout_ms: Option<u64>,
227        #[serde(default)]
228        env: BTreeMap<String, String>,
229        #[serde(default)]
230        cwd: Option<String>,
231        #[serde(default)]
232        user: Option<String>,
233        #[serde(default)]
234        stdin_base64: Option<String>,
235    },
236    FileWrite {
237        sandbox_id: String,
238        generation: u64,
239        path: String,
240        data_base64: String,
241        #[serde(default)]
242        user: Option<String>,
243    },
244    FileRead {
245        sandbox_id: String,
246        generation: u64,
247        path: String,
248        #[serde(default)]
249        user: Option<String>,
250    },
251    FilesystemStat {
252        sandbox_id: String,
253        generation: u64,
254        path: String,
255        #[serde(default)]
256        user: Option<String>,
257    },
258    FilesystemList {
259        sandbox_id: String,
260        generation: u64,
261        path: String,
262        #[serde(default = "default_depth")]
263        depth: u32,
264        #[serde(default)]
265        user: Option<String>,
266    },
267    FilesystemMakeDir {
268        sandbox_id: String,
269        generation: u64,
270        path: String,
271        #[serde(default)]
272        user: Option<String>,
273    },
274    FilesystemMove {
275        sandbox_id: String,
276        generation: u64,
277        path: String,
278        destination: String,
279        #[serde(default)]
280        user: Option<String>,
281    },
282    FilesystemRemove {
283        sandbox_id: String,
284        generation: u64,
285        path: String,
286        #[serde(default)]
287        user: Option<String>,
288    },
289}
290
291impl BridgeRequest {
292    pub const fn operation_name(&self) -> &'static str {
293        match self {
294            Self::SdkCapabilities => "sdk_capabilities",
295            Self::RuntimeDiagnostics => "runtime_diagnostics",
296            Self::RuntimeDiskUsage => "runtime_disk_usage",
297            Self::ImageBuild { .. } => "image_build",
298            Self::ImagePull { .. } => "image_pull",
299            Self::ImageGet { .. } => "image_get",
300            Self::ImageList => "image_list",
301            Self::ImageInspect { .. } => "image_inspect",
302            Self::ImageHistory { .. } => "image_history",
303            Self::ImageTag { .. } => "image_tag",
304            Self::ImagePush { .. } => "image_push",
305            Self::ImageRemove { .. } => "image_remove",
306            Self::ImageEvict => "image_evict",
307            Self::VolumeCreate { .. } => "volume_create",
308            Self::VolumeGet { .. } => "volume_get",
309            Self::VolumeList => "volume_list",
310            Self::VolumeRemove { .. } => "volume_remove",
311            Self::VolumePrune => "volume_prune",
312            Self::NetworkCreate { .. } => "network_create",
313            Self::NetworkGet { .. } => "network_get",
314            Self::NetworkList => "network_list",
315            Self::NetworkRemove { .. } => "network_remove",
316            Self::NetworkPrune => "network_prune",
317            Self::SandboxList { .. } => "sandbox_list",
318            Self::SandboxGet { .. } => "sandbox_get",
319            Self::SandboxCreate(_) => "sandbox_create",
320            Self::SandboxInspect { .. } => "sandbox_inspect",
321            Self::SandboxStop { .. } => "sandbox_stop",
322            Self::SandboxRestart { .. } => "sandbox_restart",
323            Self::SandboxRemove { .. } => "sandbox_remove",
324            Self::SandboxKill { .. } => "sandbox_kill",
325            Self::SandboxPause { .. } => "sandbox_pause",
326            Self::SandboxResume { .. } => "sandbox_resume",
327            Self::SandboxLogs { .. } => "sandbox_logs",
328            Self::SandboxStats { .. } => "sandbox_stats",
329            Self::SandboxSnapshotCreate { .. } => "sandbox_snapshot_create",
330            Self::FilesystemSnapshotList => "filesystem_snapshot_list",
331            Self::FilesystemSnapshotGet { .. } => "filesystem_snapshot_get",
332            Self::FilesystemSnapshotSize { .. } => "filesystem_snapshot_size",
333            Self::FilesystemSnapshotDelete { .. } => "filesystem_snapshot_delete",
334            Self::CommandRun { .. } => "command_run",
335            Self::FileWrite { .. } => "file_write",
336            Self::FileRead { .. } => "file_read",
337            Self::FilesystemStat { .. } => "filesystem_stat",
338            Self::FilesystemList { .. } => "filesystem_list",
339            Self::FilesystemMakeDir { .. } => "filesystem_make_dir",
340            Self::FilesystemMove { .. } => "filesystem_move",
341            Self::FilesystemRemove { .. } => "filesystem_remove",
342        }
343    }
344}
345
346const fn default_log_tail() -> usize {
347    100
348}
349
350#[derive(Debug, Deserialize, PartialEq, Eq)]
351pub struct BridgeRegistryCredentials {
352    pub(super) username: String,
353    pub(super) password: String,
354}
355
356impl From<BridgeRegistryCredentials> for RegistryCredentials {
357    fn from(value: BridgeRegistryCredentials) -> Self {
358        Self::basic(value.username, value.password)
359    }
360}
361
362#[derive(Debug, Default, Deserialize, PartialEq, Eq)]
363#[serde(tag = "mode", rename_all = "snake_case")]
364pub enum BridgeSignaturePolicy {
365    #[default]
366    Skip,
367    CosignKey {
368        public_key: String,
369    },
370    CosignKeyless {
371        issuer: String,
372        identity: String,
373    },
374}
375
376impl From<BridgeSignaturePolicy> for SignaturePolicy {
377    fn from(value: BridgeSignaturePolicy) -> Self {
378        match value {
379            BridgeSignaturePolicy::Skip => Self::Skip,
380            BridgeSignaturePolicy::CosignKey { public_key } => Self::CosignKey { public_key },
381            BridgeSignaturePolicy::CosignKeyless { issuer, identity } => {
382                Self::CosignKeyless { issuer, identity }
383            }
384        }
385    }
386}
387
388#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Eq)]
389#[serde(rename_all = "snake_case")]
390pub enum BridgeRegistryProtocol {
391    Https,
392    Http,
393}
394
395impl From<BridgeRegistryProtocol> for RegistryProtocol {
396    fn from(value: BridgeRegistryProtocol) -> Self {
397        match value {
398            BridgeRegistryProtocol::Https => Self::Https,
399            BridgeRegistryProtocol::Http => Self::Http,
400        }
401    }
402}