* [PATCH proxmox 0/2] oci: tests: refactor to drop static test tarballs
@ 2026-03-24 15:35 Filip Schauer
2026-03-24 15:35 ` [PATCH proxmox 1/2] oci: tests: return Result from tests to avoid unwrap calls Filip Schauer
2026-03-24 15:35 ` [PATCH proxmox 2/2] oci: tests: generate OCI test images on the fly Filip Schauer
0 siblings, 2 replies; 3+ messages in thread
From: Filip Schauer @ 2026-03-24 15:35 UTC (permalink / raw)
To: pve-devel
Refactor the OCI tests to generate OCI images on the fly instead of
relying on pre-built tar files checked into the repository.
Filip Schauer (2):
oci: tests: return Result from tests to avoid unwrap calls
oci: tests: generate OCI test images on the fly
proxmox-oci/Cargo.toml | 2 +
proxmox-oci/tests/extract_replace.rs | 73 +++++---
proxmox-oci/tests/extract_whiteouts.rs | 123 ++++++++-----
proxmox-oci/tests/helper/mod.rs | 3 +
.../tests/helper/oci_tar_image_builder.rs | 171 ++++++++++++++++++
.../oci_test_replace_dir_with_file.tar | Bin 8704 -> 0 bytes
.../oci_image_data/oci_test_replace_file.tar | Bin 8704 -> 0 bytes
.../oci_test_replace_file_with_dir.tar | Bin 8704 -> 0 bytes
.../oci_test_whiteout_current_directory.tar | Bin 8704 -> 0 bytes
.../oci_test_whiteout_dead_symlink_parent.tar | Bin 8704 -> 0 bytes
.../oci_test_whiteout_root_breakout.tar | Bin 7168 -> 0 bytes
...oci_test_whiteout_root_parent_breakout.tar | Bin 7168 -> 0 bytes
.../oci_test_whiteout_symlink.tar | Bin 8704 -> 0 bytes
13 files changed, 297 insertions(+), 75 deletions(-)
create mode 100644 proxmox-oci/tests/helper/mod.rs
create mode 100644 proxmox-oci/tests/helper/oci_tar_image_builder.rs
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_replace_dir_with_file.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_replace_file.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_replace_file_with_dir.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_current_directory.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_dead_symlink_parent.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_root_breakout.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_root_parent_breakout.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_symlink.tar
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH proxmox 1/2] oci: tests: return Result from tests to avoid unwrap calls
2026-03-24 15:35 [PATCH proxmox 0/2] oci: tests: refactor to drop static test tarballs Filip Schauer
@ 2026-03-24 15:35 ` Filip Schauer
2026-03-24 15:35 ` [PATCH proxmox 2/2] oci: tests: generate OCI test images on the fly Filip Schauer
1 sibling, 0 replies; 3+ messages in thread
From: Filip Schauer @ 2026-03-24 15:35 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
proxmox-oci/Cargo.toml | 1 +
| 37 +++++++++--------
| 57 +++++++++++++++-----------
3 files changed, 54 insertions(+), 41 deletions(-)
diff --git a/proxmox-oci/Cargo.toml b/proxmox-oci/Cargo.toml
index b0c1cf38..8b922f37 100644
--- a/proxmox-oci/Cargo.toml
+++ b/proxmox-oci/Cargo.toml
@@ -22,4 +22,5 @@ zstd.workspace = true
proxmox-io.workspace = true
[dev-dependencies]
+anyhow.workspace = true
proxmox-sys.workspace = true
--git a/proxmox-oci/tests/extract_replace.rs b/proxmox-oci/tests/extract_replace.rs
index eb41f9e3..5f684c8a 100644
--- a/proxmox-oci/tests/extract_replace.rs
+++ b/proxmox-oci/tests/extract_replace.rs
@@ -1,57 +1,62 @@
use std::fs::{read_to_string, remove_dir_all};
+use anyhow::Result;
+
use proxmox_oci::{parse_and_extract_image, Arch};
use proxmox_sys::fs::make_tmp_dir;
#[test]
-fn test_replace_file() {
- let extract_dir = make_tmp_dir("/tmp/", None).unwrap();
+fn test_replace_file() -> Result<()> {
+ let extract_dir = make_tmp_dir("/tmp/", None)?;
parse_and_extract_image(
&"tests/oci_image_data/oci_test_replace_file.tar".into(),
&extract_dir,
Some(&Arch::Amd64),
- )
- .unwrap();
+ )?;
let replaced_path = extract_dir.join("etc/a");
assert!(replaced_path.is_file());
- assert_eq!(read_to_string(replaced_path).unwrap(), "2");
+ assert_eq!(read_to_string(replaced_path)?, "2");
// Cleanup
- remove_dir_all(extract_dir).unwrap();
+ remove_dir_all(extract_dir)?;
+
+ Ok(())
}
#[test]
-fn test_replace_file_with_dir() {
- let extract_dir = make_tmp_dir("/tmp/", None).unwrap();
+fn test_replace_file_with_dir() -> Result<()> {
+ let extract_dir = make_tmp_dir("/tmp/", None)?;
parse_and_extract_image(
&"tests/oci_image_data/oci_test_replace_file_with_dir.tar".into(),
&extract_dir,
Some(&Arch::Amd64),
- )
- .unwrap();
+ )?;
assert!(extract_dir.join("etc/a").is_dir());
// Cleanup
- remove_dir_all(extract_dir).unwrap();
+ remove_dir_all(extract_dir)?;
+
+ Ok(())
}
#[test]
-fn test_replace_dir_with_file() {
- let extract_dir = make_tmp_dir("/tmp/", None).unwrap();
+fn test_replace_dir_with_file() -> Result<()> {
+ let extract_dir = make_tmp_dir("/tmp/", None)?;
parse_and_extract_image(
&"tests/oci_image_data/oci_test_replace_dir_with_file.tar".into(),
&extract_dir,
Some(&Arch::Amd64),
- )
- .unwrap();
+ )?;
assert!(extract_dir.join("etc/a").is_file());
// Cleanup
- remove_dir_all(extract_dir).unwrap();
+ remove_dir_all(extract_dir)?;
+
+ Ok(())
}
--git a/proxmox-oci/tests/extract_whiteouts.rs b/proxmox-oci/tests/extract_whiteouts.rs
index 71ec4dea..20156de0 100644
--- a/proxmox-oci/tests/extract_whiteouts.rs
+++ b/proxmox-oci/tests/extract_whiteouts.rs
@@ -1,92 +1,99 @@
use std::fs::remove_dir_all;
+use anyhow::Result;
+
use proxmox_oci::{parse_and_extract_image, Arch};
use proxmox_sys::fs::make_tmp_dir;
#[test]
-fn test_whiteout_root_breakout() {
- let extract_dir = make_tmp_dir("/tmp/", None).unwrap();
+fn test_whiteout_root_breakout() -> Result<()> {
+ let extract_dir = make_tmp_dir("/tmp/", None)?;
parse_and_extract_image(
&"tests/oci_image_data/oci_test_whiteout_root_breakout.tar".into(),
&extract_dir,
Some(&Arch::Amd64),
- )
- .unwrap();
+ )?;
// Check that the whiteout did not remove the root directory
assert!(extract_dir.exists());
// Cleanup
- remove_dir_all(extract_dir).unwrap();
+ remove_dir_all(extract_dir)?;
+
+ Ok(())
}
#[test]
-fn test_whiteout_root_parent_breakout() {
- let extract_dir = make_tmp_dir("/tmp/", None).unwrap();
+fn test_whiteout_root_parent_breakout() -> Result<()> {
+ let extract_dir = make_tmp_dir("/tmp/", None)?;
parse_and_extract_image(
&"tests/oci_image_data/oci_test_whiteout_root_parent_breakout.tar".into(),
&extract_dir,
Some(&Arch::Amd64),
- )
- .unwrap();
+ )?;
// Check that the whiteout did not remove the root directory
assert!(extract_dir.exists());
// Cleanup
- remove_dir_all(extract_dir).unwrap();
+ remove_dir_all(extract_dir)?;
+
+ Ok(())
}
#[test]
-fn test_whiteout_current_directory() {
- let extract_dir = make_tmp_dir("/tmp/", None).unwrap();
+fn test_whiteout_current_directory() -> Result<()> {
+ let extract_dir = make_tmp_dir("/tmp/", None)?;
parse_and_extract_image(
&"tests/oci_image_data/oci_test_whiteout_current_directory.tar".into(),
&extract_dir,
Some(&Arch::Amd64),
- )
- .unwrap();
+ )?;
assert!(!extract_dir.join("etc").exists());
// Cleanup
- remove_dir_all(extract_dir).unwrap();
+ remove_dir_all(extract_dir)?;
+
+ Ok(())
}
#[test]
-fn test_whiteout_symlink() {
- let extract_dir = make_tmp_dir("/tmp/", None).unwrap();
+fn test_whiteout_symlink() -> Result<()> {
+ let extract_dir = make_tmp_dir("/tmp/", None)?;
parse_and_extract_image(
&"tests/oci_image_data/oci_test_whiteout_symlink.tar".into(),
&extract_dir,
Some(&Arch::Amd64),
- )
- .unwrap();
+ )?;
assert!(extract_dir.join("etc/passwd").exists());
assert!(!extract_dir.join("localetc").exists());
// Cleanup
- remove_dir_all(extract_dir).unwrap();
+ remove_dir_all(extract_dir)?;
+
+ Ok(())
}
#[test]
-fn test_whiteout_dead_symlink_parent() {
- let extract_dir = make_tmp_dir("/tmp/", None).unwrap();
+fn test_whiteout_dead_symlink_parent() -> Result<()> {
+ let extract_dir = make_tmp_dir("/tmp/", None)?;
parse_and_extract_image(
&"tests/oci_image_data/oci_test_whiteout_dead_symlink_parent.tar".into(),
&extract_dir,
Some(&Arch::Amd64),
- )
- .unwrap();
+ )?;
assert!(extract_dir.join("etc/passwd").exists());
// Cleanup
- remove_dir_all(extract_dir).unwrap();
+ remove_dir_all(extract_dir)?;
+
+ Ok(())
}
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH proxmox 2/2] oci: tests: generate OCI test images on the fly
2026-03-24 15:35 [PATCH proxmox 0/2] oci: tests: refactor to drop static test tarballs Filip Schauer
2026-03-24 15:35 ` [PATCH proxmox 1/2] oci: tests: return Result from tests to avoid unwrap calls Filip Schauer
@ 2026-03-24 15:35 ` Filip Schauer
1 sibling, 0 replies; 3+ messages in thread
From: Filip Schauer @ 2026-03-24 15:35 UTC (permalink / raw)
To: pve-devel
Get rid of the pre-built tar files and instead generate them on the fly.
This makes the tests easier to understand and it is also easier to write
new tests this way.
This also fixes extraction failures when running tests as a non-root
user. The old tar files used UID/GID 0 for all layer entries, whereas
now the effective UID/GID of the test runner is used instead.
Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
proxmox-oci/Cargo.toml | 1 +
| 42 +++--
| 72 +++++---
proxmox-oci/tests/helper/mod.rs | 3 +
.../tests/helper/oci_tar_image_builder.rs | 171 ++++++++++++++++++
.../oci_test_replace_dir_with_file.tar | Bin 8704 -> 0 bytes
.../oci_image_data/oci_test_replace_file.tar | Bin 8704 -> 0 bytes
.../oci_test_replace_file_with_dir.tar | Bin 8704 -> 0 bytes
.../oci_test_whiteout_current_directory.tar | Bin 8704 -> 0 bytes
.../oci_test_whiteout_dead_symlink_parent.tar | Bin 8704 -> 0 bytes
.../oci_test_whiteout_root_breakout.tar | Bin 7168 -> 0 bytes
...oci_test_whiteout_root_parent_breakout.tar | Bin 7168 -> 0 bytes
.../oci_test_whiteout_symlink.tar | Bin 8704 -> 0 bytes
13 files changed, 249 insertions(+), 40 deletions(-)
create mode 100644 proxmox-oci/tests/helper/mod.rs
create mode 100644 proxmox-oci/tests/helper/oci_tar_image_builder.rs
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_replace_dir_with_file.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_replace_file.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_replace_file_with_dir.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_current_directory.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_dead_symlink_parent.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_root_breakout.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_root_parent_breakout.tar
delete mode 100644 proxmox-oci/tests/oci_image_data/oci_test_whiteout_symlink.tar
diff --git a/proxmox-oci/Cargo.toml b/proxmox-oci/Cargo.toml
index 8b922f37..d651390f 100644
--- a/proxmox-oci/Cargo.toml
+++ b/proxmox-oci/Cargo.toml
@@ -24,3 +24,4 @@ proxmox-io.workspace = true
[dev-dependencies]
anyhow.workspace = true
proxmox-sys.workspace = true
+nix = { workspace = true, features = ["user"] }
--git a/proxmox-oci/tests/extract_replace.rs b/proxmox-oci/tests/extract_replace.rs
index 5f684c8a..fe268d89 100644
--- a/proxmox-oci/tests/extract_replace.rs
+++ b/proxmox-oci/tests/extract_replace.rs
@@ -5,15 +5,20 @@ use anyhow::Result;
use proxmox_oci::{parse_and_extract_image, Arch};
use proxmox_sys::fs::make_tmp_dir;
+mod helper;
+use helper::{LayerEntry, OciTarImageBuilder};
+
#[test]
fn test_replace_file() -> Result<()> {
+ let image_dir = make_tmp_dir("/tmp/", None)?;
+ let image_path = image_dir.join("oci_image.tar");
+ OciTarImageBuilder::default()
+ .layer(vec![LayerEntry::file("etc/a", b"1")])
+ .layer(vec![LayerEntry::file("etc/a", b"2")])
+ .build(&image_path)?;
let extract_dir = make_tmp_dir("/tmp/", None)?;
- parse_and_extract_image(
- &"tests/oci_image_data/oci_test_replace_file.tar".into(),
- &extract_dir,
- Some(&Arch::Amd64),
- )?;
+ parse_and_extract_image(&image_path, &extract_dir, Some(&Arch::Amd64))?;
let replaced_path = extract_dir.join("etc/a");
assert!(replaced_path.is_file());
@@ -21,42 +26,49 @@ fn test_replace_file() -> Result<()> {
// Cleanup
remove_dir_all(extract_dir)?;
+ remove_dir_all(image_dir)?;
Ok(())
}
#[test]
fn test_replace_file_with_dir() -> Result<()> {
+ let image_dir = make_tmp_dir("/tmp/", None)?;
+ let image_path = image_dir.join("oci_image.tar");
+ OciTarImageBuilder::default()
+ .layer(vec![LayerEntry::file("etc/a", b"1")])
+ .layer(vec![LayerEntry::dir("etc/a")])
+ .build(&image_path)?;
let extract_dir = make_tmp_dir("/tmp/", None)?;
- parse_and_extract_image(
- &"tests/oci_image_data/oci_test_replace_file_with_dir.tar".into(),
- &extract_dir,
- Some(&Arch::Amd64),
- )?;
+ parse_and_extract_image(&image_path, &extract_dir, Some(&Arch::Amd64))?;
assert!(extract_dir.join("etc/a").is_dir());
// Cleanup
remove_dir_all(extract_dir)?;
+ remove_dir_all(image_dir)?;
Ok(())
}
#[test]
fn test_replace_dir_with_file() -> Result<()> {
+ let image_dir = make_tmp_dir("/tmp/", None)?;
+ let image_path = image_dir.join("oci_image.tar");
+ OciTarImageBuilder::default()
+ .layer(vec![LayerEntry::dir("etc/a")])
+ .layer(vec![LayerEntry::file("etc/a", b"1")])
+ .build(&image_path)?;
let extract_dir = make_tmp_dir("/tmp/", None)?;
- parse_and_extract_image(
- &"tests/oci_image_data/oci_test_replace_dir_with_file.tar".into(),
- &extract_dir,
- Some(&Arch::Amd64),
- )?;
+ parse_and_extract_image(&image_path, &extract_dir, Some(&Arch::Amd64))?;
assert!(extract_dir.join("etc/a").is_file());
// Cleanup
remove_dir_all(extract_dir)?;
+ remove_dir_all(image_dir)?;
Ok(())
}
--git a/proxmox-oci/tests/extract_whiteouts.rs b/proxmox-oci/tests/extract_whiteouts.rs
index 20156de0..7c7d95fc 100644
--- a/proxmox-oci/tests/extract_whiteouts.rs
+++ b/proxmox-oci/tests/extract_whiteouts.rs
@@ -5,95 +5,117 @@ use anyhow::Result;
use proxmox_oci::{parse_and_extract_image, Arch};
use proxmox_sys::fs::make_tmp_dir;
+mod helper;
+use helper::{LayerEntry, OciTarImageBuilder};
+
#[test]
fn test_whiteout_root_breakout() -> Result<()> {
+ let image_dir = make_tmp_dir("/tmp/", None)?;
+ let image_path = image_dir.join("oci_image.tar");
+ OciTarImageBuilder::default()
+ .layer(vec![LayerEntry::file(".wh..", b"")])
+ .build(&image_path)?;
let extract_dir = make_tmp_dir("/tmp/", None)?;
- parse_and_extract_image(
- &"tests/oci_image_data/oci_test_whiteout_root_breakout.tar".into(),
- &extract_dir,
- Some(&Arch::Amd64),
- )?;
+ parse_and_extract_image(&image_path, &extract_dir, Some(&Arch::Amd64))?;
// Check that the whiteout did not remove the root directory
assert!(extract_dir.exists());
// Cleanup
remove_dir_all(extract_dir)?;
+ remove_dir_all(image_dir)?;
Ok(())
}
#[test]
fn test_whiteout_root_parent_breakout() -> Result<()> {
+ let image_dir = make_tmp_dir("/tmp/", None)?;
+ let image_path = image_dir.join("oci_image.tar");
+ OciTarImageBuilder::default()
+ .layer(vec![LayerEntry::file(".wh...", b"")])
+ .build(&image_path)?;
let extract_dir = make_tmp_dir("/tmp/", None)?;
- parse_and_extract_image(
- &"tests/oci_image_data/oci_test_whiteout_root_parent_breakout.tar".into(),
- &extract_dir,
- Some(&Arch::Amd64),
- )?;
+ parse_and_extract_image(&image_path, &extract_dir, Some(&Arch::Amd64))?;
// Check that the whiteout did not remove the root directory
assert!(extract_dir.exists());
// Cleanup
remove_dir_all(extract_dir)?;
+ remove_dir_all(image_dir)?;
Ok(())
}
#[test]
fn test_whiteout_current_directory() -> Result<()> {
+ let image_dir = make_tmp_dir("/tmp/", None)?;
+ let image_path = image_dir.join("oci_image.tar");
+ OciTarImageBuilder::default()
+ .layer(vec![LayerEntry::file("etc/passwd", b"passwd")])
+ .layer(vec![LayerEntry::file("etc/.wh..", b"")])
+ .build(&image_path)?;
let extract_dir = make_tmp_dir("/tmp/", None)?;
- parse_and_extract_image(
- &"tests/oci_image_data/oci_test_whiteout_current_directory.tar".into(),
- &extract_dir,
- Some(&Arch::Amd64),
- )?;
+ parse_and_extract_image(&image_path, &extract_dir, Some(&Arch::Amd64))?;
assert!(!extract_dir.join("etc").exists());
// Cleanup
remove_dir_all(extract_dir)?;
+ remove_dir_all(image_dir)?;
Ok(())
}
#[test]
fn test_whiteout_symlink() -> Result<()> {
+ let image_dir = make_tmp_dir("/tmp/", None)?;
+ let image_path = image_dir.join("oci_image.tar");
+ OciTarImageBuilder::default()
+ .layer(vec![
+ LayerEntry::file("etc/passwd", b"passwd"),
+ LayerEntry::symlink("localetc", "etc"),
+ ])
+ .layer(vec![LayerEntry::file(".wh.localetc", b"")])
+ .build(&image_path)?;
let extract_dir = make_tmp_dir("/tmp/", None)?;
- parse_and_extract_image(
- &"tests/oci_image_data/oci_test_whiteout_symlink.tar".into(),
- &extract_dir,
- Some(&Arch::Amd64),
- )?;
+ parse_and_extract_image(&image_path, &extract_dir, Some(&Arch::Amd64))?;
assert!(extract_dir.join("etc/passwd").exists());
assert!(!extract_dir.join("localetc").exists());
// Cleanup
remove_dir_all(extract_dir)?;
+ remove_dir_all(image_dir)?;
Ok(())
}
#[test]
fn test_whiteout_dead_symlink_parent() -> Result<()> {
+ let image_dir = make_tmp_dir("/tmp/", None)?;
+ let image_path = image_dir.join("oci_image.tar");
+ OciTarImageBuilder::default()
+ .layer(vec![
+ LayerEntry::file("etc/passwd", b"passwd"),
+ LayerEntry::symlink("localetc", "dne"),
+ ])
+ .layer(vec![LayerEntry::file("localetc/.wh.etc", b"")])
+ .build(&image_path)?;
let extract_dir = make_tmp_dir("/tmp/", None)?;
- parse_and_extract_image(
- &"tests/oci_image_data/oci_test_whiteout_dead_symlink_parent.tar".into(),
- &extract_dir,
- Some(&Arch::Amd64),
- )?;
+ parse_and_extract_image(&image_path, &extract_dir, Some(&Arch::Amd64))?;
assert!(extract_dir.join("etc/passwd").exists());
// Cleanup
remove_dir_all(extract_dir)?;
+ remove_dir_all(image_dir)?;
Ok(())
}
diff --git a/proxmox-oci/tests/helper/mod.rs b/proxmox-oci/tests/helper/mod.rs
new file mode 100644
index 00000000..734a09f8
--- /dev/null
+++ b/proxmox-oci/tests/helper/mod.rs
@@ -0,0 +1,3 @@
+#![allow(dead_code)]
+mod oci_tar_image_builder;
+pub use oci_tar_image_builder::{LayerEntry, OciTarImageBuilder};
diff --git a/proxmox-oci/tests/helper/oci_tar_image_builder.rs b/proxmox-oci/tests/helper/oci_tar_image_builder.rs
new file mode 100644
index 00000000..c959b51a
--- /dev/null
+++ b/proxmox-oci/tests/helper/oci_tar_image_builder.rs
@@ -0,0 +1,171 @@
+use std::fs::write;
+use std::io::Write;
+use std::path::{Path, PathBuf};
+use std::str::FromStr;
+
+use anyhow::Result;
+use flate2::write::GzEncoder;
+use flate2::Compression;
+use nix::unistd::{getegid, geteuid};
+use oci_spec::image::{
+ Arch, Descriptor, DescriptorBuilder, ImageConfigurationBuilder, ImageIndexBuilder,
+ ImageManifestBuilder, MediaType, OciLayoutBuilder, RootFsBuilder, Sha256Digest,
+};
+use sha2::{Digest, Sha256};
+
+pub struct LayerEntry {
+ path: PathBuf,
+ kind: EntryKind,
+}
+
+enum EntryKind {
+ File(Vec<u8>),
+ Dir,
+ Symlink(PathBuf),
+}
+
+impl LayerEntry {
+ pub fn file(path: impl Into<PathBuf>, content: impl Into<Vec<u8>>) -> Self {
+ Self {
+ path: path.into(),
+ kind: EntryKind::File(content.into()),
+ }
+ }
+
+ pub fn dir(path: impl Into<PathBuf>) -> Self {
+ Self {
+ path: path.into(),
+ kind: EntryKind::Dir,
+ }
+ }
+
+ pub fn symlink(path: impl Into<PathBuf>, target: impl Into<PathBuf>) -> Self {
+ Self {
+ path: path.into(),
+ kind: EntryKind::Symlink(target.into()),
+ }
+ }
+}
+
+#[derive(Default)]
+pub struct OciTarImageBuilder {
+ layers: Vec<Vec<LayerEntry>>,
+}
+
+impl OciTarImageBuilder {
+ pub fn layer(mut self, entries: Vec<LayerEntry>) -> Self {
+ self.layers.push(entries);
+ self
+ }
+
+ pub fn build<P: AsRef<Path>>(self, oci_image_path: P) -> Result<()> {
+ let mut tar = tar::Builder::new(Vec::new());
+
+ let mut diff_ids = Vec::with_capacity(self.layers.len());
+ let mut layer_descriptors = Vec::with_capacity(self.layers.len());
+
+ let mut header = tar::Header::new_old();
+ header.set_uid(geteuid().as_raw().into());
+ header.set_gid(getegid().as_raw().into());
+
+ for entries in self.layers {
+ let mut layer_tar = tar::Builder::new(Vec::new());
+
+ for entry in entries {
+ let mut header = header.clone();
+ let content = match entry.kind {
+ EntryKind::File(content) => {
+ header.set_entry_type(tar::EntryType::Regular);
+ content
+ }
+ EntryKind::Dir => {
+ header.set_entry_type(tar::EntryType::Directory);
+ vec![]
+ }
+ EntryKind::Symlink(target) => {
+ header.set_entry_type(tar::EntryType::Symlink);
+ header.set_link_name(target)?;
+ vec![]
+ }
+ };
+ header.set_size(content.len() as u64);
+ header.set_cksum();
+ layer_tar.append_data(&mut header, entry.path, &*content)?;
+ }
+
+ let layer_bytes = layer_tar.into_inner()?;
+ diff_ids.push(format!("sha256:{}", sha256(&layer_bytes)));
+
+ let mut gz = GzEncoder::new(Vec::new(), Compression::fast());
+ gz.write_all(&layer_bytes)?;
+ let layer_descriptor = add_blob(&mut tar, MediaType::ImageLayerGzip, &gz.finish()?)?;
+ layer_descriptors.push(layer_descriptor);
+ }
+
+ let rootfs = RootFsBuilder::default()
+ .typ("layers")
+ .diff_ids(diff_ids)
+ .build()?;
+ let image_config = ImageConfigurationBuilder::default()
+ .architecture(Arch::Amd64)
+ .os("linux")
+ .rootfs(rootfs)
+ .build()?;
+ let config_descriptor = add_blob(
+ &mut tar,
+ MediaType::ImageConfig,
+ &image_config.to_string()?.into_bytes(),
+ )?;
+
+ let manifest = ImageManifestBuilder::default()
+ .schema_version(2u32)
+ .config(config_descriptor)
+ .layers(layer_descriptors)
+ .build()?;
+ let manifest_descriptor = add_blob(
+ &mut tar,
+ MediaType::ImageManifest,
+ &manifest.to_string()?.into_bytes(),
+ )?;
+
+ let index = ImageIndexBuilder::default()
+ .schema_version(2u32)
+ .manifests([manifest_descriptor])
+ .build()?;
+ let index_bytes = index.to_string()?.into_bytes();
+ add_file(&mut tar, "index.json", &index_bytes)?;
+
+ let layout = OciLayoutBuilder::default()
+ .image_layout_version("1.0.0")
+ .build()?;
+ let layout_bytes = layout.to_string()?.into_bytes();
+ add_file(&mut tar, "oci-layout", &layout_bytes)?;
+
+ Ok(write(oci_image_path, tar.into_inner()?)?)
+ }
+}
+
+fn sha256(data: &[u8]) -> Sha256Digest {
+ Sha256Digest::from_str(&format!("{:x}", Sha256::digest(data))).expect("digest must be valid")
+}
+
+fn add_blob<W: Write>(
+ tar: &mut tar::Builder<W>,
+ media_type: MediaType,
+ data: &[u8],
+) -> oci_spec::Result<Descriptor> {
+ let hash = sha256(data);
+ add_file(tar, &format!("blobs/sha256/{hash}"), data)?;
+ DescriptorBuilder::default()
+ .media_type(media_type)
+ .digest(hash)
+ .size(data.len() as u64)
+ .build()
+}
+
+fn add_file<W: Write>(tar: &mut tar::Builder<W>, path: &str, data: &[u8]) -> std::io::Result<()> {
+ let mut header = tar::Header::new_old();
+ header.set_size(data.len() as u64);
+ header.set_cksum();
+ tar.append_data(&mut header, path, data)
+}
diff --git a/proxmox-oci/tests/oci_image_data/oci_test_replace_dir_with_file.tar b/proxmox-oci/tests/oci_image_data/oci_test_replace_dir_with_file.tar
deleted file mode 100644
index c4e488602eef13d5cee53710b97ffce5bf0586c7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 8704
zcmeHM&1+m$6n|QyVekvPu!!jJ7DcEtz26_fjUW-xO=)nU1i7D?C&^5hnS`b_P+h2K
z79#!uqM&R23oN*(I}xdi2trrlN_Q@b^}ILJn3;5Dsxt|dytjDo&3X5pd+xdC_q*qw
zv8yfHIh!2nh2WB$C;1bu;pcu??;Rt7MN;L5YE@tPMyG4q)oRjiwYuZRoAiBL-@Evm
zE!Mx&FocW43WI!6|K0jyLCW<%lBgM2|ELX7hz4(QjE-WC48cM>$A!}|Xb^I%i13jp
zB_y^0Qy-O%&`Mx53a|P43&w_Vf9p3QjO@Kb(*zO11WKytC_He?@&ELP^YgW@Yguwa
zN#bK<Q8CY`MZ{r+NidQyucF0_aYBrXNJfKLkd~|H;2AYj0^3OHz@y2_wU@4~e2P(W
zZ|D4Z^w533veUcYe{=Qc%g<l=<l4h0-u~hG$KR%NbMJn3<Hloe{WkyIBj-M<?A(0e
zi7yj!{g)rt*<UYSdFIsI=a;`o61DqNn#><X2ps1z2Jp`bV@xTFF!v!wZ#>7$M_68O
zDHlKj+zO?L3I^`ZAdLbt)*1yQpuHa9$cgxuco_eJl=vUv&Dn}`{I|c#@eiwv5Y`+i
z%_#QDD9?>l!f5zHsl>#{U;*xeMZ*mZR(c++h7Cb!>djR6-@WI9C3^DYbAPnnf9mGx
z#l;6J_p{B%Pwo8vr+l*Uz|K48P-PLA;n5_iTz#*dRA%dhW2|ie|Hf0~gEY~>)-JFE
zOe4#Q*DPx3uy<B_>?IR~TWJ`8U-BTN6tG=OhV2MH=J+3z|6xK8;GeM)|0BFPTk)kz
zwVHNZBdnQML%Wl;n(0E7Jey0`g3rv-)_MR*YS!0RGiSQc;Ou78*IO>DXKQ99)YnWi
zi=or4Z{jm=cA$UJ*|nN6TY;YW0C%pe*KI%*boSW_43L}AJE$xK#T4e0GptP@LSyQQ
zPyqr7Qqstb&chRXL9qymAdZ+ckh{o8onu0Y!p3~!*~NTzlyb0gyD)s!Y=Iv@_<CV@
z&-^=|K+zrS&)M+I%EfHGKh*7JG3|EykLvzBu*&DrpGmdv`opn(+M~ij+Xd;_4)^8C
zcFFLw#rY_01N=WNtVRqnf&UT5ayb7(f|uvN5$>F+xZr=&c8#nXTz8}0Bl|TkSb@;g
zwS(yfpK~ukgx4^sA-sg~0@4eJ*QpSM!f~Cw)@$C#I^9-#E2q!pf=*jGm8Pp%bK^p<
zMP5gXxv;-6bc+op?bB}Fr=ZFh-^e^P>#;D1`pgft2uGZx!Uiv`ih(o1p#~8VCC&?O
zh-X1K2{w^HwDlnn4|NP<yblb=eY{iDycP_TmPo^6aF~KVL;}{76X}sNoLUM=F{6|+
zDX7QJ2;&eWM3yNpky1V_EMA8D_WzN!vZfCg>iNDs)36#)R-FG1)_wOdPx(;(hoSNW
z^}n+IGvLNU`BC71ME=)L?EZT)blcRh5AdOkZrY>AK3w;5IwAVGP?=AR3mnMfYrws&
zjj?}zjMFgr+a&xWD)zVl+9n9_k6DTT$)26Q#ig`3#l2F5z}^Wk#dTCi>Gt&cOAVz5
ON)MDCC_Qj@df;!g^|Z$T
diff --git a/proxmox-oci/tests/oci_image_data/oci_test_replace_file.tar b/proxmox-oci/tests/oci_image_data/oci_test_replace_file.tar
deleted file mode 100644
index 77922f7dbb6588a25e2b2514ec017d7327469d06..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 8704
zcmeHMOK%)S5FQ8tYsE|CKolWZ%^^Yx-gNc5EiOpN5`s$<iv!3){j>+!yVma7iW4jW
z2cAA4#1BCH1O5S#I0R0JLoVUO32}lG93qA8*|p;}nYHomq9A4to>fg(b#+yL)%}&t
zTF3M*W;1<Id<0`zddKJR`=D&_8xRMcHQ7wP8XDj1^>w$|%(|UUf82aWeIKWLAAd7t
z{(Gw$Gd`<rkdpe(@(&!>`TtjT%}D++fRIKz!KHHsdl8hy-Un`p2S5T_K+?wn$V<b8
z4+a}a7-B}NAf>7B_=x-iCa_l%2KdJW0n3`G!roNH|8x9bYc!jA&#wA){kre=icULU
zXyO-=bltl`FKuu5D9QE4##&)@KMuIK)po6pEn3C8Uh%DU-7bRf^;=tT;q6}3FO_Yl
z9g3BxnI<^Cv4Pr%si^FVl{i6iV^F9Ts00c@JE;w2PAE%t+=?1g3Pcmeq`<@qh?|me
z#Dca86HbNJAp|2els=|~7gy8j2w~C7ozn3&y&dBag>ROQ58OZg0!sDhe=D9U7gnwo
z8^fvYwF-lDVAvAN4Kf0G4cZ3~iaTPRB$U~JAut8fsfa$$t@27SWQj6Da(&nIa2<eg
z>2$f0<}mcL@f~qVg(nz0<B;Jt_z<*mL^^O_ENH}})8K^%=@o&1m9boa5fpjHX|?Zh
z1<Q?{##BLG8>@=INd2EQsTGr?qRuJZtMP~52n61f4eLJ^>HM$je?>s2D1PqKxw*#I
z^F?+Fr;?SuI{(Vel`jEh5B4r!Mvp!83q619hi`8D^zKX7zqtAMsrP>T`SWk{)2Bc9
z>h|rY-uZRzyC*Jv*4VxC^0`|Ne6mE&oO$v0&PUJQIls90XyakJ_4L`@-~JTmRv+1Y
z{}O5}UVr}VlUert$9Mk7YIsjEhm)8Z!T+QOQiUTYz(1?;UlGhHixd94CH~7R%PjE!
z%qadFH$Lpv_@8nbPi$@k|C3&;E4)bfAIJY0h{NYUB{l!6h~{*~CI8c1yIS<U?QeDm
zWN&@%hMwE5*M092_reIXdBF1smH-xzT0pEtILDC$Q2IuBq0d)~Ucb}bPV{NHq*I+l
zrSi3+y?JFYBK6Ti5)O%Bza*IXkai`Vk}8GpR^j5X0Sk+wA@kEz7%Vgk-U5-qBkVyD
zhJ`~`GhzrrKnWpKaN@vft}Swk8Y-PYQn~}YqwIMt#6AaA0eQk46*3~gd4`--#866{
z3YY?=+<_9*IN`JfZWMNcXm7nCEH6D?j(>Oli>#$+JAb8>c>8qs)j@0J`TzI6?>^=U
zJJkOHV5q+T9}MBlewX;K=>H5GJ11|3+_N<_1o)wj&ZMo!1GpaabU05vorKD|pD<?k
z#6I49ti7GhvH$!SW8fH{j>118e7_dNu^Ec^2U_$0V}y3%A=mP<i~Cx+1@=3@IkZp<
X<vSCbuMN}@s3TBEppL+O8iBt6LZ+LJ
diff --git a/proxmox-oci/tests/oci_image_data/oci_test_replace_file_with_dir.tar b/proxmox-oci/tests/oci_image_data/oci_test_replace_file_with_dir.tar
deleted file mode 100644
index 24743290414dc36a3cf3695b298b567932c5d812..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 8704
zcmeHM&1)n@6mMOlVekw0;3A?!9~NPq+4}wnUIdAVUX~3Wlpyt)v?McOW)e2L238L$
znuCacfGFr${{k00tTz!^4-teti6^~zSX^IsPhv8g&aBQvR_s1>XI@pkdhb>Je)a0b
zu5@kxY;vp*f=6<m<X?D3zx!q7-xvujk|sY^tA@(g`vcQ!Hj`erJ2+~-aqUNqy@T6q
zvHtyKL%2AuZICbO-&=nyNWK35%C0%E{)ijPh{g&V7r6@>bBCQV+)#!PM>-mAtuhu<
z>6LOUNZ}Rb$T};G3KbTQS$|9@-sOZ6|AYv_lP0RrH&yZf9RHUZ&1Twn%VE{L9D4n%
z+ezn|<mp_x8hmCJHrE13QnR+Uk~uSg4rezyzTI_MJ6knNp}lH4Sq%L_djp?&y$|Dy
z!LHkh*%FM*C%AoO<*);)V6e}YV1nF?lBnjQ<*;c87J(2$v5zq*M{U%Baiy7J40A<I
zP!<VA1$7)__$`UkByj2q8*|6Ai@A4{a<Fo%Fnq;qLL5N&YGHV3{_Q(Z3<vw$aH^bH
zx|ppEr#j3FP8eefY{cA$7`^cvGam)E-cl}v)7%QBhzbVY&LE8fGS(UumDXPWrF!TG
zR=FQTPnyHfACK)(8=?>m-r^V?#T*$}4(%KVvt!U8<W>>kBT-67Y~e)rV0MIF0waE_
z?ShoH!+Wu@)tD;CYh_gtIKcmt!m47DG5n7>mZSWSnXLK0BAind7yNH}ZaEtSH(2kL
zWWVYKD-fExUND2;bM7UG@D?U5gcmTLLwXMJHWh+U0zCFg*?l?d54ye0oIV!|I_>6E
znyzG>^$TT>JdcjKaCk5biUTGc(r!Mcpvo9u%RF=|Sr|k^<~K}QA`OqhVX9(4Bw$TB
zksdk2sig>EMk!@dP!G9_Fb;XmEK^=0rTjkLDRSO9U@S+Rq{0R-EokISaA2y4C~;nJ
zLp%$@NpO+`qOA{scwjqYyblb=w6J&)-dq1g);fUyNe`rootfibFt&^F(JvzMko*tT
z_^$}(RK-ueKRes|qLn2lAngF`XpSI(f|N=b<++hc7!56yN=%FlkYX{x;2L0Pu+sBj
zHJtKFQ*ZK&CwZ~;!nLK3F-q?4pFfWtxaVhfdgt4(uKsxW*()Did+@}Y-(COk>vU%3
z?N4spc;t;=X1{sp+y{;Ao6kMAbJu$d^yJBBe(S#b#Ld(5^Y=IIWgCy4+Wz%-`S|jE
z+i#sijrl82oq9M)8du-xC3SW%txa$M|C1(l6-JH4KO?)GkatZGaIL8EUlGmeigWz8
zzRdBjB!PPri;8(hEg}xe03^VjiFp+*W{ksK%S9xkL2&W6T*bTq0ED1`AR?Iv|DPx1
z`cL1lu|J*%l+S#6`LiTZJ3pk!>~y`YwT(s~>-cb?o!{F>Tc-EB!2hjv-#yGzK63tJ
zxK2X-ude@0Zw;z675RTf{byL%`RB!uLrX)$1b?KWGim8@UtV9<bc7hzLh5=#)!OHB
zsN=QZ?$upC@}D0^X&B!&4*!UXJuWEDf51OxHU7s(cJdyV(xQs{Qn3a0D!?gjqc%#n
VCf8qUs3TBEppHNtfjct-e*)yOwi^Hd
diff --git a/proxmox-oci/tests/oci_image_data/oci_test_whiteout_current_directory.tar b/proxmox-oci/tests/oci_image_data/oci_test_whiteout_current_directory.tar
deleted file mode 100644
index 56b34cfd774b74b8410839bb48333a38409b70d9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 8704
zcmeHLO^6&t6mB*q#3g!342vKc1`LtSPO9p4Rdp|tlb4`}#RLxti(9`lz0A)tGaIrA
zYd}yC&DoGcSn(o)H&34Q5IiafdhsfF^&%b&@m0@cC$r;j;?B&%V%MR6URS+(^<I77
zd)2z$(wz&@R2#v@35miT+s^xwvfeW#OtPrNr)pJS`Ff|T+Gx_aa|O$>Z7*(IeFrpN
z=kf2<6ysuA+aUPmzr~*dDdK-1J76gOh7zk%sbfF{aw3>ad7PwPLP`@Qq@!SgE5ekv
z95|;$0+&h%pK!~q-o@e&|M&@Lgm-L@p+XqY?dM$1C<q>v#>V6>_6&*t=lDPK@$utd
z-219Fb3_3M3OoUoKuTCDXyUnZi2}*EW&&G^`@j=rg-nEuDL9kr*gC^}0ua5qaOvk?
z=70F{C$semiDuyBN%F#TzsGkQwbhl?dc9WHCr-(jaPF4K%GQx{3zbXfXBIzr`TiS!
z{(5fi=;te^PPC)w{`@zuM#qLiRJ=^j14H=Nf+4Dj2PzE}OgP|H#lW>pxC8?>rkW^W
zK&3(%%?T5!L1-KB+6mY<{>6X``uLX=3j9wm>I2OI|7X7p_}8GBN?FRZrHNoj?x`lR
zaUMj>ElG*dNcSKGc;cAQQgDt}#vzf;Tc6{<x<wKCoy(Vd(0_R5#f$GD`3nKnCF1&^
ze|u?V?z7TMbB~UG^x(m7uYG;zHgd)5f3!Y4{phSe_U&JC?#}IdN3MSVu*V9Yy#L+v
z(Z#>-ej3dV>@J=r<AEXkQ|B3mR(PeX3aNk+ZG^{N5Ku2uP$psCSR+-;4fj$zNW9Tl
zA(&XH{o<cfxg-BGDX{)4^8aLFyqA_+v!zm5wM{MSI@4WmyYeEwH>`-u=ffw{cB<=a
zkTR?Z7f7<e_!UYQNxDdQ1q7xH#^U&DuX`=)bX)BW?0#)IAK&VPq4lh}exui;-D-7x
z5Qdp?g6_r|&RMRj4cG4ET~KH<@88WVcDt7MLQ(ICvN$eF^=B9;9JlN#=LRn0b#r#}
z@DbDy{*{P5!E#Rv=egz~scWSrW_Xrb=DeXPagI~Py}@)(EMbnOoZ8rtSaG(?MhnIM
z9`!#Rt^XO5w7~x^?wqJN$A8DvTtmHs0L)rVgeJ?O+i*5hS8{kFC9JL0Go!lL;llN%
zt+Y&5$r`HaDh<`lyz6u;*XjIf2gmn#qt*0TbpZ2cRA%yFL#lE*sNw{HNct==ZlZe3
zGo9>aAUpsb@S7XnCn6-U9N0aULK~iO0r_yWzk+|2=BqcewE^MSY{x3bJ#G(F_t!x=
z<VNQ!DfJn4I<}8{R2a2gik|IwT|SIVI#F02n6j*C-Hl4X?ewO63jY(}JO2MrN@ZN|
z|MVg<(7YG__lZ3eYx^U^e@zW})i=V0<CY#Hd?G~P^iY)*d@>04$P?!A1<YBk_3p^0
zi3y&De*$9o{6{ICH46MsEC72bx>e4rxVQ2xuw4O`X@yisd2^3}#izmpg$D``6dpL#
G9{2}Zftk|)
diff --git a/proxmox-oci/tests/oci_image_data/oci_test_whiteout_dead_symlink_parent.tar b/proxmox-oci/tests/oci_image_data/oci_test_whiteout_dead_symlink_parent.tar
deleted file mode 100644
index b1b5094689402cce0433174f79c4595c10dae392..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 8704
zcmeHLU5Hdw93K=H8)k*T@*$~h?Bl_9JfHX6yDu7)U}~C5LLuw<+`YOpv(DTVM_baO
zAYADo>Y-?%5A&&njE$_fC=7)xq8@w*q`)2`33^Df?SJo#wzKQBqq8eW_dMLW_dn<3
zcmC)6e&>JwYN)KLt1|Oi5EPD3CjNyo{dcOZ{*Dn5B-6v^6;-42k!mC>0IAclV&qV+
zPOj7bZc=-dtbcV-67J2{Hi-Rled~`YO4t9U?0}~AR}9ukVro2PJ>_}MNyM#2fwDeB
z#Bt(dC#AHOAdh=SaxN&>0aWz_30w=r@%pnV)QG>KT%igk6kmC-+X=xQtbfOxY=NiA
z{6FXafoxAtzN!apQ9fxa)v#R3_w|s6Vr$WwP;RRYTd?Hi@bFNmWds#g?Jb!?S%-zN
zC<knzC`+NU)u^x+uiRCI_DN%1F1c_3TE+vk-&ws`Q&-T~gaa@@45KboeLm6>Nx`fV
z#%e#XlpA5K@QAXKD<iQMJfMNoL}&>WxUkwGB1yoBQY^t3PdwZo&yG?KC`S|EL$U^b
z0OQjM@H+hVCy+D;`~^5wRu1eBhZ{p(YZjg&fKvya(@X$DBb*b+X(N@4>Eswuz&hbH
zwH#qfg+)GPK2yeUYuvwGH|BvENkAtv>1nurez03(F)$yP>LeG+cvx{PsHKi6t&ugv
zC*X2VBdwiKm=i%2p^SQ#IAwyF*r}*vhv$y$Xts%@>BoF|ph^EbrBw@%v8ext{v+5p
z)AgTwBGvyE?wnI|qW`j@2gAtfXrxjX`=asc8kyG>D<f-S?InotUgY-@z769(6!alp
zpq@u4A&fnh5IR2?R-<yI7R%?3L{7`Gl;(%R(#XDgjY_#3x!Bk^7^38W$v0#-Zj(r*
zbN!)#YIPL`Q$zV7Bq0nGQwClTXhS6gCmacewWL@&%(!q6#xQF*NE0`V351!mL4YK4
zN=(t6B<AhYR2$FZ92A!Y4B}1(T4g|kaUeA%Txp+!;ChrGUm=0H&$-r?_)J^h1YSNt
zyaS%2x1wq_@xRjpsm0EmjsFns&EUVlDgRrzb570o9A3P*cHx7;1q+p|+Bj;-{Q4cv
z9z?lCXO|xp=$nc0V}l>Rt?oEp9^SI_!4=us`janQ{N?4XTMr_$WX~J>#+Utea^lXh
z=a-$SWmg=3=KQJ4dsg2bOy2v`XCHm|=ecu#UB=Jmf4@7o>+kdLp4k55YnL9luW)G7
zAFH4E`IE`h6NfKNzPjbHFSFwp-&&u^&FRF_&f4-o6aPC6>ROCAJO5|g{}^K_|690o
zPR%j@FTDPK%zrrPcb7+^{s`_`{oCV!0KOiv(rm32;Q-&gSypT*N+ja+SDPL`v#xjD
z_dl%s`s~7Qb1c)fW~WmN-aC|ev+G3n#_kPAj&vW{ICkj#i)+_*xm>m@7iErqasNw?
zt~s{(^H)xd-?iwSolD1_dw5Ca)NP+G&veb{oYKzP_dr-Oc3&aBx3}NsdTY+cf6Axv
zA7d<1{$H<~Z>W9}|F_8hG!i>Eo(#EWYN!$5Ps`|ZntGfP*Vl785Ys1-`6xWod_v2;
z0eQS$xO;)px2)3fAG7fv(P{BN#&Fk6&;O1c-$n-q@<|qVL$U>~W`Og!fC?x-+C~Ry
RmDB^N2T~8D9=Ihv@DEuzwG;pV
diff --git a/proxmox-oci/tests/oci_image_data/oci_test_whiteout_root_breakout.tar b/proxmox-oci/tests/oci_image_data/oci_test_whiteout_root_breakout.tar
deleted file mode 100644
index 36e25851148064fdc39d0fee90bdd5762e187989..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 7168
zcmeHL%ZeLE6m35+X2`5;jCT=D7J<pM>)BPMW!8aU7_vwhl6sDMkko_JV>}+TF=Uf?
zX^1fd@&oya{6Gx;iF`tqxm8j|mNN2;qmc=5*P_*Zse9`_>eRU<)343=LAKF>U~q)8
z_zPqC_f6UK9U~%0*5MoVYG(X++~^UwwC-Bba~NmAt!wW+>6=vlaZeLoZfYCEyu4fe
zF-2|t-^&hIsK0ewIa~(kC^gD)jhPqHV?|sUj0s-DgHVd8@|H{M5n&2Di<~x$yK;rc
zvHt80XvA+Ae?tWc%Fo`DoRE^ztg|*ISNO9a{=o5ny4C6AW83os{goe$t9qDsJLIz{
z9e7viy^|vkl3X7h^((6znDF4y&=s|<ifW(_d@<0&D)@0zJi<GNW6)2^wjPG+05szQ
zmp3+5TQCL6t~!7Pq8rnLs#_ApFcZo$;%Mn4a{+5CEi+0A%T>VEawlC$L<kD@rqwba
zZIF;9Gu|X0W8l@37#-mZyqqM*`}zd(0K#vQ<5Tx9A3#zE{|jK1or5RU(QK*nqOfI<
zAq1p?S2zH+N`(PU97K#sf+?VmDW^Tv)=<wF^IS>`N+2{r&P~taz)U8mC-B_gnrtm>
z^z%O!@xP`+=P!}4{Wkm)!j|zbIBM~~BAr(%{`kk+x4(b+Yw!9E&kz<$Ifton0TFHq
z6h=FQgAiJ1!%JIg*npCIg(TB)<5DAm2pEwDXRmjDfA!k_vWv3o^v)f$ee)0YV$eJM
z?y%qQ_030j#myh?<4^CSSJ$53`{|Q=*M9zd`^)@vc=y@UhiL1T%Cf!R{@l)PU1@l&
zu?sS=fd6%m)fH<+vVR-?sVJB64^2jk{}t)HQgPycJ+i&3@wPc0P04=XN;c#1k=KoP
zk$VZ83A;${626CV7pX4d1uaWL;h11wPp9{)aZ`^@B7N>BI;|s>=KX4T{CGNJRM$<2
z!dYX`qy{6O(Qed9R2jmzm4j(h7LHV%t|(n5EM?Af?X^^f2%)&P*a72vhdB<$y5KR)
z2o4KgBBr>Y5(zl0IEB+IPYdkBb8<O?ywYs{_l#9T=N}ibZ`+)27vi7eMf_uo1#9uY
zxr)p!C;YGI|7VT;zi)=my&B8_zSPmLd-eQBFU*8UP=AMBc%GFH=MC<0yKwf_$Ia$q
zz6k$_F7ZFcz%?!YH&>Cl<<mUf;=f2+;OrlO92clS`D8w?eQPt&W}wYLn}PpV2L1xB
CF8omd
diff --git a/proxmox-oci/tests/oci_image_data/oci_test_whiteout_root_parent_breakout.tar b/proxmox-oci/tests/oci_image_data/oci_test_whiteout_root_parent_breakout.tar
deleted file mode 100644
index 12421d00acc42a589f2ccaf50cd085ceb34c4ad4..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 7168
zcmeHKOK%iM5MCK4LKd9h5OKlU6Ucbz_hS#7azWyd1L6R(a8EzHW9{x(J7a`FK61)A
zQbeQ(DYr=ZEs5kSKOny#XR3P_n>DPxWV{?;TH2kNn(FH6>iWK_$p>X#-R&%OAQ&8>
zPQ1c6ef>~2xyOh|(pl$A^=fK-zpBj`Txz;j^c=?V=9=33Li6)<{#D-)E|!%BF)p8X
z{+Ocn{J%&B%$&bRURY+OVT36{xz@(B;JGANGR+ZIG&fdR61byMGR3^l9aYo@NFQqE
zcpT54eE^O44C6gi5S8NiKFJA*m-WV&oa4`o_#4On%eD3Ot{K~YQF~kOkA1fX&qF6z
z_fC9e$KKT5MJYjqZz8ox_(P0)NcRxWs1Sq_!r0@9dcUaZa(n>lPqxzhvWim&#c2Qe
zL}Of*b%?^aGAvLZ?7^DdfjRKwDye|b6(Kw=9H>1>S|FNGR8K%^Qj9E;!C<Ym@_{3Z
zEz=5HDRU}_7M5efl)#EeYLK)H(pFgoa@|e#w&4G8?Qm@-6TZoZ8T^NUbFNS>1f^Cp
zs&nhDM<`&;92F2s=Q!t-IW3G*7;7WAl))KE16E>A1S8nb!oQ^aWBk(=|8v55q2h%9
z%J%)xJOTg~<p`ij5_E^&73N`rCs4xP-k`9i28FxNMlLIDkrhL;<Fla|6~R|^_6%?A
zRxp3U8|5ezJ0~z-(3nlrW=thI*ntHikxW^jX`y=0Gga{-5+30!5<+r(N<=_li76&5
z1wJgefixZb&!DT^*m+UxO_%!AE;!{zX>CJp19l2wL0JeWXsn#nNWf19flzKVWr%Z)
zCD)vq96KJMN}rgX?gKNOoIZsAt;OhV2LDYRnv<F5;h&Jx_=iZy7XNd?d7<K)KVQD=
zU;ou#xzx0>c8)gw{^#h(zPXJ$EA-kmbanM#_Uo{}yS+OY^auHs>vHu^x&0H`esk&8
zW_JJ1O7GQ;-+%n??X4fa`(yk1m2s!@%WtdqI^SRD{#s*aN1zxv|2&JleYRecx98!X
zay(oAF^2Dr7XM9RzUbVu>i@K`$7cQi6~j-q2C3_J#i@$kwDtU`7BVS6w-zoMv#&`H
z`nXN#S<3x-dAm9f|A?OY{>K=;HCy~I??g^4zwD+i{y|EC<1c_N&QONBhbMaNT^oTm
N0&N7^2z*@;cn3S&@<;#x
diff --git a/proxmox-oci/tests/oci_image_data/oci_test_whiteout_symlink.tar b/proxmox-oci/tests/oci_image_data/oci_test_whiteout_symlink.tar
deleted file mode 100644
index 7e6835cab889566cdf1d8dc1a42b69642b9d0463..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 8704
zcmeHL-D_M$6u(Kdl$bo!hEVjuuoMlZ+0OUeSrC0Fg`j95ML`M8d}eRDA8~h6l9oV0
z{D3?Og28|WKVF0iz6t&VN?QyFeG)_p;;RUKlGd5K+nSBtW|K_{#XApo?>&3Y%$YOu
z`^}l7N>x=q869W?zEJ?8@ax<5->tIdI|PWMXpA1HSFO$$>kV1+F7-NA@Z7h1lk2s=
zhh(qP^{*EtqU@lyL5R!l)*oV!t^Y&W0d4EAq*e@AV2ISxafCP!MiL+ew}v2zfmFc8
zmRT875JP7PHc&IHsWMWU4jzZ~CtIKqzJ0q36^Jmr``(lz#4wM>dd6f2f7-<VbNpW#
z92?8kb<vjP>$X-;s+C+}44nwlvNef3yS!k%BqtXZN{N;YuW<50#pJ6x$tPtwXY*xQ
zNt~@W@)zL5eBIlp#=2T@$(*+g19ab6)2yv4Z)}n|KR|G!NmK>R9T6I92_W<vRT3`!
z282ooY$SukQ7a9B8WE$d<{Sz|B_x(;MF@2~^)XC5xfo`LG4)=qq>h*5vX6rozLh%O
zbiexvq~_lLygyYY<}M}+t)cEWi`WSvIOA3d<6#DcWJDN?Bw@tH0>uhqOtdrrN+hHM
zkj26xU~vqv=IGz9Tl0W8PMuC?GS&+H!T64ViMg{%OR1cSjmE}uj$v$L=vRUPg#^<a
zBO@3i$V)L$R1hGvl@5Xb`i{aH_*L-FnZcF8Hjri?2Ni)f{_ho59h?lL{s8_56!Pu-
zPchE;ze70pRh;s_tm$IXu)48WYm$B0Fp?rPr)yR=tO?wU0HTv1o<#I4gasf9faWn{
z2qQ$un@#m%Qg2ji%Yi;;QaY^$D$SLW%HmQ}qgJgpToASnhDLh8<XW^FY*MOp?p$KL
zT9bvnsKxwTJIDluK%$sAE@BN7r^-_$@~$8zrFKFwEQkY?P>rde3L~MNCW^%I7T!s7
z-h%a7ELMQ|Kc!?wX-~aA*P%ef2KfVpSVlQyRzM4lLR@j@6CbT(M|`4$bE(HO{<-of
zvQ``Zdp(dk?983;k09EHf5;)s@ZTYv`zn5B_3+`%>)#an2b8Sa=;g_&8*>{FME%nP
z1E73)O3U^2^))cQhBo^?8vXeAXy27D-+S)E7x<}{o(H#|cye|1>U8nxJI^lN{B?-l
z9v&XPe(l)E(CM3>{eJnz+b<3t;y?WO+N;<4M*H9S`fpAM<K_(b{M+wO|8-~l*yCT!
z9v_Hi|NQE=XlP$2m37v21lsW5Yf{%?)Sd7TIo*bTglLBU4$<6Salrp~pIiy}_b2`N
z>SE(u!{4>ey%7=u|24f__J{ZRaGi;Mp7?3=YJl_9<doYu;z<G@Jqm^&`-7~Ni}SPd
zrBbn^hDJQhA#-QI?8d<OWPa*If8pJyK0S5omlW_LL$xUS;MV&`qC@*Tk*v2pMIfmd
zyOa<2_C1+*WwaCiu?Kt5X|>2->LDlD`QKG=dsIsE{|@z^R$*uF#gO}!hFS^!wu(-#
zrN=FKeY2*+SXNKyVsH35-lV^Kd8Y3|d5<aq*AKe?1I)JL-`_Pe{O>W`yE40!ORKoA
hq+8%#1vm%uAP;gYyXq=a&LWUSAd5g2fk!9;{{UmyntT8N
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-03-24 15:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-24 15:35 [PATCH proxmox 0/2] oci: tests: refactor to drop static test tarballs Filip Schauer
2026-03-24 15:35 ` [PATCH proxmox 1/2] oci: tests: return Result from tests to avoid unwrap calls Filip Schauer
2026-03-24 15:35 ` [PATCH proxmox 2/2] oci: tests: generate OCI test images on the fly Filip Schauer
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.