Skip to content

Commit ce3b777

Browse files
oci: add handling for "/" in layer tars
So far we've been testing with local podman builds, which don't produce these by default, but we need to support these, as they appear in some bootc images. It's a bit tricky because our root directory isn't an Inode, so add a special path. While we're at it, add some error context to the path where this was failing before. Signed-off-by: Allison Karlitskaya <[email protected]>
1 parent b69974e commit ce3b777

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

src/oci/image.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{ffi::OsStr, os::unix::ffi::OsStrExt, rc::Rc};
22

3-
use anyhow::Result;
3+
use anyhow::{ensure, Context, Result};
44
use oci_spec::image::ImageConfiguration;
55

66
use crate::{
@@ -20,6 +20,19 @@ pub fn process_entry<ObjectID: FsVerityHashValue>(
2020
filesystem: &mut FileSystem<ObjectID>,
2121
entry: TarEntry<ObjectID>,
2222
) -> Result<()> {
23+
if entry.path.file_name().is_none() {
24+
// special handling for the root directory
25+
ensure!(
26+
matches!(entry.item, TarItem::Directory),
27+
"Unpacking layer tar: filename {:?} must be a directory",
28+
entry.path
29+
);
30+
31+
// Update the stat, but don't do anything else
32+
filesystem.set_root_stat(entry.stat);
33+
return Ok(());
34+
}
35+
2336
let inode = match entry.item {
2437
TarItem::Directory => Inode::Directory(Box::from(Directory::new(entry.stat))),
2538
TarItem::Leaf(content) => Inode::Leaf(Rc::new(Leaf {
@@ -32,7 +45,15 @@ pub fn process_entry<ObjectID: FsVerityHashValue>(
3245
}
3346
};
3447

35-
let (dir, filename) = filesystem.root.split_mut(entry.path.as_os_str())?;
48+
let (dir, filename) = filesystem
49+
.root
50+
.split_mut(entry.path.as_os_str())
51+
.with_context(|| {
52+
format!(
53+
"Error unpacking container layer file {:?} {:?}",
54+
entry.path, inode
55+
)
56+
})?;
3657

3758
let bytes = filename.as_bytes();
3859
if let Some(whiteout) = bytes.strip_prefix(b".wh.") {

0 commit comments

Comments
 (0)