Skip to content

Commit

Permalink
treefile: Add exclude-packages
Browse files Browse the repository at this point in the history
In FCOS we have a kola test that basically does `rpm -q python`.
It's...a bit silly to spawn a whole VM for this.  Ensuring that
some specific packages don't get included has come up in a few
cases.

I think FCOS/RHCOS at least will want to blacklist `dnf` for example.
And as noted above, FCOS could blacklist `python`.

One major benefit of doing this inside rpm-ostree is that one
gets the full "libsolv error message experience" when dependency
resolution fails, e.g. blacklisting `glibc` I get:

```
 Problem 79: conflicting requests
  - package coreos-installer-systemd-0.1.2-1.fc31.x86_64 requires coreos-installer = 0.1.2-1.fc31, but none of the providers can be installed
  - package coreos-installer-0.1.2-1.fc31.x86_64 requires rtld(GNU_HASH), but none of the providers can be installed
  - package glibc-2.30-10.fc31.x86_64 is filtered out by exclude filtering
  - package glibc-2.30-7.fc31.x86_64 is filtered out by exclude filtering
  - package glibc-2.30-8.fc31.x86_64 is filtered out by exclude filtering
  - package glibc-2.30-5.fc31.i686 is filtered out by exclude filtering
  - package glibc-2.30-5.fc31.x86_64 is filtered out by exclude filtering
  - package glibc-2.30-10.fc31.i686 is filtered out by exclude filtering
```
  • Loading branch information
cgwalters committed Feb 5, 2020
1 parent 70c3856 commit 7673390
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 0 deletions.
9 changes: 9 additions & 0 deletions docs/manual/treefile.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ It supports the following parameters:
* `packages-$basearch`: Array of strings, optional: Set of installed packages, used
only if $basearch matches the target architecture name.

* `exclude-packages`: Array of strings, optional: Each entry in this list is a package name
which will be filtered out. If a package listed in the manifest ("manifest package") indirectly hard depends
on one of these packages, it will be a fatal error. If a manifest package recommends one
of these packages, the recommended package will simply be omitted. It is also a fatal
error to include a package both as a manifest package and in the blacklist.

An example use case for this is for Fedora CoreOS, which will blacklist the `python` and `python3`
packages to ensure that nothing included in the OS starts depending on it in the future.

* `ostree-layers`: Array of strings, optional: After all packages are unpacked,
check out these OSTree refs, which must already be in the destination repository.
Any conflicts with packages will be an error.
Expand Down
4 changes: 4 additions & 0 deletions rust/src/treefile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) {
repos,
packages,
bootstrap_packages,
exclude_packages,
ostree_layers,
ostree_override_layers,
install_langs,
Expand Down Expand Up @@ -656,6 +657,9 @@ struct TreeComposeConfig {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "ostree-override-layers")]
ostree_override_layers: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "exclude-packages")]
exclude_packages: Option<Vec<String>>,

// Content installation opts
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down
2 changes: 2 additions & 0 deletions src/app/rpmostree-composeutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, "exclude-packages", NULL, FALSE, error))
return FALSE;
if (!treespec_bind_array (treedata, treespec, "repos", NULL, TRUE, error))
return FALSE;
if (!treespec_bind_bool (treedata, treespec, "documentation", TRUE, error))
Expand Down
18 changes: 18 additions & 0 deletions src/libpriv/rpmostree-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, "exclude-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);
Expand Down Expand Up @@ -1891,8 +1892,11 @@ rpmostree_context_prepare (RpmOstreeContext *self,

DnfContext *dnfctx = self->dnfctx;
g_autofree char **pkgnames = NULL;
g_autofree char **exclude_packages = NULL;
g_assert (g_variant_dict_lookup (self->spec->dict, "packages",
"^a&s", &pkgnames));
g_variant_dict_lookup (self->spec->dict, "exclude-packages",
"^a&s", &exclude_packages);

g_autofree char **cached_pkgnames = NULL;
g_assert (g_variant_dict_lookup (self->spec->dict, "cached-packages",
Expand Down Expand Up @@ -2023,6 +2027,20 @@ rpmostree_context_prepare (RpmOstreeContext *self,
}
}

/* Process excludes */
for (char **iter = exclude_packages; 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++)
Expand Down
9 changes: 9 additions & 0 deletions tests/common/libtest-core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ assert_file_has_content_literal () {
done
}

assert_not_file_has_content_literal () {
fpath=$1; shift
for s in "$@"; do
if grep -q -F -e "$s" "$fpath"; then
_fatal_print_file "$fpath" "File '$fpath' matches fixed string list '$s'"
fi
done
}

assert_symlink_has_content () {
if ! test -L "$1"; then
fatal "File '$1' is not a symbolic link"
Expand Down
41 changes: 41 additions & 0 deletions tests/compose/test-excludes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash
set -xeuo pipefail

dn=$(cd "$(dirname "$0")" && pwd)
# shellcheck source=libcomposetest.sh
. "${dn}/libcomposetest.sh"

# Add a local rpm-md repo for recommends testing
treefile_append "repos" '["test-repo"]'
build_rpm foodep
build_rpm foobar recommends foobar-rec requires foodep
build_rpm foobar-rec

echo gpgcheck=0 >> yumrepo.repo
ln "$PWD/yumrepo.repo" config/yumrepo.repo
# the top-level manifest doesn't have any packages, so just set it
treefile_append "packages" '["foobar"]'
treefile_set 'recommends' "True"

runcompose --dry-run >log.txt
assert_file_has_content_literal log.txt 'foobar-1.0'
assert_file_has_content_literal log.txt 'foobar-rec-1.0'
rm -f log.txt
echo "ok no exclude"

# Test exclude
treefile_append "exclude-packages" '["foobar-rec"]'

runcompose --dry-run >log.txt
assert_file_has_content_literal log.txt 'foobar-1.0'
assert_not_file_has_content_literal log.txt 'foobar-rec-1.0'
rm -f log.txt
echo "ok exclude recommend"

treefile_append "exclude-packages" '["foodep"]'

if runcompose --dry-run 2>err.txt; then
fatal "compose unexpectedly succeeded"
fi
assert_file_has_content err.txt 'package foodep.*is filtered out by exclude filtering'
echo "ok exclude included"
3 changes: 3 additions & 0 deletions tests/compose/test-misc-tweaks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ treefile_append "include" '["documentation.yaml", "recommends.yaml"]'
treefile_del 'recommends'
treefile_del 'documentation'

# Test blacklists
treefile_append "exclude-packages" '["somenonexistent-package", "gnome-shell"]'

# Note this overrides:
# $ rpm -q systemd
# systemd-243.4-1.fc31.x86_64
Expand Down

0 comments on commit 7673390

Please sign in to comment.