| 1 | //! Docker in a workflow job on g1t's own machines: a Docker Engine of the |
| 2 | //! job's own, inside its sandbox, started the first time anything asks |
| 3 | //! for it, and gone with the sandbox when the job ends. |
| 4 | //! |
| 5 | //! - `engine` starts it, as root inside the sandbox (as Cloudflare |
| 6 | //! Containers run Docker), with no iptables and no IP forwarding, which |
| 7 | //! a sandbox does not have. |
| 8 | //! - `api` is `/var/run/docker.sock`: the Engine's API, with containers |
| 9 | //! moved to the job's own network, where its guardrails apply. |
| 10 | //! - `oci` is the `runc` the Engine runs containers with: build steps on |
| 11 | //! the job's network, and a guarded job's egress certificate in every |
| 12 | //! container. |
| 13 | //! - `http` is the HTTP/1.1 the proxy reads. |
| 14 | //! |
| 15 | //! Nothing here is shared with another job: each job has its own sandbox, |
| 16 | //! and so its own Engine, images and build cache. |
| 17 | |
| 18 | // Off g1t's Linux machines only the pure parts are used, by tests. |
| 19 | #![cfg_attr(not(target_os = "linux"), allow(dead_code))] |
| 20 | |
| 21 | pub(crate) mod api; |
| 22 | pub(crate) mod engine; |
| 23 | pub(crate) mod http; |
| 24 | pub(crate) mod oci; |
| 25 | |
| 26 | use std::sync::Mutex; |
| 27 | |
| 28 | /// Lines for the job's log, from threads that do not hold it: the Engine |
| 29 | /// starting, a port that could not be forwarded. |
| 30 | static NOTES: Mutex<Vec<String>> = Mutex::new(Vec::new()); |
| 31 | |
| 32 | pub(crate) fn note(line: impl Into<String>) { |
| 33 | if let Ok(mut notes) = NOTES.lock() { |
| 34 | notes.push(line.into()); |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | /// The lines noted since the last call. |
| 39 | pub(crate) fn take_notes() -> Vec<String> { |
| 40 | NOTES.lock().map(|mut notes| std::mem::take(&mut *notes)).unwrap_or_default() |
| 41 | } |