Skip to main content

pf_registry/
lib.rs

1// SPDX-License-Identifier: MIT
2//! # `pf-registry`
3//!
4//! Push / pull `.pfimg` artifacts to one of five registry backends. See
5//! `agent_docs/registry-spec.md` for the URL-scheme table and the auth
6//! conventions.
7//!
8//! ## What ships in Phase 9 (this commit)
9//!
10//! - [`image_ref::ImageRef`]: parser for `file://`, `hf://`, `s3://`,
11//!   `ipfs://`, `oci://` URLs.
12//! - [`registry::Registry`] trait + [`registry::RegistryError`].
13//! - [`file::FileRegistry`]: filesystem-backed registry for tests and
14//!   air-gapped use. Round-trips a full `.pfimg` (manifest + every
15//!   referenced layer blob) into a target directory.
16//! - [`hf::HfRegistry`], [`s3::S3Registry`], [`ipfs::IpfsRegistry`]:
17//!   trait surface + URL parsing + `not_yet_implemented` push/pull
18//!   gated behind feature flags. Real implementations land in v1.0.1.
19//! - [`sign::ManifestSignature`] / [`sign::sign_manifest`] /
20//!   [`sign::verify_manifest`]: cosign-shaped signing for the v1
21//!   self-signed mode. Sigstore Fulcio integration is feature-gated
22//!   (`sigstore-keyless`) for v1.1.
23
24#![deny(unsafe_code)]
25#![allow(missing_docs)]
26// documented per-symbol in submodules
27// async_trait emits future-proxy types that clippy quibbles with;
28// these allows scope to the registry crate only.
29// `collapsible_if` was introduced in Rust 1.88's clippy; the
30// transitive-blob walker (registry.rs) deliberately uses staircase
31// `if let Ok(...)` blocks for readability over `let-else`.
32#![allow(
33    clippy::needless_pass_by_value,
34    clippy::module_name_repetitions,
35    clippy::collapsible_if,
36    clippy::collapsible_match
37)]
38
39pub mod file;
40pub mod hf;
41pub mod image_ref;
42pub mod ipfs;
43pub mod oci;
44pub mod registry;
45pub mod s3;
46pub mod sign;
47
48pub use file::FileRegistry;
49pub use hf::HfRegistry;
50pub use image_ref::{ImageRef, ImageRefError};
51pub use ipfs::IpfsRegistry;
52pub use oci::OciRegistry;
53pub use registry::{LayerSet, Registry, RegistryError};
54pub use s3::S3Registry;
55pub use sign::{ManifestSignature, sign_manifest, verify_manifest};
56
57/// Construct a [`Registry`] for a given URL scheme. Returns
58/// `Err(RegistryError::UnsupportedScheme)` for schemes whose
59/// implementation lives behind a feature flag we weren't built with.
60///
61/// `auth` is a key/value bag of credentials (e.g. `{"HF_TOKEN": "..."}`);
62/// adapters consume the entries they recognise and ignore the rest.
63pub fn open(
64    image_ref: &ImageRef,
65    auth: &std::collections::BTreeMap<String, String>,
66) -> Result<Box<dyn Registry>, RegistryError> {
67    match image_ref {
68        ImageRef::File { .. } => Ok(Box::new(FileRegistry::new())),
69        ImageRef::Hf { .. } => Ok(Box::new(HfRegistry::new(auth.get("HF_TOKEN").cloned()))),
70        ImageRef::S3 { .. } => Ok(Box::new(S3Registry::new(auth.clone()))),
71        ImageRef::Ipfs { .. } => Ok(Box::new(IpfsRegistry::new(
72            auth.get("IPFS_API")
73                .cloned()
74                .unwrap_or_else(|| "http://127.0.0.1:5001".into()),
75        ))),
76        ImageRef::Oci { .. } => Ok(Box::new(OciRegistry::new(auth.clone()))),
77    }
78}