Allow disabling inheriting ExcludeArch to noarch packages

Copying ExcludeArch/ExclusiveArch from source rpm to noarch is an easy
option to block shipping that particular noarch package from a certain
architecture. However, there is no way to bypass it, and it is rather
confusing and not discoverable.

An alternative way to remove an unwanted package is to use the good old
`filter_packages`, which has enough granularity to remove pretty much
anything from anywhere. The only downside is that it requires a change
in configuration, so it can't be done by a packager directly from a spec
file.

When we decide to break backwards compatibility, this option should be
removed and the entire ExcludeArch/ExclusiveArch inheritance removed
completely.

JIRA: ENGCMP-2606
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit ab508c1511)
This commit is contained in:
Lubomír Sedlář 2022-09-22 16:17:53 +02:00 committed by Stepan Oksanichenko
parent 135bbbfe7e
commit 4cb8671fe4
Signed by: soksanichenko
GPG Key ID: AB9983172AB1E45B
6 changed files with 71 additions and 9 deletions

View File

@ -581,6 +581,16 @@ Options
with everything. Set this option to ``False`` to ignore ``noarch`` in with everything. Set this option to ``False`` to ignore ``noarch`` in
``ExclusiveArch`` and always consider only binary architectures. ``ExclusiveArch`` and always consider only binary architectures.
**pkgset_inherit_exclusive_arch_to_noarch** = True
(*bool*) -- When set to ``True``, the value of ``ExclusiveArch`` or
``ExcludeArch`` will be copied from source rpm to all its noarch packages.
That will than limit which architectures the noarch packages can be
included in.
By setting this option to ``False`` this step is skipped, and noarch
packages will by default land in all architectures. They can still be
excluded by listing them in a relevant section of ``filter_packages``.
**pkgset_allow_reuse** = True **pkgset_allow_reuse** = True
(*bool*) -- When set to ``True``, *Pungi* will try to reuse pkgset data (*bool*) -- When set to ``True``, *Pungi* will try to reuse pkgset data
from the old composes specified by ``--old-composes``. When enabled, this from the old composes specified by ``--old-composes``. When enabled, this

View File

