kratart: fix multiple oci layer compiler issues

This commit is contained in:
Alex Zenla
2024-03-22 19:14:27 +00:00
parent f29d7d61e1
commit 1a6287893e
2 changed files with 37 additions and 13 deletions

View File

@ -60,7 +60,7 @@ termion = "3.0.0"
thiserror = "1.0" thiserror = "1.0"
tokio-listener = "0.3.1" tokio-listener = "0.3.1"
tokio-native-tls = "0.3.1" tokio-native-tls = "0.3.1"
tokio-tar = "0.3.1" tokio-tar = { git = "https://github.com/edera-dev/tokio-tar.git", branch = "edera" }
tokio-tun = "0.11.2" tokio-tun = "0.11.2"
tonic-build = "0.11.0" tonic-build = "0.11.0"
tower = "0.4.13" tower = "0.4.13"

View File

@ -109,17 +109,16 @@ impl ImageCompiler<'_> {
} }
let local = downloader.download(resolved).await?; let local = downloader.download(resolved).await?;
for layer in local.layers { for layer in &local.layers {
debug!( debug!(
"process layer digest={} compression={:?}", "process layer digest={} compression={:?}",
&layer.digest, layer.compression &layer.digest, layer.compression,
); );
self.process_layer_whiteout(layer, image_dir).await?;
let mut archive = layer.archive().await?; let mut archive = layer.archive().await?;
let mut entries = archive.entries()?; let mut entries = archive.entries()?;
while let Some(entry) = entries.next().await { while let Some(entry) = entries.next().await {
let mut entry: Entry<tokio_tar::Archive<std::pin::Pin<Box<dyn AsyncRead + Send>>>> = let mut entry = entry?;
entry?;
let path = entry.path()?; let path = entry.path()?;
let Some(name) = path.file_name() else { let Some(name) = path.file_name() else {
return Err(anyhow!("unable to get file name")); return Err(anyhow!("unable to get file name"));
@ -129,15 +128,19 @@ impl ImageCompiler<'_> {
}; };
if name.starts_with(".wh.") { if name.starts_with(".wh.") {
self.process_whiteout_entry(&entry, name, &layer, image_dir) continue;
.await?;
} else { } else {
self.process_write_entry(&mut entry, &layer, image_dir) self.process_write_entry(&mut entry, layer, image_dir)
.await?; .await?;
} }
} }
}
for layer in &local.layers {
if layer.path.exists() {
fs::remove_file(&layer.path).await?; fs::remove_file(&layer.path).await?;
} }
}
self.squash(image_dir, squash_file)?; self.squash(image_dir, squash_file)?;
let info = ImageInfo::new( let info = ImageInfo::new(
@ -148,6 +151,27 @@ impl ImageCompiler<'_> {
self.cache.store(&cache_digest, &info).await self.cache.store(&cache_digest, &info).await
} }
async fn process_layer_whiteout(&self, layer: &OciImageLayer, image_dir: &Path) -> Result<()> {
let mut archive = layer.archive().await?;
let mut entries = archive.entries()?;
while let Some(entry) = entries.next().await {
let entry = entry?;
let path = entry.path()?;
let Some(name) = path.file_name() else {
return Err(anyhow!("unable to get file name"));
};
let Some(name) = name.to_str() else {
return Err(anyhow!("unable to get file name as string"));
};
if name.starts_with(".wh.") {
self.process_whiteout_entry(&entry, name, layer, image_dir)
.await?;
}
}
Ok(())
}
async fn process_whiteout_entry( async fn process_whiteout_entry(
&self, &self,
entry: &Entry<Archive<Pin<Box<dyn AsyncRead + Send>>>>, entry: &Entry<Archive<Pin<Box<dyn AsyncRead + Send>>>>,
@ -162,7 +186,7 @@ impl ImageCompiler<'_> {
let opaque = name == ".wh..wh..opq"; let opaque = name == ".wh..wh..opq";
if !opaque { if !opaque {
dst.push(name); dst.push(&name[4..]);
self.check_safe_path(&dst, image_dir)?; self.check_safe_path(&dst, image_dir)?;
} }
@ -187,7 +211,7 @@ impl ImageCompiler<'_> {
} }
} else { } else {
warn!( warn!(
"whiteout entry missing locally layer={} path={:?} local={:?}", "whiteout opaque entry missing locally layer={} path={:?} local={:?}",
&layer.digest, &layer.digest,
entry.path()?, entry.path()?,
dst, dst,
@ -196,7 +220,7 @@ impl ImageCompiler<'_> {
} else if dst.is_file() || dst.is_symlink() { } else if dst.is_file() || dst.is_symlink() {
fs::remove_file(&dst).await?; fs::remove_file(&dst).await?;
} else if dst.is_dir() { } else if dst.is_dir() {
fs::remove_dir(&dst).await?; fs::remove_dir_all(&dst).await?;
} else { } else {
warn!( warn!(
"whiteout entry missing locally layer={} path={:?} local={:?}", "whiteout entry missing locally layer={} path={:?} local={:?}",