2024-04-16 01:53:44 -07:00
|
|
|
use crate::{
|
|
|
|
packer::{OciPackedFormat, OciPackedImage},
|
|
|
|
schema::OciSchema,
|
|
|
|
};
|
2024-04-14 17:19:38 -07:00
|
|
|
|
2024-03-05 11:35:25 +00:00
|
|
|
use anyhow::Result;
|
2024-01-18 00:02:21 -08:00
|
|
|
use log::debug;
|
2024-01-18 00:15:36 -08:00
|
|
|
use oci_spec::image::{ImageConfiguration, ImageManifest};
|
2024-01-18 00:02:21 -08:00
|
|
|
use std::path::{Path, PathBuf};
|
2024-03-07 05:26:35 +00:00
|
|
|
use tokio::fs;
|
2024-01-18 00:02:21 -08:00
|
|
|
|
2024-04-02 00:56:18 +00:00
|
|
|
#[derive(Clone)]
|
2024-04-15 10:24:14 -07:00
|
|
|
pub struct OciPackerCache {
|
2024-01-18 00:02:21 -08:00
|
|
|
cache_dir: PathBuf,
|
|
|
|
}
|
|
|
|
|
2024-04-15 10:24:14 -07:00
|
|
|
impl OciPackerCache {
|
|
|
|
pub fn new(cache_dir: &Path) -> Result<OciPackerCache> {
|
|
|
|
Ok(OciPackerCache {
|
2024-01-18 00:02:21 -08:00
|
|
|
cache_dir: cache_dir.to_path_buf(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-04-15 10:24:14 -07:00
|
|
|
pub async fn recall(
|
|
|
|
&self,
|
|
|
|
digest: &str,
|
|
|
|
format: OciPackedFormat,
|
2024-04-16 01:53:44 -07:00
|
|
|
) -> Result<Option<OciPackedImage>> {
|
2024-04-14 17:19:38 -07:00
|
|
|
let mut fs_path = self.cache_dir.clone();
|
2024-01-18 00:15:36 -08:00
|
|
|
let mut config_path = self.cache_dir.clone();
|
2024-01-18 00:02:21 -08:00
|
|
|
let mut manifest_path = self.cache_dir.clone();
|
2024-04-14 17:19:38 -07:00
|
|
|
fs_path.push(format!("{}.{}", digest, format.extension()));
|
2024-01-18 00:15:36 -08:00
|
|
|
manifest_path.push(format!("{}.manifest.json", digest));
|
|
|
|
config_path.push(format!("{}.config.json", digest));
|
|
|
|
Ok(
|
2024-04-14 17:19:38 -07:00
|
|
|
if fs_path.exists() && manifest_path.exists() && config_path.exists() {
|
|
|
|
let image_metadata = fs::metadata(&fs_path).await?;
|
2024-03-07 05:26:35 +00:00
|
|
|
let manifest_metadata = fs::metadata(&manifest_path).await?;
|
|
|
|
let config_metadata = fs::metadata(&config_path).await?;
|
2024-04-14 17:19:38 -07:00
|
|
|
if image_metadata.is_file()
|
2024-01-18 00:15:36 -08:00
|
|
|
&& manifest_metadata.is_file()
|
|
|
|
&& config_metadata.is_file()
|
|
|
|
{
|
2024-04-16 01:53:44 -07:00
|
|
|
let manifest_bytes = fs::read(&manifest_path).await?;
|
|
|
|
let manifest: ImageManifest = serde_json::from_slice(&manifest_bytes)?;
|
|
|
|
let config_bytes = fs::read(&config_path).await?;
|
|
|
|
let config: ImageConfiguration = serde_json::from_slice(&config_bytes)?;
|
2024-01-18 00:15:36 -08:00
|
|
|
debug!("cache hit digest={}", digest);
|
2024-04-16 01:53:44 -07:00
|
|
|
Some(OciPackedImage::new(
|
2024-04-15 10:24:14 -07:00
|
|
|
digest.to_string(),
|
|
|
|
fs_path.clone(),
|
|
|
|
format,
|
2024-04-16 01:53:44 -07:00
|
|
|
OciSchema::new(config_bytes, config),
|
|
|
|
OciSchema::new(manifest_bytes, manifest),
|
2024-04-15 10:24:14 -07:00
|
|
|
))
|
2024-01-18 00:15:36 -08:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2024-01-18 00:02:21 -08:00
|
|
|
} else {
|
2024-01-18 00:15:36 -08:00
|
|
|
debug!("cache miss digest={}", digest);
|
2024-01-18 00:02:21 -08:00
|
|
|
None
|
2024-01-18 00:15:36 -08:00
|
|
|
},
|
|
|
|
)
|
2024-01-18 00:02:21 -08:00
|
|
|
}
|
|
|
|
|
2024-04-16 01:53:44 -07:00
|
|
|
pub async fn store(&self, packed: OciPackedImage) -> Result<OciPackedImage> {
|
2024-04-15 10:24:14 -07:00
|
|
|
debug!("cache store digest={}", packed.digest);
|
2024-04-14 17:19:38 -07:00
|
|
|
let mut fs_path = self.cache_dir.clone();
|
2024-01-18 00:02:21 -08:00
|
|
|
let mut manifest_path = self.cache_dir.clone();
|
2024-01-18 00:15:36 -08:00
|
|
|
let mut config_path = self.cache_dir.clone();
|
2024-04-15 10:24:14 -07:00
|
|
|
fs_path.push(format!("{}.{}", packed.digest, packed.format.extension()));
|
|
|
|
manifest_path.push(format!("{}.manifest.json", packed.digest));
|
|
|
|
config_path.push(format!("{}.config.json", packed.digest));
|
2024-04-16 01:53:44 -07:00
|
|
|
fs::rename(&packed.path, &fs_path).await?;
|
|
|
|
fs::write(&config_path, packed.config.raw()).await?;
|
|
|
|
fs::write(&manifest_path, packed.manifest.raw()).await?;
|
|
|
|
Ok(OciPackedImage::new(
|
2024-04-15 10:24:14 -07:00
|
|
|
packed.digest,
|
|
|
|
fs_path.clone(),
|
|
|
|
packed.format,
|
|
|
|
packed.config,
|
|
|
|
packed.manifest,
|
|
|
|
))
|
2024-01-18 00:02:21 -08:00
|
|
|
}
|
|
|
|
}
|