diff --git a/01-github-rpm-libdnf-pr1274.patch b/01-github-rpm-libdnf-pr1274.patch new file mode 100644 index 0000000..9f75bf6 --- /dev/null +++ b/01-github-rpm-libdnf-pr1274.patch @@ -0,0 +1,38 @@ +From 27a8e7be662b9fca6badc8925d5991d5d7abfcfc Mon Sep 17 00:00:00 2001 +From: Jonathan Lebon +Date: Wed, 16 Jun 2021 09:11:43 -0400 +Subject: [PATCH] os-release.cpp: make initLibRpm call dnf_context_globals_init + +We shouldn't have our separate static var here. Otherwise clients will +incur `rpmReadConfigFiles` twice which breaks their ability to +consistently override macros. + +Reported-by: Luca Bruno +Reported-by: Christian Kellner + +Fixes: #1273 +--- + libdnf/utils/os-release.cpp | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/libdnf/libdnf/utils/os-release.cpp b/libdnf/libdnf/utils/os-release.cpp +index 1d8a95be65..e2f3d06dd0 100644 +--- a/libdnf/libdnf/utils/os-release.cpp ++++ b/libdnf/libdnf/utils/os-release.cpp +@@ -80,12 +80,10 @@ std::map getOsReleaseData() + + static void initLibRpm() + { +- static bool libRpmInitiated{false}; +- if (libRpmInitiated) return; +- if (rpmReadConfigFiles(NULL, NULL) != 0) { +- throw std::runtime_error("failed to read rpm config files\n"); +- } +- libRpmInitiated = true; ++ // call dnf_context_globals_init to ensure this only happens once ++ g_autoptr(GError) local_error = NULL; ++ if (!dnf_context_globals_init(&local_error)) ++ throw std::runtime_error(local_error->message); + } + + static std::string getBaseArch() diff --git a/02-github-coreos-rpm-ostree-pr2897.patch b/02-github-coreos-rpm-ostree-pr2897.patch new file mode 100644 index 0000000..e902c1a --- /dev/null +++ b/02-github-coreos-rpm-ostree-pr2897.patch @@ -0,0 +1,212 @@ +From 8c533c5aab948fff3ebef12a6d965c9303302c35 Mon Sep 17 00:00:00 2001 +From: Luca BRUNO +Date: Thu, 17 Jun 2021 08:30:00 +0000 +Subject: [PATCH 1/3] builtin/tree: inject _dbpath macro file in postprocessing + step + +This wires the _dbpath macro injection logic to `compose postprocess`, +in order to make sure that the rpm configuration in the commit +matches the location of the rpmdb database. +--- + rust/src/composepost.rs | 12 +++++++++--- + rust/src/lib.rs | 1 + + src/libpriv/rpmostree-postprocess.cxx | 3 +++ + 3 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/rust/src/composepost.rs b/rust/src/composepost.rs +index c63ca8fa5..4e000a97e 100644 +--- a/rust/src/composepost.rs ++++ b/rust/src/composepost.rs +@@ -172,9 +172,15 @@ fn postprocess_presets(rootfs_dfd: &openat::Dir) -> Result<()> { + Ok(()) + } + +-// We keep hitting issues with the ostree-remount preset not being +-// enabled; let's just do this rather than trying to propagate the +-// preset everywhere. ++/// 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 = &crate::ffiutil::ffi_view_openat_dir(rootfs_dfd); ++ postprocess_rpm_macro(rootfs)?; ++ Ok(()) ++} ++ ++/// Ensure our own `_dbpath` macro exists in the tree. ++#[context("Writing _dbpath RPM macro")] + fn postprocess_rpm_macro(rootfs_dfd: &openat::Dir) -> Result<()> { + let rpm_macros_dir = "usr/lib/rpm/macros.d"; + rootfs_dfd.ensure_dir_all(rpm_macros_dir, 0o755)?; +diff --git a/rust/src/lib.rs b/rust/src/lib.rs +index 4c328fe4c..658a7fa95 100644 +--- a/rust/src/lib.rs ++++ b/rust/src/lib.rs +@@ -160,6 +160,7 @@ pub mod ffi { + rootfs_dfd: i32, + cancellable: Pin<&mut GCancellable>, + ) -> Result<()>; ++ fn compose_postprocess_rpm_macro(rootfs_dfd: i32) -> Result<()>; + } + + // A grab-bag of metadata from the deployment's ostree commit +diff --git a/src/libpriv/rpmostree-postprocess.cxx b/src/libpriv/rpmostree-postprocess.cxx +index 42aa0b569..781c3a15c 100644 +--- a/src/libpriv/rpmostree-postprocess.cxx ++++ b/src/libpriv/rpmostree-postprocess.cxx +@@ -649,6 +649,9 @@ rpmostree_rootfs_postprocess_common (int rootfs_fd, + } + } + ++ /* Make sure there is an RPM macro in place pointing to the rpmdb in /usr */ ++ rpmostreecxx::compose_postprocess_rpm_macro(rootfs_fd); ++ + if (!rpmostree_cleanup_leftover_rpmdb_files (rootfs_fd, cancellable, error)) + return FALSE; + + +From ac7c64428594726a5420b1c11d7b6d6a48ffc0a8 Mon Sep 17 00:00:00 2001 +From: Luca BRUNO +Date: Sun, 13 Jun 2021 13:50:39 +0000 +Subject: [PATCH 2/3] libpriv/core: set _dbpath macro in dnf context + +This ensures that the `_dbpath` macro is always in all dnf contexts, +in order to use the rpmdb under /usr. +Setting it explicitly makes sure that there is no logic implicitly +relying on host configuration. This is particularly relevant in +server-side compose cases, which are more likely to be running in +an environment without rpm-ostree macro file. +--- + src/libpriv/rpmostree-core.cxx | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/libpriv/rpmostree-core.cxx b/src/libpriv/rpmostree-core.cxx +index 12381e20e..ab0e0ef54 100644 +--- a/src/libpriv/rpmostree-core.cxx ++++ b/src/libpriv/rpmostree-core.cxx +@@ -379,6 +379,9 @@ rpmostree_context_new_client (OstreeRepo *repo) + dnf_context_set_zchunk (self->dnfctx, FALSE); + #endif + ++ /* The rpmdb is at /usr/share/rpm */ ++ dnf_context_set_rpm_macro (self->dnfctx, "_dbpath", "/" RPMOSTREE_RPMDB_LOCATION); ++ + return self; + } + + +From bfdebee9f8b0bf7c4488bcfe723b12faed784da8 Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Fri, 11 Jun 2021 15:33:30 +0000 +Subject: [PATCH 3/3] builtin/tree: explicitly set _dbpath macro in global + libdnf initialization + +This ensures that the `_dbpath` macro is always in all dnf contexts, +in order to use the rpmdb under /usr. +Setting it explicitly makes sure that there is no logic implicitly +relying on host configuration. This is particularly relevant in +server-side compose cases, which are more likely to be running in +an environment without rpm-ostree macro file. +--- + src/app/rpmostree-compose-builtin-tree.cxx | 2 ++ + src/libpriv/rpmostree-core.cxx | 32 +++++++++++++++++++--- + src/libpriv/rpmostree-core.h | 4 +++ + src/libpriv/rpmostree-rpm-util.cxx | 2 ++ + 4 files changed, 36 insertions(+), 4 deletions(-) + +diff --git a/src/app/rpmostree-compose-builtin-tree.cxx b/src/app/rpmostree-compose-builtin-tree.cxx +index 4d88ee95f..d6eef2c44 100644 +--- a/src/app/rpmostree-compose-builtin-tree.cxx ++++ b/src/app/rpmostree-compose-builtin-tree.cxx +@@ -574,6 +574,8 @@ rpm_ostree_compose_context_new (const char *treefile_pathstr, + { + g_autoptr(RpmOstreeTreeComposeContext) self = g_new0 (RpmOstreeTreeComposeContext, 1); + ++ rpmostreecxx::core_libdnf_process_global_init(); ++ + /* Init fds to -1 */ + self->workdir_dfd = self->rootfs_dfd = self->cachedir_dfd = -1; + /* Test whether or not bwrap is going to work - we will fail inside e.g. a Docker +diff --git a/src/libpriv/rpmostree-core.cxx b/src/libpriv/rpmostree-core.cxx +index ab0e0ef54..e142ccd76 100644 +--- a/src/libpriv/rpmostree-core.cxx ++++ b/src/libpriv/rpmostree-core.cxx +@@ -653,6 +653,32 @@ rpmostree_context_set_treespec (RpmOstreeContext *self, RpmOstreeTreespec *trees + self->spec = (RpmOstreeTreespec*)g_object_ref (treespec); + } + ++namespace rpmostreecxx { ++// Sadly, like most of librpm, macros are a process-global state. ++// For rpm-ostree, the dbpath must be overriden. ++void ++core_libdnf_process_global_init() ++{ ++ static gsize initialized = 0; ++ ++ if (g_once_init_enter (&initialized)) ++ { ++ g_autoptr(GError) error = NULL; ++ /* Fatally error out if this fails */ ++ if (!dnf_context_globals_init (&error)) ++ g_error ("%s", error->message); ++ ++ /* This is what we use as default. Note we should be able to drop this in the ++ * future on the *client side* now that we inject a macro to set that value in our OSTrees. ++ */ ++ free (rpmExpand ("%define _dbpath /" RPMOSTREE_RPMDB_LOCATION, NULL)); ++ ++ g_once_init_leave (&initialized, 1); ++ } ++} ++ ++} /* namespace */ ++ + /* Wraps `dnf_context_setup()`, and initializes state based on the treespec + * @spec. Another way to say it is we pair `DnfContext` with an + * `RpmOstreeTreespec`. For example, we handle "instlangs", set the rpmdb root +@@ -674,6 +700,8 @@ rpmostree_context_setup (RpmOstreeContext *self, + /* This exists (as a canonically empty dir) at least on RHEL7+ */ + static const char emptydir_path[] = "/usr/share/empty"; + ++ rpmostreecxx::core_libdnf_process_global_init(); ++ + /* Auto-synthesize a spec for now; this will be removed */ + if (!self->spec) + rpmostree_context_set_treespec (self, NULL); +@@ -710,10 +738,6 @@ rpmostree_context_setup (RpmOstreeContext *self, + dnf_context_set_rpm_macro (self->dnfctx, "_install_langs", instlangs.c_str()); + } + +- /* This is what we use as default. Note we should be able to drop this in the +- * future now that we inject a macro to set that value in our OSTrees. */ +- dnf_context_set_rpm_macro (self->dnfctx, "_dbpath", "/" RPMOSTREE_RPMDB_LOCATION); +- + /* Set the database backend only in the compose path. It then becomes the default + * for any client side layering. + */ +diff --git a/src/libpriv/rpmostree-core.h b/src/libpriv/rpmostree-core.h +index 1db1014cd..cea97028e 100644 +--- a/src/libpriv/rpmostree-core.h ++++ b/src/libpriv/rpmostree-core.h +@@ -78,6 +78,10 @@ char* rpmostree_refspec_to_string (RpmOstreeRefspecType reftype, + char* rpmostree_refspec_canonicalize (const char *orig_refspec, + GError **error); + ++namespace rpmostreecxx { ++void core_libdnf_process_global_init(); ++} ++ + RpmOstreeContext *rpmostree_context_new_client (OstreeRepo *repo); + + RpmOstreeContext *rpmostree_context_new_compose (int basedir_dfd, +diff --git a/src/libpriv/rpmostree-rpm-util.cxx b/src/libpriv/rpmostree-rpm-util.cxx +index 57bdda4ed..19640b864 100644 +--- a/src/libpriv/rpmostree-rpm-util.cxx ++++ b/src/libpriv/rpmostree-rpm-util.cxx +@@ -851,6 +851,8 @@ get_sack_for_root (int dfd, + GLNX_AUTO_PREFIX_ERROR ("Loading sack", error); + g_assert (out_sack != NULL); + ++ rpmostreecxx::core_libdnf_process_global_init(); ++ + g_autofree char *fullpath = glnx_fdrel_abspath (dfd, path); + + g_autoptr(DnfSack) sack = dnf_sack_new (); diff --git a/03-adjust-prebuilt-bindings.patch b/03-adjust-prebuilt-bindings.patch new file mode 100644 index 0000000..ce1f6d2 --- /dev/null +++ b/03-adjust-prebuilt-bindings.patch @@ -0,0 +1,42 @@ +diff --git a/rpmostree-cxxrs-prebuilt.cxx b/rpmostree-cxxrs-prebuilt.cxx +index 46985b6f..e73f5d1c 100644 +--- a/rpmostree-cxxrs-prebuilt.cxx ++++ b/rpmostree-cxxrs-prebuilt.cxx +@@ -1457,6 +1457,8 @@ void rpmostreecxx$cxxbridge1$cliwrap_destdir(::rust::String *return$) noexcept; + + ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$prepare_rpmdb_base_location(::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable &cancellable) noexcept; + ++::rust::repr::PtrLen rpmostreecxx$cxxbridge1$compose_postprocess_rpm_macro(::std::int32_t rootfs_dfd) noexcept; ++ + void rpmostreecxx$cxxbridge1$deployment_generate_id(::rpmostreecxx::OstreeDeployment &deployment, ::rust::String *return$) noexcept; + + ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$deployment_populate_variant(::rpmostreecxx::OstreeSysroot &sysroot, ::rpmostreecxx::OstreeDeployment &deployment, ::rpmostreecxx::GVariantDict &dict) noexcept; +@@ -2079,6 +2081,13 @@ void prepare_rpmdb_base_location(::std::int32_t rootfs_dfd, ::rpmostreecxx::GCan + } + } + ++void compose_postprocess_rpm_macro(::std::int32_t rootfs_dfd) { ++ ::rust::repr::PtrLen error$ = rpmostreecxx$cxxbridge1$compose_postprocess_rpm_macro(rootfs_dfd); ++ if (error$.ptr) { ++ throw ::rust::impl<::rust::Error>::error(error$); ++ } ++} ++ + ::rust::String deployment_generate_id(::rpmostreecxx::OstreeDeployment &deployment) noexcept { + ::rust::MaybeUninit<::rust::String> return$; + rpmostreecxx$cxxbridge1$deployment_generate_id(deployment, &return$.value); +diff --git a/rpmostree-cxxrs-prebuilt.h b/rpmostree-cxxrs-prebuilt.h +index 631ea2b9..9428089b 100644 +--- a/rpmostree-cxxrs-prebuilt.h ++++ b/rpmostree-cxxrs-prebuilt.h +@@ -1249,6 +1249,8 @@ void workaround_selinux_cross_labeling(::std::int32_t rootfs_dfd, ::rpmostreecxx + + void prepare_rpmdb_base_location(::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable &cancellable); + ++void compose_postprocess_rpm_macro(::std::int32_t rootfs_dfd); ++ + ::rust::String deployment_generate_id(::rpmostreecxx::OstreeDeployment &deployment) noexcept; + + void deployment_populate_variant(::rpmostreecxx::OstreeSysroot &sysroot, ::rpmostreecxx::OstreeDeployment &deployment, ::rpmostreecxx::GVariantDict &dict); + + diff --git a/rpm-ostree.spec b/rpm-ostree.spec index 79c6ea4..e81367a 100644 --- a/rpm-ostree.spec +++ b/rpm-ostree.spec @@ -4,13 +4,17 @@ Summary: Hybrid image/package system Name: rpm-ostree Version: 2021.5 -Release: 1%{?dist} +Release: 2%{?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. Source0: https://github.com/coreos/rpm-ostree/releases/download/v%{version}/rpm-ostree-%{version}.tar.xz +Patch01: 01-github-rpm-libdnf-pr1274.patch +Patch02: 02-github-coreos-rpm-ostree-pr2897.patch +Patch03: 03-adjust-prebuilt-bindings.patch + ExclusiveArch: %{rust_arches} BuildRequires: make @@ -206,6 +210,10 @@ $PYTHON autofiles.py > files.devel \ %files devel -f files.devel %changelog +* Thu Jun 17 2021 Luca BRUNO - 2021.5-2 +- Backport _dbpath fixes, see + https://github.com/coreos/rpm-ostree/issues/2904 + * Wed May 12 2021 Luca BRUNO - 2021.5-1 - New upstream version https://github.com/coreos/rpm-ostree/releases/tag/v2021.5