2024-03-05 11:35:25 +00:00
|
|
|
use super::ImageInfo;
|
|
|
|
use anyhow::Result;
|
2024-01-18 08:02:21 +00:00
|
|
|
use log::debug;
|
2024-01-18 08:15:36 +00:00
|
|
|
use oci_spec::image::{ImageConfiguration, ImageManifest};
|
2024-01-18 08:02:21 +00:00
|
|
|
use std::fs;
|
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
|
|
|
|
pub struct ImageCache {
|
|
|
|
cache_dir: PathBuf,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ImageCache {
|
|
|
|
pub fn new(cache_dir: &Path) -> Result<ImageCache> {
|
|
|
|
Ok(ImageCache {
|
|
|
|
cache_dir: cache_dir.to_path_buf(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn recall(&self, digest: &str) -> Result<Option<ImageInfo>> {
|
|
|
|
let mut squashfs_path = self.cache_dir.clone();
|
2024-01-18 08:15:36 +00:00
|
|
|
let mut config_path = self.cache_dir.clone();
|
2024-01-18 08:02:21 +00:00
|
|
|
let mut manifest_path = self.cache_dir.clone();
|
|
|
|
squashfs_path.push(format!("{}.squashfs", digest));
|
2024-01-18 08:15:36 +00:00
|
|
|
manifest_path.push(format!("{}.manifest.json", digest));
|
|
|
|
config_path.push(format!("{}.config.json", digest));
|
|
|
|
Ok(
|
|
|
|
if squashfs_path.exists() && manifest_path.exists() && config_path.exists() {
|
|
|
|
let squashfs_metadata = fs::metadata(&squashfs_path)?;
|
|
|
|
let manifest_metadata = fs::metadata(&manifest_path)?;
|
|
|
|
let config_metadata = fs::metadata(&config_path)?;
|
|
|
|
if squashfs_metadata.is_file()
|
|
|
|
&& manifest_metadata.is_file()
|
|
|
|
&& config_metadata.is_file()
|
|
|
|
{
|
|
|
|
let manifest_text = fs::read_to_string(&manifest_path)?;
|
|
|
|
let manifest: ImageManifest = serde_json::from_str(&manifest_text)?;
|
2024-01-18 09:38:56 +00:00
|
|
|
let config_text = fs::read_to_string(&config_path)?;
|
2024-01-18 08:15:36 +00:00
|
|
|
let config: ImageConfiguration = serde_json::from_str(&config_text)?;
|
|
|
|
debug!("cache hit digest={}", digest);
|
|
|
|
Some(ImageInfo::new(squashfs_path.clone(), manifest, config)?)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2024-01-18 08:02:21 +00:00
|
|
|
} else {
|
2024-01-18 08:15:36 +00:00
|
|
|
debug!("cache miss digest={}", digest);
|
2024-01-18 08:02:21 +00:00
|
|
|
None
|
2024-01-18 08:15:36 +00:00
|
|
|
},
|
|
|
|
)
|
2024-01-18 08:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn store(&self, digest: &str, info: &ImageInfo) -> Result<ImageInfo> {
|
|
|
|
debug!("cache store digest={}", digest);
|
|
|
|
let mut squashfs_path = self.cache_dir.clone();
|
|
|
|
let mut manifest_path = self.cache_dir.clone();
|
2024-01-18 08:15:36 +00:00
|
|
|
let mut config_path = self.cache_dir.clone();
|
2024-01-18 08:02:21 +00:00
|
|
|
squashfs_path.push(format!("{}.squashfs", digest));
|
2024-01-18 08:15:36 +00:00
|
|
|
manifest_path.push(format!("{}.manifest.json", digest));
|
|
|
|
config_path.push(format!("{}.config.json", digest));
|
2024-01-18 22:52:35 +00:00
|
|
|
fs::copy(&info.image_squashfs, &squashfs_path)?;
|
2024-01-18 08:02:21 +00:00
|
|
|
let manifest_text = serde_json::to_string_pretty(&info.manifest)?;
|
|
|
|
fs::write(&manifest_path, manifest_text)?;
|
2024-01-18 08:15:36 +00:00
|
|
|
let config_text = serde_json::to_string_pretty(&info.config)?;
|
|
|
|
fs::write(&config_path, config_text)?;
|
|
|
|
ImageInfo::new(
|
|
|
|
squashfs_path.clone(),
|
|
|
|
info.manifest.clone(),
|
|
|
|
info.config.clone(),
|
|
|
|
)
|
2024-01-18 08:02:21 +00:00
|
|
|
}
|
|
|
|
}
|