diff --git a/rust/src/treefile.rs b/rust/src/treefile.rs index c572ec19e1..500a537c3f 100644 --- a/rust/src/treefile.rs +++ b/rust/src/treefile.rs @@ -310,6 +310,7 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) { repos, packages, bootstrap_packages, + blacklist_packages, ostree_layers, ostree_override_layers, install_langs, @@ -656,6 +657,9 @@ struct TreeComposeConfig { #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "ostree-override-layers")] ostree_override_layers: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "blacklist-packages")] + blacklist_packages: Option>, // Content installation opts #[serde(skip_serializing_if = "Option::is_none")] diff --git a/src/app/rpmostree-composeutil.c b/src/app/rpmostree-composeutil.c index 38364499e0..b464b69c17 100644 --- a/src/app/rpmostree-composeutil.c +++ b/src/app/rpmostree-composeutil.c @@ -247,6 +247,8 @@ rpmostree_composeutil_get_treespec (RpmOstreeContext *ctx, if (!treespec_bind_array (treedata, treespec, "packages", NULL, TRUE, error)) return FALSE; + if (!treespec_bind_array (treedata, treespec, "blacklist-packages", NULL, TRUE, error)) + return FALSE; if (!treespec_bind_array (treedata, treespec, "repos", NULL, TRUE, error)) return FALSE; if (!treespec_bind_bool (treedata, treespec, "documentation", TRUE, error)) diff --git a/src/libpriv/rpmostree-core.c b/src/libpriv/rpmostree-core.c index b0e7150a0a..c8076c3c3c 100644 --- a/src/libpriv/rpmostree-core.c +++ b/src/libpriv/rpmostree-core.c @@ -257,6 +257,7 @@ rpmostree_treespec_new_from_keyfile (GKeyFile *keyfile, #undef BIND_STRING add_canonicalized_string_array (&builder, "packages", NULL, keyfile); + add_canonicalized_string_array (&builder, "blacklist-packages", NULL, keyfile); add_canonicalized_string_array (&builder, "cached-packages", NULL, keyfile); add_canonicalized_string_array (&builder, "removed-base-packages", NULL, keyfile); add_canonicalized_string_array (&builder, "cached-replaced-base-packages", NULL, keyfile); @@ -1891,8 +1892,11 @@ rpmostree_context_prepare (RpmOstreeContext *self, DnfContext *dnfctx = self->dnfctx; g_autofree char **pkgnames = NULL; + g_autofree char **blacklist_pkgnames = NULL; g_assert (g_variant_dict_lookup (self->spec->dict, "packages", "^a&s", &pkgnames)); + g_variant_dict_lookup (self->spec->dict, "blacklist-packages", + "^a&s", &blacklist_pkgnames); g_autofree char **cached_pkgnames = NULL; g_assert (g_variant_dict_lookup (self->spec->dict, "cached-packages", @@ -2023,6 +2027,20 @@ rpmostree_context_prepare (RpmOstreeContext *self, } } + /* Process excludes */ + for (char **iter = blacklist_pkgnames; iter && *iter; iter++) + { + const char *pkgname = *iter; + hy_autoquery HyQuery query = hy_query_create (sack); + hy_query_filter (query, HY_PKG_NAME, HY_EQ, pkgname); + g_autoptr(GPtrArray) pkglist = hy_query_run (query); + DnfPackageSet *pset = dnf_packageset_new (sack); + for (guint i = 0; i < pkglist->len; i++) + dnf_packageset_add (pset, pkglist->pdata[i]); + dnf_sack_add_excludes (sack, pset); + dnf_packageset_free (pset); + } + /* First, handle packages to remove */ g_autoptr(GPtrArray) removed_pkgnames = g_ptr_array_new (); for (char **it = removed_base_pkgnames; it && *it; it++) diff --git a/tests/compose/test-misc-tweaks.sh b/tests/compose/test-misc-tweaks.sh index 784299c33d..d32a7735f5 100755 --- a/tests/compose/test-misc-tweaks.sh +++ b/tests/compose/test-misc-tweaks.sh @@ -27,6 +27,9 @@ treefile_append "include" '["documentation.yaml", "recommends.yaml"]' treefile_del 'recommends' treefile_del 'documentation' +# And test blacklists +treefile_append "blacklist-packages" '["somenonexistent-package"]' + # Note this overrides: # $ rpm -q systemd # systemd-243.4-1.fc31.x86_64