Skip to main content

snix_store/
import.rs

1use snix_castore::{
2    blob_engine::BlobEngine, directoryservice::DirectoryService, import::fs::ingest_path,
3};
4use tracing::instrument;
5
6use nix_compat::{
7    nixhash::{CAHash, NixHash},
8    store_path,
9};
10
11use crate::{
12    nar::NarCalculationService,
13    pathinfoservice::{PathInfo, PathInfoService},
14    proto::nar_info,
15};
16
17impl From<CAHash> for nar_info::Ca {
18    fn from(value: CAHash) -> Self {
19        let hash_type: nar_info::ca::Hash = (&value).into();
20        let digest: bytes::Bytes = value.hash().to_string().into();
21        nar_info::Ca {
22            r#type: hash_type.into(),
23            digest,
24        }
25    }
26}
27
28/// Ingest the contents at the given path `path` into castore, and registers the
29/// resulting root node in the passed PathInfoService, using the "NAR sha256
30/// digest" and the passed name for output path calculation.
31///
32/// This inserts the PathInfo into the PathInfoService and returns it back to the caller.
33#[instrument(skip_all, fields(name=%name.as_ref(), path=?path.as_ref()), err)]
34pub async fn import_path_as_nar_ca<BE, DS, PS, NS, P>(
35    path: P,
36    name: impl AsRef<store_path::StorePathName>,
37    blob_engine: BE,
38    directory_service: DS,
39    path_info_service: PS,
40    nar_calculation_service: NS,
41) -> Result<PathInfo, std::io::Error>
42where
43    P: AsRef<std::path::Path>,
44    BE: BlobEngine + Clone,
45    DS: DirectoryService,
46    PS: AsRef<dyn PathInfoService>,
47    NS: NarCalculationService,
48{
49    // Ingest the contents at the given path `path` into castore.
50    let root_node = ingest_path::<_, _, _, &[u8]>(blob_engine, directory_service, path, None)
51        .await
52        .map_err(std::io::Error::other)?;
53
54    // Ask for the NAR size and sha256
55    let (nar_size, nar_sha256) = nar_calculation_service
56        .calculate_nar(&root_node)
57        .await
58        .map_err(std::io::Error::other)?;
59
60    let hash = NixHash::Sha256(nar_sha256);
61
62    // Calculate the output path.
63    let output_path = store_path::build_ca_path(name.as_ref(), true, &hash, [], false);
64
65    // Insert a PathInfo. On success, return it back to the caller.
66    path_info_service
67        .as_ref()
68        .put(PathInfo {
69            store_path: output_path.to_owned(),
70            node: root_node,
71            // There's no reference scanning on imported paths
72            references: vec![],
73            nar_size,
74            nar_sha256,
75            signatures: vec![],
76            deriver: None,
77            ca: Some(CAHash::Nar(hash)),
78        })
79        .await
80        .map_err(std::io::Error::other)
81}