@ -865,6 +865,10 @@ def make_schema():
"type": "boolean", "type": "boolean",
"default": True, "default": True,
}, },
"pkgset_inherit_exclusive_arch_to_noarch": {
"type": "boolean",
"default": True,
},
"pkgset_scratch_modules": { "pkgset_scratch_modules": {
"type": "object", "type": "object",
"patternProperties": { "patternProperties": {

View File

@ -38,12 +38,17 @@ from pungi.phases.createrepo import add_modular_metadata
def populate_arch_pkgsets(compose, path_prefix, global_pkgset): def populate_arch_pkgsets(compose, path_prefix, global_pkgset):
result = {} result = {}
exclusive_noarch = compose.conf["pkgset_exclusive_arch_considers_noarch"]
for arch in compose.get_arches(): for arch in compose.get_arches():
compose.log_info("Populating package set for arch: %s", arch) compose.log_info("Populating package set for arch: %s", arch)
is_multilib = is_arch_multilib(compose.conf, arch) is_multilib = is_arch_multilib(compose.conf, arch)
arches = get_valid_arches(arch, is_multilib, add_src=True) arches = get_valid_arches(arch, is_multilib, add_src=True)
pkgset = global_pkgset.subset(arch, arches, exclusive_noarch=exclusive_noarch) pkgset = global_pkgset.subset(
arch,
arches,
exclusive_noarch=compose.conf["pkgset_exclusive_arch_considers_noarch"],
inherit_to_noarch=compose.conf["pkgset_inherit_exclusive_arch_to_noarch"],
)
pkgset.save_file_list( pkgset.save_file_list(
compose.paths.work.package_list(arch=arch, pkgset=global_pkgset), compose.paths.work.package_list(arch=arch, pkgset=global_pkgset),
remove_path_prefix=path_prefix, remove_path_prefix=path_prefix,

View File

@ -211,16 +211,31 @@ class PackageSetBase(kobo.log.LoggingBase):
return self.rpms_by_arch return self.rpms_by_arch
def subset(self, primary_arch, arch_list, exclusive_noarch=True): def subset(
self, primary_arch, arch_list, exclusive_noarch=True, inherit_to_noarch=True
):
"""Create a subset of this package set that only includes """Create a subset of this package set that only includes
packages compatible with""" packages compatible with"""
pkgset = PackageSetBase( pkgset = PackageSetBase(
self.name, self.sigkey_ordering, logger=self._logger, arches=arch_list self.name, self.sigkey_ordering, logger=self._logger, arches=arch_list
) )
pkgset.merge(self, primary_arch, arch_list, exclusive_noarch=exclusive_noarch) pkgset.merge(
self,
primary_arch,
arch_list,
exclusive_noarch=exclusive_noarch,
inherit_to_noarch=inherit_to_noarch,
)
return pkgset return pkgset
def merge(self, other, primary_arch, arch_list, exclusive_noarch=True): def merge(
self,
other,
primary_arch,
arch_list,
exclusive_noarch=True,
inherit_to_noarch=True,
):
""" """
Merge ``other`` package set into this instance. Merge ``other`` package set into this instance.
""" """
@ -259,7 +274,7 @@ class PackageSetBase(kobo.log.LoggingBase):
if i.file_path in self.file_cache: if i.file_path in self.file_cache:
# TODO: test if it really works # TODO: test if it really works
continue continue
if exclusivearch_list and arch == "noarch": if inherit_to_noarch and exclusivearch_list and arch == "noarch":
if is_excluded(i, exclusivearch_list, logger=self._logger): if is_excluded(i, exclusivearch_list, logger=self._logger):
continue continue

View File

@ -47,7 +47,7 @@ class TestMaterializedPkgsetCreate(helpers.PungiTestCase):
pkgset.name = name pkgset.name = name
pkgset.reuse = None pkgset.reuse = None
def mock_subset(primary, arch_list, exclusive_noarch): def mock_subset(primary, arch_list, **kwargs):
self.subsets[primary] = mock.Mock() self.subsets[primary] = mock.Mock()
return self.subsets[primary] return self.subsets[primary]
@ -73,10 +73,16 @@ class TestMaterializedPkgsetCreate(helpers.PungiTestCase):
self.assertEqual(result["amd64"], self.subsets["amd64"]) self.assertEqual(result["amd64"], self.subsets["amd64"])
self.pkgset.subset.assert_any_call( self.pkgset.subset.assert_any_call(
"x86_64", ["x86_64", "noarch", "src"], exclusive_noarch=True "x86_64",
["x86_64", "noarch", "src"],
exclusive_noarch=True,
inherit_to_noarch=True,
) )
self.pkgset.subset.assert_any_call( self.pkgset.subset.assert_any_call(
"amd64", ["amd64", "x86_64", "noarch", "src"], exclusive_noarch=True "amd64",
["amd64", "x86_64", "noarch", "src"],
exclusive_noarch=True,
inherit_to_noarch=True,
) )
for arch, pkgset in result.package_sets.items(): for arch, pkgset in result.package_sets.items():

View File

@ -1181,6 +1181,28 @@ class TestMergePackageSets(PkgsetCompareMixin, unittest.TestCase):
first.rpms_by_arch, {"i686": ["rpms/bash@4.3.42@4.fc24@i686"], "noarch": []} first.rpms_by_arch, {"i686": ["rpms/bash@4.3.42@4.fc24@i686"], "noarch": []}
) )
def test_merge_doesnt_exclude_noarch_exclude_arch_when_configured(self):
first = pkgsets.PackageSetBase("first", [None])
second = pkgsets.PackageSetBase("second", [None])
pkg = first.file_cache.add("rpms/bash@4.3.42@4.fc24@i686")
first.rpms_by_arch.setdefault(pkg.arch, []).append(pkg)
pkg = second.file_cache.add("rpms/pungi@4.1.3@3.fc25@noarch")
pkg.excludearch = ["i686"]
second.rpms_by_arch.setdefault(pkg.arch, []).append(pkg)
first.merge(second, "i386", ["i686", "noarch"], inherit_to_noarch=False)
print(first.rpms_by_arch)
self.assertPkgsetEqual(
first.rpms_by_arch,
{
"i686": ["rpms/bash@4.3.42@4.fc24@i686"],
"noarch": ["rpms/pungi@4.1.3@3.fc25@noarch"],
},
)
def test_merge_excludes_noarch_exclusive_arch(self): def test_merge_excludes_noarch_exclusive_arch(self):
first = pkgsets.PackageSetBase("first", [None]) first = pkgsets.PackageSetBase("first", [None])
second = pkgsets.PackageSetBase("second", [None]) second = pkgsets.PackageSetBase("second", [None])