mirror of
				https://github.com/edera-dev/krata.git
				synced 2025-11-03 23:29:39 +00:00 
			
		
		
		
	hypha: cache image config
This commit is contained in:
		@ -1,6 +1,6 @@
 | 
			
		||||
use crate::image::{ImageInfo, Result};
 | 
			
		||||
use log::debug;
 | 
			
		||||
use oci_spec::image::ImageManifest;
 | 
			
		||||
use oci_spec::image::{ImageConfiguration, ImageManifest};
 | 
			
		||||
use std::fs;
 | 
			
		||||
use std::path::{Path, PathBuf};
 | 
			
		||||
 | 
			
		||||
@ -17,35 +17,53 @@ impl ImageCache {
 | 
			
		||||
 | 
			
		||||
    pub fn recall(&self, digest: &str) -> Result<Option<ImageInfo>> {
 | 
			
		||||
        let mut squashfs_path = self.cache_dir.clone();
 | 
			
		||||
        let mut config_path = self.cache_dir.clone();
 | 
			
		||||
        let mut manifest_path = self.cache_dir.clone();
 | 
			
		||||
        squashfs_path.push(format!("{}.squashfs", digest));
 | 
			
		||||
        manifest_path.push(format!("{}.json", digest));
 | 
			
		||||
        Ok(if squashfs_path.exists() && manifest_path.exists() {
 | 
			
		||||
            let squashfs_metadata = fs::metadata(&squashfs_path)?;
 | 
			
		||||
            let manifest_metadata = fs::metadata(&manifest_path)?;
 | 
			
		||||
            if squashfs_metadata.is_file() && manifest_metadata.is_file() {
 | 
			
		||||
                let manifest_text = fs::read_to_string(&manifest_path)?;
 | 
			
		||||
                let manifest: ImageManifest = serde_json::from_str(manifest_text.as_str())?;
 | 
			
		||||
                debug!("cache hit digest={}", digest);
 | 
			
		||||
                Some(ImageInfo::new(squashfs_path.clone(), manifest)?)
 | 
			
		||||
        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)?;
 | 
			
		||||
                    let config_text = fs::read_to_string(&manifest_path)?;
 | 
			
		||||
                    let config: ImageConfiguration = serde_json::from_str(&config_text)?;
 | 
			
		||||
                    debug!("cache hit digest={}", digest);
 | 
			
		||||
                    Some(ImageInfo::new(squashfs_path.clone(), manifest, config)?)
 | 
			
		||||
                } else {
 | 
			
		||||
                    None
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                debug!("cache miss digest={}", digest);
 | 
			
		||||
                None
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            debug!("cache miss digest={}", digest);
 | 
			
		||||
            None
 | 
			
		||||
        })
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
        let mut config_path = self.cache_dir.clone();
 | 
			
		||||
        squashfs_path.push(format!("{}.squashfs", digest));
 | 
			
		||||
        manifest_path.push(format!("{}.json", digest));
 | 
			
		||||
        manifest_path.push(format!("{}.manifest.json", digest));
 | 
			
		||||
        config_path.push(format!("{}.config.json", digest));
 | 
			
		||||
        fs::copy(&info.squashfs, &squashfs_path)?;
 | 
			
		||||
        let manifest_text = serde_json::to_string_pretty(&info.manifest)?;
 | 
			
		||||
        fs::write(&manifest_path, manifest_text)?;
 | 
			
		||||
        ImageInfo::new(squashfs_path.clone(), info.manifest.clone())
 | 
			
		||||
        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(),
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ use crate::error::{HyphaError, Result};
 | 
			
		||||
use crate::image::cache::ImageCache;
 | 
			
		||||
use backhand::{FilesystemWriter, NodeHeader};
 | 
			
		||||
use log::{debug, trace};
 | 
			
		||||
use oci_spec::image::{ImageManifest, MediaType};
 | 
			
		||||
use oci_spec::image::{ImageConfiguration, ImageManifest, MediaType};
 | 
			
		||||
use ocipkg::distribution::Client;
 | 
			
		||||
use ocipkg::error::Error;
 | 
			
		||||
use ocipkg::{Digest, ImageName};
 | 
			
		||||
@ -19,11 +19,20 @@ use walkdir::WalkDir;
 | 
			
		||||
pub struct ImageInfo {
 | 
			
		||||
    pub squashfs: PathBuf,
 | 
			
		||||
    pub manifest: ImageManifest,
 | 
			
		||||
    pub config: ImageConfiguration,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ImageInfo {
 | 
			
		||||
    fn new(squashfs: PathBuf, manifest: ImageManifest) -> Result<ImageInfo> {
 | 
			
		||||
        Ok(ImageInfo { squashfs, manifest })
 | 
			
		||||
    fn new(
 | 
			
		||||
        squashfs: PathBuf,
 | 
			
		||||
        manifest: ImageManifest,
 | 
			
		||||
        config: ImageConfiguration,
 | 
			
		||||
    ) -> Result<ImageInfo> {
 | 
			
		||||
        Ok(ImageInfo {
 | 
			
		||||
            squashfs,
 | 
			
		||||
            manifest,
 | 
			
		||||
            config,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -70,6 +79,10 @@ impl ImageCompiler<'_> {
 | 
			
		||||
        if let Some(cached) = self.cache.recall(&manifest_digest)? {
 | 
			
		||||
            return Ok(cached);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let config_bytes = client.get_blob(&Digest::new(manifest.config().digest())?)?;
 | 
			
		||||
        let config: ImageConfiguration = serde_json::from_slice(&config_bytes)?;
 | 
			
		||||
 | 
			
		||||
        for layer in manifest.layers() {
 | 
			
		||||
            debug!(
 | 
			
		||||
                "ImageCompiler download start digest={} size={}",
 | 
			
		||||
@ -100,7 +113,7 @@ impl ImageCompiler<'_> {
 | 
			
		||||
                layer.size()
 | 
			
		||||
            );
 | 
			
		||||
            self.squash(image_dir, squash_file)?;
 | 
			
		||||
            let info = ImageInfo::new(squash_file.clone(), manifest.clone())?;
 | 
			
		||||
            let info = ImageInfo::new(squash_file.clone(), manifest.clone(), config)?;
 | 
			
		||||
            return self.cache.store(&manifest_digest, &info);
 | 
			
		||||
        }
 | 
			
		||||
        Err(Error::MissingLayer.into())
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user