forge
ExploreLog in

Tahinli/forge

public
0 watching
★ 0
2.6 KiB
1//! The builtin image store: pulls OCI images, unpacks them into rootfs directories and garbage
2//! collects them. Everything lives under one root directory:
3//!
4//! - `blobs/sha256/<hex>`: verified layer blobs, as pulled (compressed)
5//! - `rootfs/<hex>/`: the unpacked rootfs for one manifest digest
6//! - `meta/<hex>.json`: env, working dir, user and layer digests for that rootfs
7//! - `tags/<encoded ref>`: the digest that a reference last resolved to
8//! - `locks/<hex>.lock`: held while an image is pulled or unpacked
9//! - `last_used/<hex>`: a stamp file, touched on every use, for garbage collection
10
11mod helper;
12mod pull;
13mod store;
14pub mod unpack;
15
16use std::fmt;
17use std::path::PathBuf;
18
19pub use helper::unpack_helper_main;
20pub use store::{GcStats, ImageStore};
21pub use unpack::{Ownership, UnpackError, UnpackStats};
22
23/// Errors from pulling, verifying, unpacking or collecting images.
24#[derive(Debug, thiserror::Error)]
25pub enum ImageError {
26 #[error("invalid image reference {image}: {reason}")]
27 InvalidReference { image: String, reason: String },
28 #[error("registry error for {image}: {source}")]
29 Registry {
30 image: String,
31 #[source]
32 source: oci_client::errors::OciDistributionError,
33 },
34 #[error("unsupported or malformed digest {0}, only sha256:<hex> is supported")]
35 UnsupportedDigest(String),
36 #[error("blob digest mismatch: expected {expected}, got {actual}")]
37 DigestMismatch { expected: String, actual: String },
38 #[error("image config or metadata is not valid JSON: {0}")]
39 Json(#[from] serde_json::Error),
40 #[error("{0}")]
41 Unpack(#[from] UnpackError),
42 #[error("I/O error: {0}")]
43 Io(#[from] std::io::Error),
44 #[error("background task failed: {0}")]
45 Task(#[from] tokio::task::JoinError),
46}
47
48/// Basic-auth credentials for a registry. The password is never printed.
49#[derive(Clone)]
50pub struct RegistryAuth {
51 pub username: String,
52 pub password: String,
53}
54
55impl fmt::Debug for RegistryAuth {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 f.debug_struct("RegistryAuth")
58 .field("username", &self.username)
59 .field("password", &"<redacted>")
60 .finish()
61 }
62}
63
64/// An image ready to run: its rootfs directory and the settings from its config.
65#[derive(Debug, Clone, PartialEq, Eq)]
66pub struct PreparedImage {
67 pub rootfs: PathBuf,
68 /// The manifest digest, `sha256:<hex>`.
69 pub digest: String,
70 /// The image config `Env` list, as `NAME=value` strings. Empty when the image sets none.
71 pub env: Vec<String>,
72 pub working_dir: Option<String>,
73 pub user: Option<String>,
74}