From 04092c1d3b489fe9a8aa2d48fadf20ca253c2671 Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Mon, 22 Jan 2024 07:24:42 -0800 Subject: [PATCH] hypha: use manifest digest as part of key in image cache --- hypha/src/image/fetch.rs | 14 +++++++++++--- hypha/src/image/mod.rs | 11 ++++++----- xenclient/src/lib.rs | 3 ++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/hypha/src/image/fetch.rs b/hypha/src/image/fetch.rs index c2855ec..e08c805 100644 --- a/hypha/src/image/fetch.rs +++ b/hypha/src/image/fetch.rs @@ -47,7 +47,11 @@ impl RegistryClient { Ok(copy(reader.deref_mut(), dest)?) } - pub fn get_manifest(&mut self, name: &str, reference: &str) -> Result { + pub fn get_manifest_with_digest( + &mut self, + name: &str, + reference: &str, + ) -> Result<(ImageManifest, String)> { let url = self .url .join(&format!("/v2/{}/manifests/{}", name, reference))?; @@ -69,10 +73,14 @@ impl RegistryClient { let descriptor = self .pick_manifest(index) .ok_or_else(|| HyphaError::new("unable to pick manifest from index"))?; - return self.get_manifest(name, descriptor.digest()); + return self.get_manifest_with_digest(name, descriptor.digest()); } + let digest = response + .header("Docker-Content-Digest") + .ok_or_else(|| HyphaError::new("fetching manifest did not yield a content digest"))? + .to_string(); let manifest = ImageManifest::from_reader(response.into_reader())?; - Ok(manifest) + Ok((manifest, digest)) } fn pick_manifest(&mut self, index: ImageIndex) -> Option { diff --git a/hypha/src/image/mod.rs b/hypha/src/image/mod.rs index 54253c9..5ca34bd 100644 --- a/hypha/src/image/mod.rs +++ b/hypha/src/image/mod.rs @@ -6,7 +6,8 @@ use crate::error::{HyphaError, Result}; use crate::image::cache::ImageCache; use crate::image::fetch::RegistryClient; use crate::image::name::ImageName; -use backhand::{FilesystemWriter, NodeHeader}; +use backhand::compression::Compressor; +use backhand::{FilesystemCompressor, FilesystemWriter, NodeHeader}; use flate2::read::GzDecoder; use log::{debug, trace, warn}; use oci_spec::image::{Descriptor, ImageConfiguration, ImageManifest, MediaType, ToDockerV2S2}; @@ -125,11 +126,10 @@ impl ImageCompiler<'_> { image_dir.to_str().unwrap() ); let mut client = RegistryClient::new(image.registry_url()?)?; - let manifest = client.get_manifest(&image.name, &image.reference)?; - let manifest_serialized = serde_json::to_string(&manifest)?; + let (manifest, digest) = client.get_manifest_with_digest(&image.name, &image.reference)?; let cache_key = format!( - "manifest\n{}squashfs-version\n{}\n", - manifest_serialized, IMAGE_SQUASHFS_VERSION + "manifest={}:squashfs-version={}\n", + digest, IMAGE_SQUASHFS_VERSION ); let cache_digest = sha256::digest(cache_key); @@ -338,6 +338,7 @@ impl ImageCompiler<'_> { fn squash(&self, image_dir: &PathBuf, squash_file: &PathBuf) -> Result<()> { let mut writer = FilesystemWriter::default(); + writer.set_compressor(FilesystemCompressor::new(Compressor::Gzip, None)?); let walk = WalkDir::new(image_dir).follow_links(false); for entry in walk { let entry = entry?; diff --git a/xenclient/src/lib.rs b/xenclient/src/lib.rs index d061c0d..d1c97ca 100644 --- a/xenclient/src/lib.rs +++ b/xenclient/src/lib.rs @@ -195,7 +195,8 @@ impl XenClient { let mut count: u32 = 0; loop { if count >= 100 { - return Err(XenClientError::new("unable to destroy device")); + warn!("unable to safely destroy backend: {}", backend); + break; } let state = self.store.read_string(&state_path)?; let state = i64::from_str(&state).unwrap_or(-1);