diff --git a/SOURCES/0001-compose-Handle-embedded-whiteouts.patch b/SOURCES/0001-compose-Handle-embedded-whiteouts.patch new file mode 100644 index 0000000..39ad676 --- /dev/null +++ b/SOURCES/0001-compose-Handle-embedded-whiteouts.patch @@ -0,0 +1,143 @@ +From 0049dbdd91cc0c1900132374645c5114063db04d Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Thu, 29 Sep 2022 14:01:07 -0400 +Subject: [PATCH] compose: Handle embedded whiteouts + +This pairs with +https://github.com/ostreedev/ostree/pull/2722/commits/0085494e350c72599fc5c0e00422885d80b3c660 + +Basically, while I think it'd make sense actually for the baseline +`ostree commit` process to handle this, for now let's put it +here in rpm-ostree (where it can be in Rust too). Though +a definite negative is that we're now traversing the whole filesystem +again. + +(cherry picked from commit fea26bdd5db59fcf0853a9bb4ab6dcb340be9470) +--- + rust/src/composepost.rs | 63 ++++++++++++++++++++++++++++++- + tests/compose/test-installroot.sh | 8 ++++ + 2 files changed, 70 insertions(+), 1 deletion(-) + +diff --git a/rust/src/composepost.rs b/rust/src/composepost.rs +index ab5cc176..70a01497 100644 +--- a/rust/src/composepost.rs ++++ b/rust/src/composepost.rs +@@ -202,6 +202,47 @@ fn postprocess_presets(rootfs_dfd: &Dir) -> Result<()> { + Ok(()) + } + ++fn is_overlay_whiteout(meta: &cap_std::fs::Metadata) -> bool { ++ (meta.mode() & libc::S_IFMT) == libc::S_IFCHR && meta.rdev() == 0 ++} ++ ++/// Auto-synthesize embedded overlayfs whiteouts; for more information ++/// see https://github.com/ostreedev/ostree/pull/2722/commits/0085494e350c72599fc5c0e00422885d80b3c660 ++#[context("Postprocessing embedded overlayfs")] ++fn postprocess_embedded_ovl_whiteouts(root: &Dir) -> Result<()> { ++ const OSTREE_WHITEOUT_PREFIX: &str = ".ostree-wh."; ++ fn recurse(root: &Dir, path: &Utf8Path) -> Result { ++ let mut n = 0; ++ for entry in root.read_dir(path)? { ++ let entry = entry?; ++ let meta = entry.metadata()?; ++ let name = PathBuf::from(entry.file_name()); ++ let name: Utf8PathBuf = name.try_into()?; ++ if meta.is_dir() { ++ n += recurse(root, &path.join(name))?; ++ continue; ++ } ++ if !is_overlay_whiteout(&meta) { ++ continue; ++ }; ++ let srcpath = path.join(&name); ++ let targetname = format!("{OSTREE_WHITEOUT_PREFIX}{name}"); ++ let destpath = path.join(&targetname); ++ root.remove_file(srcpath)?; ++ root.atomic_write_with_perms(destpath, "", meta.permissions())?; ++ n += 1; ++ } ++ Ok(n) ++ } ++ let n = recurse(root, ".".into())?; ++ if n > 0 { ++ println!("Processed {n} embedded whiteouts"); ++ } else { ++ println!("No embedded whiteouts found"); ++ } ++ Ok(()) ++} ++ + /// Write an RPM macro file to ensure the rpmdb path is set on the client side. + pub fn compose_postprocess_rpm_macro(rootfs_dfd: i32) -> CxxResult<()> { + let rootfs = unsafe { &crate::ffiutil::ffi_dirfd(rootfs_dfd)? }; +@@ -290,13 +331,17 @@ pub(crate) fn postprocess_cleanup_rpmdb(rootfs_dfd: i32) -> CxxResult<()> { + /// on the target host. + pub fn compose_postprocess_final(rootfs_dfd: i32) -> CxxResult<()> { + let rootfs_dfd = unsafe { &crate::ffiutil::ffi_dirfd(rootfs_dfd)? }; ++ // These tasks can safely run in parallel, so just for fun we do so via rayon. + let tasks = [ + postprocess_useradd, + postprocess_presets, + postprocess_subs_dist, + postprocess_rpm_macro, + ]; +- Ok(tasks.par_iter().try_for_each(|f| f(rootfs_dfd))?) ++ tasks.par_iter().try_for_each(|f| f(rootfs_dfd))?; ++ // This task recursively traverses the filesystem and hence should be serial. ++ postprocess_embedded_ovl_whiteouts(rootfs_dfd)?; ++ Ok(()) + } + + #[context("Handling treefile 'units'")] +@@ -1290,6 +1335,22 @@ OSTREE_VERSION='33.4' + Ok(()) + } + ++ #[test] ++ fn test_overlay() -> Result<()> { ++ // We don't actually test creating whiteout devices here as that ++ // may not work. ++ let td = cap_tempfile::tempdir(cap_std::ambient_authority())?; ++ // Verify no-op case ++ postprocess_embedded_ovl_whiteouts(&td).unwrap(); ++ td.create("foo")?; ++ td.symlink("foo", "bar")?; ++ postprocess_embedded_ovl_whiteouts(&td).unwrap(); ++ assert!(td.try_exists("foo")?); ++ assert!(td.try_exists("bar")?); ++ ++ Ok(()) ++ } ++ + #[test] + fn test_tmpfiles_d_translation() { + use nix::sys::stat::{umask, Mode}; +diff --git a/tests/compose/test-installroot.sh b/tests/compose/test-installroot.sh +index 1ac09b9a..3e40f679 100755 +--- a/tests/compose/test-installroot.sh ++++ b/tests/compose/test-installroot.sh +@@ -54,6 +54,8 @@ echo "ok postprocess with treefile" + + testdate=$(date) + runasroot sh -xec " ++# https://github.com/ostreedev/ostree/pull/2717/commits/e234b630f85b97e48ecf45d5aaba9b1aa64e6b54 ++mknod -m 000 ${instroot}-directcommit/usr/share/foowhiteout c 0 0 + echo \"${testdate}\" > ${instroot}-directcommit/usr/share/rpm-ostree-composetest-split.txt + ! test -f ${instroot}-directcommit/${integrationconf} + rpm-ostree compose commit --repo=${repo} ${treefile} ${instroot}-directcommit +@@ -61,6 +63,12 @@ ostree --repo=${repo} ls ${treeref} /usr/bin/bash + if ostree --repo=${repo} ls ${treeref} /var/lib/rpm >/dev/null; then + echo found /var/lib/rpm in commit 1>&2; exit 1 + fi ++ ++# Verify whiteout renames ++ostree --repo=${repo} ls ${treeref} /usr/share ++ostree --repo=${repo} ls ${treeref} /usr/share/.ostree-wh.foowhiteout >out.txt ++grep -Ee '^-00000' out.txt ++ + ostree --repo=${repo} cat ${treeref} /usr/share/rpm-ostree-composetest-split.txt >out.txt + grep \"${testdate}\" out.txt + ostree --repo=${repo} cat ${treeref} /${integrationconf} +-- +2.38.1 + diff --git a/SPECS/rpm-ostree.spec b/SPECS/rpm-ostree.spec index 8fbb452..feb295a 100644 --- a/SPECS/rpm-ostree.spec +++ b/SPECS/rpm-ostree.spec @@ -4,13 +4,16 @@ Summary: Hybrid image/package system Name: rpm-ostree Version: 2022.10.90.g4abaf4b4 -Release: 4%{?dist} +Release: 5%{?dist} License: LGPLv2+ URL: https://github.com/coreos/rpm-ostree # This tarball is generated via "cd packaging && make -f Makefile.dist-packaging dist-snapshot" # in the upstream git. It also contains vendored Rust sources. This is generated from the "rhel8" branch. Source0: https://github.com/coreos/rpm-ostree/releases/download/v%{version}/rpm-ostree-%{version}.tar.xz +# https://bugzilla.redhat.com/show_bug.cgi?id=2137905 +Patch0: 0001-compose-Handle-embedded-whiteouts.patch + ExclusiveArch: %{rust_arches} BuildRequires: make @@ -227,6 +230,11 @@ $PYTHON autofiles.py > files.devel \ %files devel -f files.devel %changelog +* Tue Dec 13 2022 Colin Walters - 2022.10.90.g4abaf4b4-5 +- Backport + https://github.com/coreos/rpm-ostree/commit/0049dbdd91cc0c1900132374645c5114063db04d + Resolves: rhbz#2137905 + * Tue Aug 16 2022 Colin Walters - 2022.10.90.g4abaf4b4-4 - Update to latest https://github.com/coreos/rpm-ostree/tree/rhel8 at commit https://github.com/coreos/rpm-ostree/commit/4abaf4b4