rpm-ostree/0001-extensions-Add-support-for-per-extension-repos-and-m.patch

156 lines
5.8 KiB
Diff

From 9b4b19cda21c84fa68496e1874a31044e099d742 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
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<String>,
#[serde(skip_serializing_if = "Option::is_none")]
+ repos: Option<Vec<String>>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ modules: Option<crate::treefile::ModulesConfig>,
+ #[serde(skip_serializing_if = "Option::is_none")]
architectures: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
match_base_evr: Option<String>,
@@ -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<T: Eq + std::hash::Hash>(
}
/// Merge modules fields.
-fn merge_modules(dest: &mut Option<ModulesConfig>, src: &mut Option<ModulesConfig>) {
+pub(crate) fn merge_modules(dest: &mut Option<ModulesConfig>, src: &mut Option<ModulesConfig>) {
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