diff --git a/lib/src/tar/write.rs b/lib/src/tar/write.rs index 7d251b98..34ab7944 100644 --- a/lib/src/tar/write.rs +++ b/lib/src/tar/write.rs @@ -156,7 +156,23 @@ pub(crate) fn filter_tar( }; let mut header = entry.header().clone(); - dest.append_data(&mut header, normalized, entry)?; + + // Need to use the entry.link_name() not the header.link_name() + // api as the header api does not handle long paths: + // https://github.com/alexcrichton/tar-rs/issues/192 + match entry.header().entry_type() { + tar::EntryType::Link | tar::EntryType::Symlink => { + let target = entry.link_name()?.ok_or_else(|| anyhow!("Invalid link"))?; + let target = target + .as_os_str() + .to_str() + .ok_or_else(|| anyhow!("Non-utf8 link"))?; + dest.append_link(&mut header, &normalized, target)?; + } + _ => { + dest.append_data(&mut header, normalized, entry)?; + } + } } dest.into_inner()?.flush()?; Ok(filtered) diff --git a/lib/tests/it/fixtures/hlinks.tar.gz b/lib/tests/it/fixtures/hlinks.tar.gz new file mode 100644 index 00000000..0bbc06d4 Binary files /dev/null and b/lib/tests/it/fixtures/hlinks.tar.gz differ diff --git a/lib/tests/it/main.rs b/lib/tests/it/main.rs index 77200d32..cf0abcfd 100644 --- a/lib/tests/it/main.rs +++ b/lib/tests/it/main.rs @@ -15,6 +15,7 @@ use std::process::Command; use fixture::Fixture; +const EXAMPLE_TAR_LAYER: &[u8] = include_bytes!("fixtures/hlinks.tar.gz"); const EXAMPLEOS_CONTENT_CHECKSUM: &str = "0ef7461f9db15e1d8bd8921abf20694225fbaa4462cadf7deed8ea0e43162120"; const TEST_REGISTRY_DEFAULT: &str = "localhost:5000"; @@ -324,6 +325,16 @@ async fn test_tar_write() -> Result<()> { Ok(()) } +#[tokio::test] +async fn test_tar_write_tar_layer() -> Result<()> { + let fixture = Fixture::new()?; + let uncompressed_tar = tokio::io::BufReader::new( + async_compression::tokio::bufread::GzipDecoder::new(EXAMPLE_TAR_LAYER), + ); + ostree_ext::tar::write_tar(&fixture.destrepo, uncompressed_tar, "test", None).await?; + Ok(()) +} + fn skopeo_inspect(imgref: &str) -> Result { let out = Command::new("skopeo") .args(&["inspect", imgref])