From 13fa62a56070ed109129e469d23ba849c6e89665 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 1 Mar 2024 09:46:51 -0500 Subject: [PATCH] compose: change opt_usrlocal_overlays to be an enum xref https://github.com/ostreedev/ostree-rs-ext/issues/607 We need to support having `/opt` and `/usr/local` be directly on the rootfs. Change the existing knob for this to be more configurable. The stateoverlay path is now an internal-only knob; we expect people to do that externally. --- ci/prow/fcos-e2e.sh | 4 +- docs/treefile.md | 12 ++--- rpmostree-cxxrs.cxx | 34 +++++++++---- rpmostree-cxxrs.h | 16 +++++- rust/src/composepost.rs | 58 +++++++++++++--------- rust/src/lib.rs | 16 +++++- rust/src/treefile.rs | 33 ++++++++++-- src/app/rpmostree-compose-builtin-tree.cxx | 2 +- src/libpriv/rpmostree-core.cxx | 2 +- src/libpriv/rpmostree-postprocess.cxx | 2 +- tests/compose/libbasic-test.sh | 2 + tests/compose/libcomposetest.sh | 1 + tests/compose/test-misc-tweaks.sh | 7 +++ tests/compose/test-state-overlays.sh | 2 +- tests/kolainst/destructive/apply-live | 2 +- tests/kolainst/destructive/state-overlays | 4 +- 16 files changed, 140 insertions(+), 57 deletions(-) diff --git a/ci/prow/fcos-e2e.sh b/ci/prow/fcos-e2e.sh index 46d5db3c7c..c3cecae165 100755 --- a/ci/prow/fcos-e2e.sh +++ b/ci/prow/fcos-e2e.sh @@ -9,9 +9,9 @@ ls -al /usr/bin/rpm-ostree rpm-ostree --version cd $(mktemp -d) cosa init https://github.com/coreos/fedora-coreos-config/ -# let's turn on opt-usrlocal-overlays in this test since CoreOS CI already +# let's turn on stateoverlays in this test since CoreOS CI already # covers the off path -echo -e '\nopt-usrlocal-overlays: true\n' >> src/config/manifest.yaml +echo -e '\nopt-usrlocal: "stateoverlay"\n' >> src/config/manifest.yaml cp /cosa/component-rpms/*.rpm overrides/rpm # XXX: temporarily import new ostree until it makes it into FCOS (cd overrides/rpm && curl -L --remote-name-all https://kojipkgs.fedoraproject.org//packages/ostree/2024.2/1.fc39/x86_64/ostree-{,libs-}2024.2-1.fc39.x86_64.rpm) diff --git a/docs/treefile.md b/docs/treefile.md index c03819bc79..34b5b0a92d 100644 --- a/docs/treefile.md +++ b/docs/treefile.md @@ -479,9 +479,9 @@ version of `rpm-ostree`. names to use when substituting variables in yum repo files. The `releasever` variable name is invalid. Use the `releasever` key instead. The `basearch` name is invalid; it is filled in automatically. - * `opt-usrlocal-overlays`: boolean, optional: Defaults to `false`. By - default, `/opt` and `/usr/local` are symlinks to subdirectories in `/ - var`. This prevents the ability to compose with packages that install in - those directories. If enabled, RPMs with `/opt` and `/usr/local` content - are allowed; client-side, both paths are writable overlay directories on. - Requires libostree v2023.9+. + * `opt-usrlocal`: enum, optional: Defaults to `var`. There are + two possible behaviors: + - `var`: `/opt` and `/usr/local` are symlinks to subdirectories in `/var` + and are purely machine-local state. + - `root`: These are plain directories; only use this with composefs enabled! + diff --git a/rpmostree-cxxrs.cxx b/rpmostree-cxxrs.cxx index 38dcd880ae..c326b7c1a9 100644 --- a/rpmostree-cxxrs.cxx +++ b/rpmostree-cxxrs.cxx @@ -1312,6 +1312,7 @@ enum class RepoMetadataTarget : ::std::uint8_t; struct Refspec; enum class OverrideReplacementType : ::std::uint8_t; struct OverrideReplacement; +enum class OptUsrLocal : ::std::uint8_t; struct Treefile; struct RepoPackage; struct LiveApplyState; @@ -1708,6 +1709,16 @@ struct OverrideReplacement final }; #endif // CXXBRIDGE1_STRUCT_rpmostreecxx$OverrideReplacement +#ifndef CXXBRIDGE1_ENUM_rpmostreecxx$OptUsrLocal +#define CXXBRIDGE1_ENUM_rpmostreecxx$OptUsrLocal +enum class OptUsrLocal : ::std::uint8_t +{ + Var = 0, + Root = 1, + StateOverlay = 2, +}; +#endif // CXXBRIDGE1_ENUM_rpmostreecxx$OptUsrLocal + #ifndef CXXBRIDGE1_STRUCT_rpmostreecxx$Treefile #define CXXBRIDGE1_STRUCT_rpmostreecxx$Treefile struct Treefile final : public ::rust::Opaque @@ -1773,7 +1784,7 @@ struct Treefile final : public ::rust::Opaque ::rpmostreecxx::RepoMetadataTarget get_repo_metadata_target () const noexcept; bool rpmdb_backend_is_target () const noexcept; bool should_normalize_rpmdb () const noexcept; - bool get_opt_usrlocal_overlays () const noexcept; + ::rpmostreecxx::OptUsrLocal get_opt_usrlocal () const noexcept; ::rust::Vec< ::rust::String> get_files_remove_regex (::rust::Str package) const noexcept; ::rust::String get_checksum (::rpmostreecxx::OstreeRepo const &repo) const; ::rust::String get_ostree_ref () const noexcept; @@ -2201,8 +2212,10 @@ extern "C" ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$convert_var_to_tmpfiles_d ( ::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable const &cancellable) noexcept; - ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$rootfs_prepare_links (::std::int32_t rootfs_dfd, - bool skip_usrlocal) noexcept; + ::rust::repr::PtrLen + rpmostreecxx$cxxbridge1$rootfs_prepare_links (::std::int32_t rootfs_dfd, + ::rpmostreecxx::Treefile const &treefile, + bool skip_usrlocal) noexcept; ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$workaround_selinux_cross_labeling ( ::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable &cancellable) noexcept; @@ -2647,8 +2660,8 @@ extern "C" bool rpmostreecxx$cxxbridge1$Treefile$should_normalize_rpmdb ( ::rpmostreecxx::Treefile const &self) noexcept; - bool rpmostreecxx$cxxbridge1$Treefile$get_opt_usrlocal_overlays ( - ::rpmostreecxx::Treefile const &self) noexcept; + ::rpmostreecxx::OptUsrLocal + rpmostreecxx$cxxbridge1$Treefile$get_opt_usrlocal (::rpmostreecxx::Treefile const &self) noexcept; void rpmostreecxx$cxxbridge1$Treefile$get_files_remove_regex ( ::rpmostreecxx::Treefile const &self, ::rust::Str package, @@ -4045,10 +4058,11 @@ convert_var_to_tmpfiles_d (::std::int32_t rootfs_dfd, } void -rootfs_prepare_links (::std::int32_t rootfs_dfd, bool skip_usrlocal) +rootfs_prepare_links (::std::int32_t rootfs_dfd, ::rpmostreecxx::Treefile const &treefile, + bool skip_usrlocal) { ::rust::repr::PtrLen error$ - = rpmostreecxx$cxxbridge1$rootfs_prepare_links (rootfs_dfd, skip_usrlocal); + = rpmostreecxx$cxxbridge1$rootfs_prepare_links (rootfs_dfd, treefile, skip_usrlocal); if (error$.ptr) { throw ::rust::impl< ::rust::Error>::error (error$); @@ -5270,10 +5284,10 @@ Treefile::should_normalize_rpmdb () const noexcept return rpmostreecxx$cxxbridge1$Treefile$should_normalize_rpmdb (*this); } -bool -Treefile::get_opt_usrlocal_overlays () const noexcept +::rpmostreecxx::OptUsrLocal +Treefile::get_opt_usrlocal () const noexcept { - return rpmostreecxx$cxxbridge1$Treefile$get_opt_usrlocal_overlays (*this); + return rpmostreecxx$cxxbridge1$Treefile$get_opt_usrlocal (*this); } ::rust::Vec< ::rust::String> diff --git a/rpmostree-cxxrs.h b/rpmostree-cxxrs.h index 51941c2903..cb7ff4116b 100644 --- a/rpmostree-cxxrs.h +++ b/rpmostree-cxxrs.h @@ -1094,6 +1094,7 @@ enum class RepoMetadataTarget : ::std::uint8_t; struct Refspec; enum class OverrideReplacementType : ::std::uint8_t; struct OverrideReplacement; +enum class OptUsrLocal : ::std::uint8_t; struct Treefile; struct RepoPackage; struct LiveApplyState; @@ -1490,6 +1491,16 @@ struct OverrideReplacement final }; #endif // CXXBRIDGE1_STRUCT_rpmostreecxx$OverrideReplacement +#ifndef CXXBRIDGE1_ENUM_rpmostreecxx$OptUsrLocal +#define CXXBRIDGE1_ENUM_rpmostreecxx$OptUsrLocal +enum class OptUsrLocal : ::std::uint8_t +{ + Var = 0, + Root = 1, + StateOverlay = 2, +}; +#endif // CXXBRIDGE1_ENUM_rpmostreecxx$OptUsrLocal + #ifndef CXXBRIDGE1_STRUCT_rpmostreecxx$Treefile #define CXXBRIDGE1_STRUCT_rpmostreecxx$Treefile struct Treefile final : public ::rust::Opaque @@ -1555,7 +1566,7 @@ struct Treefile final : public ::rust::Opaque ::rpmostreecxx::RepoMetadataTarget get_repo_metadata_target () const noexcept; bool rpmdb_backend_is_target () const noexcept; bool should_normalize_rpmdb () const noexcept; - bool get_opt_usrlocal_overlays () const noexcept; + ::rpmostreecxx::OptUsrLocal get_opt_usrlocal () const noexcept; ::rust::Vec< ::rust::String> get_files_remove_regex (::rust::Str package) const noexcept; ::rust::String get_checksum (::rpmostreecxx::OstreeRepo const &repo) const; ::rust::String get_ostree_ref () const noexcept; @@ -1866,7 +1877,8 @@ void compose_postprocess_final (::std::int32_t rootfs_dfd, void convert_var_to_tmpfiles_d (::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable const &cancellable); -void rootfs_prepare_links (::std::int32_t rootfs_dfd, bool skip_usrlocal); +void rootfs_prepare_links (::std::int32_t rootfs_dfd, ::rpmostreecxx::Treefile const &treefile, + bool skip_usrlocal); void workaround_selinux_cross_labeling (::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable &cancellable); diff --git a/rust/src/composepost.rs b/rust/src/composepost.rs index 7c816d7fc9..1a5ae86937 100644 --- a/rust/src/composepost.rs +++ b/rust/src/composepost.rs @@ -12,7 +12,7 @@ use crate::ffi::BubblewrapMutability; use crate::ffiutil::ffi_dirfd; use crate::normalization; use crate::passwd::PasswdDB; -use crate::treefile::Treefile; +use crate::treefile::{OptUsrLocal, Treefile}; use crate::{bwrap, importer}; use anyhow::{anyhow, bail, format_err, Context, Result}; use camino::{Utf8Path, Utf8PathBuf}; @@ -148,31 +148,33 @@ fn compose_init_rootfs_transient(rootfs_dfd: &cap_std::fs::Dir) -> Result<()> { fn compose_init_rootfs_strict( rootfs_dfd: &cap_std::fs::Dir, tmp_is_dir: bool, - opt_state_overlay: bool, + opt_usrlocal: OptUsrLocal, ) -> Result<()> { println!("Initializing rootfs"); compose_init_rootfs_base(rootfs_dfd, tmp_is_dir)?; - const OPT_SYMLINK_LEGACY: &str = "var/opt"; - const OPT_SYMLINK_STATEOVERLAY: &str = "usr/lib/opt"; - let opt_symlink = if opt_state_overlay { - OPT_SYMLINK_STATEOVERLAY - } else { - OPT_SYMLINK_LEGACY + let opt_symlink = match opt_usrlocal { + OptUsrLocal::Var => Some("var/opt"), + OptUsrLocal::Root => { + rootfs_dfd.create_dir_all("opt")?; + None + } + OptUsrLocal::StateOverlay => Some("usr/lib/opt"), }; // This is used in the case where we don't have a transient rootfs; redirect // these toplevel directories underneath /var. - let ostree_strict_mode_symlinks: &[(&str, &str)] = &[ - (opt_symlink, "opt"), + let ostree_strict_mode_symlinks = [ ("var/srv", "srv"), ("var/mnt", "mnt"), ("run/media", "media"), ]; + ostree_strict_mode_symlinks - .par_iter() - .try_for_each(|&(dest, src)| { + .into_iter() + .chain(opt_symlink.map(|link| (link, "opt"))) + .try_for_each(|(dest, src)| { rootfs_dfd .symlink(dest, src) .with_context(|| format!("Creating {src}")) @@ -230,7 +232,8 @@ pub fn compose_prepare_rootfs( treefile .parsed .base - .opt_usrlocal_overlays + .opt_usrlocal + .clone() .unwrap_or_default(), )?; @@ -679,12 +682,10 @@ pub fn compose_postprocess( compose_postprocess_default_target(rootfs, t)?; } - if treefile - .parsed - .base - .opt_usrlocal_overlays - .unwrap_or_default() - { + if matches!( + treefile.parsed.base.opt_usrlocal, + Some(OptUsrLocal::StateOverlay) + ) { compose_postprocess_state_overlays(rootfs)?; } @@ -1034,13 +1035,18 @@ fn state_overlay_enabled(rootfs_dfd: &cap_std::fs::Dir, state_overlay: &str) -> /// - If present, symlink /var/lib/alternatives -> /usr/lib/alternatives /// - If present, symlink /var/lib/vagrant -> /usr/lib/vagrant #[context("Preparing symlinks in rootfs")] -pub fn rootfs_prepare_links(rootfs_dfd: i32, skip_usrlocal: bool) -> CxxResult<()> { +pub fn rootfs_prepare_links( + rootfs_dfd: i32, + treefile: &Treefile, + skip_usrlocal: bool, +) -> CxxResult<()> { let rootfs = unsafe { &crate::ffiutil::ffi_dirfd(rootfs_dfd)? }; let mut db = dirbuilder_from_mode(0o755); db.recursive(true); if !skip_usrlocal { - if state_overlay_enabled(rootfs, "usr-local")? { + let usrlocal_root = matches!(treefile.parsed.base.opt_usrlocal, Some(OptUsrLocal::Root)); + if usrlocal_root || state_overlay_enabled(rootfs, "usr-local")? { // because of the filesystem lua issue (see // compose_init_rootfs_base()) we need to create this manually rootfs.ensure_dir_with("usr/local", &db)?; @@ -1636,8 +1642,11 @@ OSTREE_VERSION='33.4' } #[test] - fn test_prepare_symlinks() { - let rootfs = cap_tempfile::tempdir(cap_std::ambient_authority()).unwrap(); + fn test_prepare_symlinks() -> Result<()> { + let tempdir = tempfile::tempdir()?; + let tempdir: &Utf8Path = tempdir.path().try_into().unwrap(); + let tf = crate::treefile::tests::new_test_treefile(tempdir, "", None)?; + let rootfs = Dir::open_ambient_dir(tempdir, cap_std::ambient_authority())?; let mut db = DirBuilder::new(); db.recursive(true); db.mode(0o755); @@ -1645,7 +1654,7 @@ OSTREE_VERSION='33.4' rootfs.ensure_dir_with("var/lib/alternatives", &db).unwrap(); rootfs.ensure_dir_with("var/lib/vagrant", &db).unwrap(); - rootfs_prepare_links(rootfs.as_raw_fd(), false).unwrap(); + rootfs_prepare_links(rootfs.as_raw_fd(), &tf, false).unwrap(); { let usr_dir = rootfs.open_dir("usr").unwrap(); let local_target = usr_dir.read_link("local").unwrap(); @@ -1663,6 +1672,7 @@ OSTREE_VERSION='33.4' assert_eq!(target.unwrap().to_str(), Some(*content)); } } + Ok(()) } #[test] diff --git a/rust/src/lib.rs b/rust/src/lib.rs index d636e88c24..d167413198 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -300,7 +300,11 @@ pub mod ffi { fn compose_postprocess_final_pre(rootfs_dfd: i32) -> Result<()>; fn compose_postprocess_final(rootfs_dfd: i32, treefile: &Treefile) -> Result<()>; fn convert_var_to_tmpfiles_d(rootfs_dfd: i32, cancellable: &GCancellable) -> Result<()>; - fn rootfs_prepare_links(rootfs_dfd: i32, skip_usrlocal: bool) -> Result<()>; + fn rootfs_prepare_links( + rootfs_dfd: i32, + treefile: &Treefile, + skip_usrlocal: bool, + ) -> Result<()>; fn workaround_selinux_cross_labeling( rootfs_dfd: i32, cancellable: Pin<&mut GCancellable>, @@ -547,6 +551,14 @@ pub mod ffi { packages: Vec, } + // treefile.rs + #[derive(Debug)] + enum OptUsrLocal { + Var, + Root, + StateOverlay, + } + extern "Rust" { type Treefile; @@ -627,7 +639,7 @@ pub mod ffi { fn get_repo_metadata_target(&self) -> RepoMetadataTarget; fn rpmdb_backend_is_target(&self) -> bool; fn should_normalize_rpmdb(&self) -> bool; - fn get_opt_usrlocal_overlays(&self) -> bool; + fn get_opt_usrlocal(&self) -> OptUsrLocal; fn get_files_remove_regex(&self, package: &str) -> Vec; fn get_checksum(&self, repo: &OstreeRepo) -> Result; fn get_ostree_ref(&self) -> String; diff --git a/rust/src/treefile.rs b/rust/src/treefile.rs index 0a8b904c24..a8cadaf5be 100644 --- a/rust/src/treefile.rs +++ b/rust/src/treefile.rs @@ -427,7 +427,7 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) { documentation, boot_location, tmp_is_dir, - opt_usrlocal_overlays, + opt_usrlocal, default_target, machineid_compat, releasever, @@ -1412,8 +1412,8 @@ impl Treefile { self.parsed.base.rpmdb_normalize.unwrap_or(false) } - pub(crate) fn get_opt_usrlocal_overlays(&self) -> bool { - self.parsed.base.opt_usrlocal_overlays.unwrap_or_default() + pub(crate) fn get_opt_usrlocal(&self) -> crate::ffi::OptUsrLocal { + self.parsed.base.opt_usrlocal.unwrap_or_default().into() } pub(crate) fn get_files_remove_regex(&self, package: &str) -> Vec { @@ -2405,6 +2405,31 @@ impl From for crate::ffi::RepoMetadataTarget { } } +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum OptUsrLocal { + Var, + Root, + #[serde(alias = "stateoverlay")] + StateOverlay, +} + +impl Default for OptUsrLocal { + fn default() -> Self { + Self::Var + } +} + +impl From for crate::ffi::OptUsrLocal { + fn from(target: OptUsrLocal) -> Self { + match target { + OptUsrLocal::Var => Self::Var, + OptUsrLocal::Root => Self::Root, + OptUsrLocal::StateOverlay => Self::StateOverlay, + } + } +} + #[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] #[serde(rename_all = "kebab-case")] /// The database backend; see https://github.com/coreos/fedora-coreos-tracker/issues/609 @@ -2537,7 +2562,7 @@ pub(crate) struct BaseComposeConfigFields { #[serde(skip_serializing_if = "Option::is_none")] pub(crate) tmp_is_dir: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub(crate) opt_usrlocal_overlays: Option, + pub(crate) opt_usrlocal: Option, // systemd #[serde(skip_serializing_if = "Option::is_none")] diff --git a/src/app/rpmostree-compose-builtin-tree.cxx b/src/app/rpmostree-compose-builtin-tree.cxx index d52974b9e6..1f2862f893 100644 --- a/src/app/rpmostree-compose-builtin-tree.cxx +++ b/src/app/rpmostree-compose-builtin-tree.cxx @@ -498,7 +498,7 @@ install_packages (RpmOstreeTreeComposeContext *self, gboolean *out_unmodified, cancellable, error)) return FALSE; - if ((*self->treefile_rs)->get_opt_usrlocal_overlays ()) + if ((*self->treefile_rs)->get_opt_usrlocal () == rpmostreecxx::OptUsrLocal::StateOverlay) { if (!glnx_file_copy_at ( pkglibdir_dfd, "rpm-ostree-0-integration-opt-usrlocal-compat.conf", NULL, rootfs_dfd, diff --git a/src/libpriv/rpmostree-core.cxx b/src/libpriv/rpmostree-core.cxx index 9cc872b27b..fc6b046a97 100644 --- a/src/libpriv/rpmostree-core.cxx +++ b/src/libpriv/rpmostree-core.cxx @@ -4357,7 +4357,7 @@ rpmostree_context_assemble (RpmOstreeContext *self, GCancellable *cancellable, G * under /usr as well as symlinks under /var. We're really interested here * in the / var part. We don't want to change the /usr/local setting from the * base tree (or in a base compose, from `filesystem`). */ - ROSCXX_TRY (rootfs_prepare_links (tmprootfs_dfd, true), error); + ROSCXX_TRY (rootfs_prepare_links (tmprootfs_dfd, *self->treefile_rs, true), error); CXX_TRY_VAR (etc_guard, rpmostreecxx::prepare_tempetc_guard (tmprootfs_dfd), error); diff --git a/src/libpriv/rpmostree-postprocess.cxx b/src/libpriv/rpmostree-postprocess.cxx index ad29741136..9b5cdec7be 100644 --- a/src/libpriv/rpmostree-postprocess.cxx +++ b/src/libpriv/rpmostree-postprocess.cxx @@ -426,7 +426,7 @@ postprocess_final (int rootfs_dfd, rpmostreecxx::Treefile &treefile, gboolean un return glnx_prefix_error (error, "SELinux postprocess"); } - ROSCXX_TRY (rootfs_prepare_links (rootfs_dfd, false), error); + ROSCXX_TRY (rootfs_prepare_links (rootfs_dfd, treefile, false), error); if (!unified_core_mode) ROSCXX_TRY (convert_var_to_tmpfiles_d (rootfs_dfd, *cancellable), error); diff --git a/tests/compose/libbasic-test.sh b/tests/compose/libbasic-test.sh index 78ad72b19e..0a7517608f 100644 --- a/tests/compose/libbasic-test.sh +++ b/tests/compose/libbasic-test.sh @@ -128,6 +128,8 @@ ostree --repo="${repo}" ls "${treeref}" /usr/lib/alternatives | grep '^d00755'> assert_file_has_content_literal dirs.txt '/usr/lib/alternatives' ostree --repo="${repo}" ls "${treeref}" /usr/local | grep '^l00777' > symlinks.txt assert_file_has_content_literal symlinks.txt '/usr/local -> ../var/usrlocal' +ostree --repo="${repo}" ls "${treeref}" /opt > symlinks.txt +assert_file_has_content_literal symlinks.txt '/opt -> var/opt' echo "ok symlinks" # Check iptables setup through alternatives. diff --git a/tests/compose/libcomposetest.sh b/tests/compose/libcomposetest.sh index ed36946be1..39c5f03870 100644 --- a/tests/compose/libcomposetest.sh +++ b/tests/compose/libcomposetest.sh @@ -84,6 +84,7 @@ runcompose() { runasroot() { if has_compose_privileges; then + set -x "$@" else runvm "$@" diff --git a/tests/compose/test-misc-tweaks.sh b/tests/compose/test-misc-tweaks.sh index 3630e31995..c8ca7e15f1 100755 --- a/tests/compose/test-misc-tweaks.sh +++ b/tests/compose/test-misc-tweaks.sh @@ -44,6 +44,7 @@ selinux-label-version: 1 readonly-executables: true container-cmd: - /usr/bin/bash +opt-usrlocal: "root" EOF treefile_append "include" '["documentation.yaml", "other.yaml"]' for x in 'recommends' 'documentation' 'readonly-executables'; do @@ -179,6 +180,12 @@ ostree --repo=${repo} ls ${treeref} /usr/etc > out.txt assert_file_has_content out.txt 'etc/sharedfile' echo "ok remove-from-packages" +ostree --repo=${repo} ls ${treeref} /opt > ls.txt +assert_file_has_content ls.txt '^d0' +ostree --repo=${repo} ls ${treeref} /usr/local > ls.txt +assert_file_has_content ls.txt '^d0' +echo "ok opt-usrlocal" + # https://github.com/projectatomic/rpm-ostree/issues/669 ostree --repo=${repo} ls ${treeref} /tmp > ls.txt assert_file_has_content ls.txt 'l00777 0 0 0 /tmp -> sysroot/tmp' diff --git a/tests/compose/test-state-overlays.sh b/tests/compose/test-state-overlays.sh index a5a6bfa236..257c8543c8 100755 --- a/tests/compose/test-state-overlays.sh +++ b/tests/compose/test-state-overlays.sh @@ -27,7 +27,7 @@ ln "$PWD/yumrepo.repo" config/yumrepo.repo treefile_append "packages" '["test-opt", "test-usr-local"]' # enable state overlays -treefile_set "opt-usrlocal-overlays" 'True' +treefile_set "opt-usrlocal" '"stateoverlay"' runcompose diff --git a/tests/kolainst/destructive/apply-live b/tests/kolainst/destructive/apply-live index 25310aeca4..b2ed11ada3 100755 --- a/tests/kolainst/destructive/apply-live +++ b/tests/kolainst/destructive/apply-live @@ -27,7 +27,7 @@ cd $(mktemp -d) # apply-live is not yet compatible with state overlays # https://github.com/coreos/rpm-ostree/pull/4810#issuecomment-1939351259 -if jq -e '.["opt-usrlocal-overlays"]' /usr/share/rpm-ostree/treefile.json; then +if test $(jq -r '.["opt-usrlocal"]' /usr/share/rpm-ostree/treefile.json) = "stateoverlay"; then echo "skip apply-live does not work currently with state overlays" exit 0 fi diff --git a/tests/kolainst/destructive/state-overlays b/tests/kolainst/destructive/state-overlays index 2d00afa661..be06d2981b 100755 --- a/tests/kolainst/destructive/state-overlays +++ b/tests/kolainst/destructive/state-overlays @@ -31,10 +31,10 @@ case "${AUTOPKGTEST_REBOOT_MARK:-}" in rpm-ostree override replace https://bodhi.fedoraproject.org/updates/FEDORA-2024-6c7480dd2f fi - # FCOS doesn't enable opt-usrlocal-overlays yet. It's on in Prow CI though. + # FCOS doesn't enable opt-usrlocal = stateoverlay yet. It's on in Prow CI though. # Just check the treefile so we do the right thing regardless of CoreOS CI # or Prow. - if ! jq -e '.["opt-usrlocal-overlays"]' /usr/share/rpm-ostree/treefile.json; then + if test "$(jq -r '.["opt-usrlocal"]' /usr/share/rpm-ostree/treefile.json)" = null; then mkdir -p /etc/systemd/system/rpm-ostreed.service.d/ cat > /etc/systemd/system/rpm-ostreed.service.d/state-overlay.conf <