diff --git a/rpmostree-cxxrs.cxx b/rpmostree-cxxrs.cxx index fae1d81b05..f919ff0815 100644 --- a/rpmostree-cxxrs.cxx +++ b/rpmostree-cxxrs.cxx @@ -1439,7 +1439,7 @@ struct TempEtcGuard final : public ::rust::Opaque #define CXXBRIDGE1_STRUCT_rpmostreecxx$FilesystemScriptPrep struct FilesystemScriptPrep final : public ::rust::Opaque { - void undo () const; + void undo (); ~FilesystemScriptPrep () = delete; private: @@ -2069,7 +2069,7 @@ extern "C" ::std::int32_t rootfs, ::rust::Box< ::rpmostreecxx::FilesystemScriptPrep> *return$) noexcept; ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$FilesystemScriptPrep$undo ( - const ::rpmostreecxx::FilesystemScriptPrep &self) noexcept; + ::rpmostreecxx::FilesystemScriptPrep &self) noexcept; ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$run_depmod (::std::int32_t rootfs_dfd, ::rust::Str kver, @@ -3719,7 +3719,7 @@ prepare_filesystem_script_prep (::std::int32_t rootfs) } void -FilesystemScriptPrep::undo () const +FilesystemScriptPrep::undo () { ::rust::repr::PtrLen error$ = rpmostreecxx$cxxbridge1$FilesystemScriptPrep$undo (*this); if (error$.ptr) diff --git a/rpmostree-cxxrs.h b/rpmostree-cxxrs.h index 8ddb976b64..b2d63dbc67 100644 --- a/rpmostree-cxxrs.h +++ b/rpmostree-cxxrs.h @@ -1225,7 +1225,7 @@ struct TempEtcGuard final : public ::rust::Opaque #define CXXBRIDGE1_STRUCT_rpmostreecxx$FilesystemScriptPrep struct FilesystemScriptPrep final : public ::rust::Opaque { - void undo () const; + void undo (); ~FilesystemScriptPrep () = delete; private: diff --git a/rust/src/core.rs b/rust/src/core.rs index 66075bd2ee..f308139252 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -125,6 +125,7 @@ pub(crate) fn refspec_classify(refspec: &str) -> crate::ffi::RefspecType { /// Perform reversible filesystem transformations necessary before we execute scripts. pub(crate) struct FilesystemScriptPrep { rootfs: Dir, + enabled: bool, } pub(crate) fn prepare_filesystem_script_prep(rootfs: i32) -> CxxResult> { @@ -166,12 +167,18 @@ impl FilesystemScriptPrep { rootfs.atomic_write_with_perms(path, contents, mode)?; } } - Ok(Box::new(Self { rootfs })) + Ok(Box::new(Self { + rootfs, + enabled: true, + })) } /// Undo the filesystem changes. #[context("Undoing prep filesystem for scripts")] - pub(crate) fn undo(&self) -> CxxResult<()> { + pub(crate) fn undo(&mut self) -> CxxResult<()> { + if !self.enabled { + return Ok(()); + } for &path in Self::OPTIONAL_PATHS .iter() .chain(Self::REPLACE_OPTIONAL_PATHS.iter().map(|x| &x.0)) @@ -181,10 +188,17 @@ impl FilesystemScriptPrep { self.rootfs.rename(saved, &self.rootfs, path)?; } } + self.enabled = false; Ok(()) } } +impl Drop for FilesystemScriptPrep { + fn drop(&mut self) { + let _ = self.undo(); + } +} + /// Some Fedora/RHEL kernels ship .hmac files with absolute paths inside, /// which breaks when we relocate them into ostree/. This function /// changes them to be relative. @@ -363,7 +377,7 @@ mod test { let d = cap_tempfile::tempdir(cap_std::ambient_authority())?; // The no-op case { - let g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; + let mut g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; g.undo()?; } let mut db = dirbuilder_from_mode(0o755); @@ -375,7 +389,7 @@ mod test { // Neutered sss_cache. { assert!(d.try_exists(super::SSS_CACHE_PATH)?); - let g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; + let mut g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; assert!(!d.try_exists(super::SSS_CACHE_PATH)?); g.undo()?; assert!(d.try_exists(super::SSS_CACHE_PATH)?); @@ -386,7 +400,7 @@ mod test { d.atomic_write_with_perms(super::SYSTEMCTL_PATH, original_systemctl, mode.clone())?; let contents = d.read_to_string(super::SYSTEMCTL_PATH)?; assert_eq!(contents, original_systemctl); - let g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; + let mut g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; let contents = d.read_to_string(super::SYSTEMCTL_PATH)?; assert_eq!(contents.as_bytes(), super::SYSTEMCTL_WRAPPER); g.undo()?; @@ -399,7 +413,7 @@ mod test { d.atomic_write_with_perms(super::GROUPADD_PATH, original_groupadd, mode.clone())?; let contents = d.read_to_string(super::GROUPADD_PATH)?; assert_eq!(contents, original_groupadd); - let g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; + let mut g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; let contents = d.read_to_string(super::GROUPADD_PATH)?; assert_eq!(contents.as_bytes(), super::GROUPADD_WRAPPER); g.undo()?; @@ -412,7 +426,7 @@ mod test { d.atomic_write_with_perms(super::USERADD_PATH, original_useradd, mode.clone())?; let contents = d.read_to_string(super::USERADD_PATH)?; assert_eq!(contents, original_useradd); - let g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; + let mut g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; let contents = d.read_to_string(super::USERADD_PATH)?; assert_eq!(contents.as_bytes(), super::USERADD_WRAPPER); g.undo()?; @@ -425,7 +439,7 @@ mod test { d.atomic_write_with_perms(super::USERMOD_PATH, original_usermod, mode)?; let contents = d.read_to_string(super::USERMOD_PATH)?; assert_eq!(contents, original_usermod); - let g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; + let mut g = super::prepare_filesystem_script_prep(d.as_raw_fd())?; let contents = d.read_to_string(super::USERMOD_PATH)?; assert_eq!(contents.as_bytes(), super::USERMOD_WRAPPER); g.undo()?; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 9a554b9d2f..2ea6406ddb 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -217,7 +217,7 @@ pub mod ffi { fn undo(self: &TempEtcGuard) -> Result<()>; fn prepare_filesystem_script_prep(rootfs: i32) -> Result>; - fn undo(self: &FilesystemScriptPrep) -> Result<()>; + fn undo(self: &mut FilesystemScriptPrep) -> Result<()>; fn run_depmod(rootfs_dfd: i32, kver: &str, unified_core: bool) -> Result<()>; diff --git a/src/libpriv/rpmostree-container.cxx b/src/libpriv/rpmostree-container.cxx index 37e14f2af4..e893bd1198 100644 --- a/src/libpriv/rpmostree-container.cxx +++ b/src/libpriv/rpmostree-container.cxx @@ -41,6 +41,13 @@ rpmostree_container_rebuild (rpmostreecxx::Treefile &treefile, GCancellable *can g_autoptr (RpmOstreeContext) ctx = rpmostree_context_new_container (); rpmostree_context_set_treefile (ctx, treefile); + glnx_autofd int rootfs_fd = -1; + if (!glnx_opendirat (AT_FDCWD, "/", TRUE, &rootfs_fd, error)) + return FALSE; + + // Ensure we have our wrappers for groupadd/systemctl set up + CXX_TRY_VAR (fs_prep, rpmostreecxx::prepare_filesystem_script_prep (rootfs_fd), error); + if (!rpmostree_context_setup (ctx, "/", "/", cancellable, error)) return FALSE; @@ -61,9 +68,8 @@ rpmostree_container_rebuild (rpmostreecxx::Treefile &treefile, GCancellable *can if (!dnf_context_run (dnfctx, NULL, error)) return FALSE; - glnx_autofd int rootfs_fd = -1; - if (!glnx_opendirat (AT_FDCWD, "/", TRUE, &rootfs_fd, error)) - return FALSE; + CXX_TRY (fs_prep->undo (), error); + CXX_TRY (rpmostreecxx::postprocess_cleanup_rpmdb (rootfs_fd), error); return TRUE;