Skip to main content

sui_cache/
lib.rs

1//! Built-in binary cache server and push pipeline for sui.
2//!
3//! Replaces Attic, Cachix, and nix-serve with a single integrated component.
4//! Implements the standard Nix binary cache HTTP protocol (narinfo + NAR).
5//!
6//! # Architecture
7//!
8//! - [`sui_castore`] — pluggable storage backends (shared with sui-registry);
9//!   re-exported from here for backward compatibility.
10//! - [`server`] — axum HTTP server implementing the cache protocol
11//! - [`signing`] — ed25519 key management and narinfo signing
12//! - [`push`] — pipeline to push store paths to the cache
13//! - [`gc`] — garbage collection of unreferenced cache entries
14//! - [`config`] — cache configuration types (CacheConfig; BackendConfig is in sui-castore)
15
16pub mod config;
17pub mod gc;
18pub mod push;
19pub mod resign;
20pub mod server;
21pub mod signing;
22pub mod watch;
23
24// ---------------------------------------------------------------------------
25// Backward-compatibility re-exports from sui-castore.
26//
27// Every `sui_cache::X` path that existed before the extract-and-dominate
28// refactor continues to resolve — callers need zero changes. The canonical
29// home is now `sui_castore::X`.
30// ---------------------------------------------------------------------------
31
32/// `CacheError` is now `sui_castore::StoreError` (same variants, same derives).
33/// This type alias preserves every existing `sui_cache::CacheError` use site.
34pub use sui_castore::StoreError as CacheError;
35
36pub use config::{CACHE_TIER_ENV, CacheConfig};
37
38// BackendConfig lives in sui-castore; re-export at the sui-cache surface so
39// `sui_cache::BackendConfig` still resolves.
40pub use sui_castore::BackendConfig;
41
42// `${VAR}` config-text expansion also lives in sui-castore; re-export here so
43// `sui cache serve`'s config loader (`sui_cache::expand_env_vars`) can inject a
44// secret-sourced DSN password without the value ever entering the ConfigMap.
45pub use sui_castore::{ExpandEnvError, expand_env_vars};
46
47pub use gc::GcResult;
48pub use push::{LevelOutOfRange, NarCodec, PushResult, XzLevel, ZstdLevel};
49pub use server::{AppState, build_router, serve};
50pub use signing::{CacheSigner, verify_narinfo_signature};
51
52// Storage primitives — all moved to sui-castore, re-exported here.
53pub use sui_castore::{
54    BytesNarSource, DEFAULT_INGEST_MEMORY_CAP, FileNarSource, LocalStorage, MemNarRefIndex,
55    NAR_CHUNK_BYTES, NAR_REF_PREFIX, NarRefIndex, NarRefKey, NarRefScan, NarResidency, NarSource,
56    NarStream, PgCacheConn, PgStorageBackend, PgTable, RedisBackend, RedisConn, S3Storage,
57    SpooledNarSource, StorageBackend, StorageIndex, TIERED_BACKEND_TIER, TieredBackend, TieredTier,
58    WritePolicy, advertised_nar_url, advertised_url_line, build_backend, bytes_stream, collect_nar,
59    empty_stream, file_stream, is_addressable_nar_path, is_servable_narinfo, referrer_of,
60    spool_or_buffer, whole_value_stream,
61};
62
63#[cfg(feature = "redis-client")]
64pub use sui_castore::RedisConnectionManager;
65
66#[cfg(feature = "postgres")]
67pub use sui_castore::SqlxPgCacheConn;
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn cache_error_is_store_error_display() {
75        let e = CacheError::PathNotFound("/nix/store/abc".to_string());
76        assert!(format!("{e}").contains("/nix/store/abc"));
77    }
78
79    #[test]
80    fn cache_error_io_display() {
81        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "missing");
82        let e = CacheError::Io(io_err);
83        assert!(format!("{e}").contains("missing"));
84    }
85
86    #[test]
87    fn cache_error_signing_display() {
88        let e = CacheError::Signing("bad key".to_string());
89        assert!(format!("{e}").contains("bad key"));
90    }
91
92    #[test]
93    fn cache_error_not_implemented_display() {
94        let e = CacheError::NotImplemented("S3");
95        assert!(format!("{e}").contains("S3"));
96    }
97
98    #[test]
99    fn cache_error_narinfo_display() {
100        let e = CacheError::NarInfo("parse failed".to_string());
101        assert!(format!("{e}").contains("parse failed"));
102    }
103}