diff --git a/0001-extensions-Add-support-for-per-extension-repos-and-m.patch b/0001-extensions-Add-support-for-per-extension-repos-and-m.patch new file mode 100644 index 0000000..0f3dafe --- /dev/null +++ b/0001-extensions-Add-support-for-per-extension-repos-and-m.patch @@ -0,0 +1,155 @@ +From 9b4b19cda21c84fa68496e1874a31044e099d742 Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Wed, 29 Sep 2021 14:33:04 -0400 +Subject: [PATCH] extensions: Add support for per-extension repos and modules + +While we support arch-specific extensions today, the state of +repos and modules are global. Which means if a module-using +extension is only available on one architecture (as is the +case in RHEL8/OCP with the `av` module) then it's not +possible to build on other architectures. + +The most powerful mechanism here is the `arch-include` design +that we have in the treefile, but...since we already have +an architecture filter per extension, it's easier to add +repos and modules per extension. + +Note that the repos and modules are still *global* state, so +we're not supporting actively conflicting extensions right now +still. + +Closes: https://github.com/coreos/rpm-ostree/issues/3150 +--- + docs/extensions.md | 12 +++++++++++ + rust/src/extensions.rs | 46 ++++++++++++++++++++++++++++++++++++++++++ + rust/src/treefile.rs | 2 +- + 3 files changed, 59 insertions(+), 1 deletion(-) + +diff --git a/docs/extensions.md b/docs/extensions.md +index 9dbc6230..bc3d0d7b 100644 +--- a/docs/extensions.md ++++ b/docs/extensions.md +@@ -55,6 +55,18 @@ extensions: + packages: + - strace + - ltrace ++ # Optional additional repos (still added globally). ++ # The reason use per-extension `repos` and `modules` ++ # is that it more closely groups them (where relevant) ++ # and further these are only added after architecture conditionals ++ # apply, so one can use repositories that only exist ++ # on a particular architecture. ++ repos: ++ - sooper-repo ++ # Optional additional modules (this also affects global state) ++ modules: ++ enable: ++ - sooper:latest + # Optional list of architectures on which this extension + # is valid. These are RPM basearches. If omitted, + # defaults to all architectures. +diff --git a/rust/src/extensions.rs b/rust/src/extensions.rs +index e667f886..df37b792 100644 +--- a/rust/src/extensions.rs ++++ b/rust/src/extensions.rs +@@ -34,6 +34,10 @@ pub struct Extensions { + pub struct Extension { + packages: Vec, + #[serde(skip_serializing_if = "Option::is_none")] ++ repos: Option>, ++ #[serde(skip_serializing_if = "Option::is_none")] ++ modules: Option, ++ #[serde(skip_serializing_if = "Option::is_none")] + architectures: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + match_base_evr: Option, +@@ -74,6 +78,14 @@ fn extensions_load_stream( + .collect(); + + for (_, ext) in parsed.extensions.iter_mut() { ++ // Extend the global extension state with the per-extension repos and modules, ++ // after we've done architecture filtering. ++ if let Some(repos) = parsed.repos.as_mut() { ++ repos.extend(ext.repos.take().unwrap_or_default()); ++ } else { ++ parsed.repos = ext.repos.take(); ++ } ++ crate::treefile::merge_modules(&mut parsed.modules, &mut ext.modules); + if ext.kind == ExtensionKind::OsExtension { + for pkg in &ext.packages { + if base_pkgs.contains_key(pkg.as_str()) { +@@ -264,10 +276,17 @@ extensions: + #[test] + fn basearch_filter() { + let buf = r###" ++repos: ++ - baserepo ++modules: ++ enable: ++ - virt:av + extensions: + bazboo: + packages: + - bazboo ++ repos: ++ - bazboo-repo + architectures: + - x86_64 + dodo: +@@ -276,13 +295,40 @@ extensions: + - dada + architectures: + - s390x ++ foo: ++ modules: ++ enable: ++ - foo:stable ++ packages: ++ - foo ++ repos: ++ - foo-repo ++ architectures: ++ - ppc64le + "###; + let mut input = std::io::BufReader::new(buf.as_bytes()); + let extensions = extensions_load_stream(&mut input, "x86_64", &base_rpmdb()).unwrap(); + assert!(extensions.get_os_extension_packages() == vec!["bazboo"]); ++ assert_eq!(extensions.get_repos().len(), 2); ++ assert_eq!(extensions.get_repos()[1], "bazboo-repo"); ++ let modules = extensions.modules.unwrap(); ++ assert_eq!(modules.enable.unwrap(), vec!["virt:av"]); ++ assert!(modules.install.is_none()); ++ + let mut input = std::io::BufReader::new(buf.as_bytes()); + let extensions = extensions_load_stream(&mut input, "s390x", &base_rpmdb()).unwrap(); + assert!(extensions.get_os_extension_packages() == vec!["dodo", "dada"]); ++ assert_eq!(extensions.get_repos().len(), 1); ++ assert_eq!(extensions.get_repos()[0], "baserepo"); ++ ++ let mut input = std::io::BufReader::new(buf.as_bytes()); ++ let extensions = extensions_load_stream(&mut input, "ppc64le", &base_rpmdb()).unwrap(); ++ assert_eq!(extensions.get_os_extension_packages(), vec!["foo"]); ++ assert_eq!(extensions.get_repos().len(), 2); ++ assert_eq!(extensions.get_repos()[1], "foo-repo"); ++ let modules = extensions.modules.unwrap(); ++ assert_eq!(modules.enable.unwrap(), vec!["foo:stable", "virt:av"]); ++ assert!(modules.install.is_none()); + } + + #[test] +diff --git a/rust/src/treefile.rs b/rust/src/treefile.rs +index 2c9af278..9f6c6581 100644 +--- a/rust/src/treefile.rs ++++ b/rust/src/treefile.rs +@@ -324,7 +324,7 @@ fn merge_hashset_field( + } + + /// Merge modules fields. +-fn merge_modules(dest: &mut Option, src: &mut Option) { ++pub(crate) fn merge_modules(dest: &mut Option, src: &mut Option) { + if let Some(mut srcv) = src.take() { + if let Some(mut destv) = dest.take() { + merge_vec_field(&mut destv.enable, &mut srcv.enable); +-- +2.31.1 + diff --git a/0001-extensions-support-enabling-installing-modules.patch b/0001-extensions-support-enabling-installing-modules.patch deleted file mode 100644 index e97bc5a..0000000 --- a/0001-extensions-support-enabling-installing-modules.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 25fcebfeb0e63ce395bdbbf710d4c79888e57130 Mon Sep 17 00:00:00 2001 -From: Jonathan Lebon -Date: Thu, 26 Aug 2021 21:42:21 -0400 -Subject: [PATCH] extensions: support enabling/installing modules - -Fix that gap now since RHCOS does use modular packages in its -extensions. This ended up being easier than I thought because we're just -converting to a treefile underneath. ---- - docs/extensions.md | 11 +++++++++++ - rust/src/extensions.rs | 3 +++ - rust/src/treefile.rs | 2 +- - 3 files changed, 15 insertions(+), 1 deletion(-) - -diff --git a/docs/extensions.md b/docs/extensions.md -index a754b185..9dbc6230 100644 ---- a/docs/extensions.md -+++ b/docs/extensions.md -@@ -30,6 +30,17 @@ extension packages and places them in an output directory. - The format of the `extensions.yaml` file is as follow: - - ```yaml -+# Any additional repos to enable on top of treefile repos -+repos: -+ - myrepo -+ -+# Any modules to enable/install -+modules: -+ enable: -+ - foo:bar -+ install: -+ - baz:boo/default -+ - # The top-level object is a dict. The only supported key - # right now is `extensions`, which is a dict of extension - # names to extension objects. -diff --git a/rust/src/extensions.rs b/rust/src/extensions.rs -index ad2fe19b..6cb1a3a6 100644 ---- a/rust/src/extensions.rs -+++ b/rust/src/extensions.rs -@@ -25,6 +25,8 @@ pub struct Extensions { - extensions: HashMap, - #[serde(skip_serializing_if = "Option::is_none")] - repos: Option>, -+ #[serde(skip_serializing_if = "Option::is_none")] -+ modules: Option, - } - - #[derive(Serialize, Deserialize, Debug)] -@@ -162,6 +164,7 @@ impl Extensions { - repos: Some(repos), - packages: Some(self.get_os_extension_packages()), - releasever: src.parsed.releasever.clone(), -+ modules: self.modules.clone(), - ..Default::default() - }; - Ok(Box::new(Treefile::new_from_config(ret, None)?)) -diff --git a/rust/src/treefile.rs b/rust/src/treefile.rs -index 421f2b6c..eeb21a50 100644 ---- a/rust/src/treefile.rs -+++ b/rust/src/treefile.rs -@@ -1290,7 +1290,7 @@ pub(crate) struct RepoPackage { - pub(crate) packages: Vec, - } - --#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq)] -+#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq, Clone)] - pub(crate) struct ModulesConfig { - #[serde(skip_serializing_if = "Option::is_none")] - pub(crate) enable: Option>, --- -2.31.1 - diff --git a/rpm-ostree.spec b/rpm-ostree.spec index ea8f7cd..54aa85c 100644 --- a/rpm-ostree.spec +++ b/rpm-ostree.spec @@ -4,13 +4,16 @@ Summary: Hybrid image/package system Name: rpm-ostree Version: 2021.11 -Release: 2%{?dist} +Release: 3%{?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 +# For multiarch openshift/os extensions +Patch0: 0001-extensions-Add-support-for-per-extension-repos-and-m.patch + ExclusiveArch: %{rust_arches} BuildRequires: make @@ -221,6 +224,9 @@ $PYTHON autofiles.py > files.devel \ %files devel -f files.devel %changelog +* Thu Sep 30 2021 Colin Walters - 2021.11-3 +- Backport patch for openshift/os extensions + multiarch + * Fri Sep 24 2021 Colin Walters - 2021.11-2 - https://github.com/coreos/rpm-ostree/releases/tag/v2021.11