dnf: fix installing a package based the file it provides (#82744)

Fixes #82461
pull/82725/head
Martin Krizek 2 months ago committed by GitHub
parent e0c91af45f
commit a28709f92d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,2 @@
bugfixes:
- dnf - fix an issue when installing a package by specifying a file it provides could result in installing a different package providing the same file than the package already installed resulting in resolution failure (https://github.com/ansible/ansible/issues/82461)

@ -921,17 +921,6 @@ class DnfModule(YumDnf):
return {'failed': False, 'msg': msg, 'failure': '', 'rc': 0}
def _whatprovides(self, filepath):
self.base.read_all_repos()
available = self.base.sack.query().available()
# Search in file
files_filter = available.filter(file=filepath)
# And Search in provides
pkg_spec = files_filter.union(available.filter(provides=filepath)).run()
if pkg_spec:
return pkg_spec[0].name
def _parse_spec_group_file(self):
pkg_specs, grp_specs, module_specs, filenames = [], [], [], []
already_loaded_comps = False # Only load this if necessary, it's slow
@ -943,11 +932,13 @@ class DnfModule(YumDnf):
elif name.endswith(".rpm"):
filenames.append(name)
elif name.startswith('/'):
# like "dnf install /usr/bin/vi"
pkg_spec = self._whatprovides(name)
if pkg_spec:
pkg_specs.append(pkg_spec)
continue
# dnf install /usr/bin/vi
installed = self.base.sack.query().filter(provides=name, file=name).installed().run()
if installed:
pkg_specs.append(installed[0].name) # should be only one?
elif not self.update_only:
# not installed, pass the filename for dnf to process
pkg_specs.append(name)
elif name.startswith("@") or ('/' in name):
if not already_loaded_comps:
self.base.read_comps()

@ -435,3 +435,35 @@
dnf:
name: dinginessentail
state: absent
- name: >
test that when a package providing a file is installed then installing by specifying the file doesn't result in
installing a different package providing the same file
block:
- dnf:
name: provides_foo_b
state: "{{ item }}"
loop:
- absent
- present
- dnf:
name: /foo.so
state: present
register: dnf_result
- command: rpm -q package_foo_a
ignore_errors: true
register: rpm_result
- assert:
that:
- dnf_result is not changed
- rpm_result.rc == 1
always:
- name: Clean up
dnf:
name: "{{ item }}"
state: absent
loop:
- provides_foo_b

@ -12,10 +12,12 @@ from ansible.module_utils.common.respawn import has_respawned, probe_interpreter
HAS_RPMFLUFF = True
can_use_rpm_weak_deps = None
try:
from rpmfluff import SimpleRpmBuild
from rpmfluff import SimpleRpmBuild, GeneratedSourceFile, make_elf
from rpmfluff import YumRepoBuild
except ImportError:
try:
from rpmfluff.make import make_elf
from rpmfluff.sourcefile import GeneratedSourceFile
from rpmfluff.rpmbuild import SimpleRpmBuild
from rpmfluff.yumrepobuild import YumRepoBuild
except ImportError:
@ -32,20 +34,21 @@ if HAS_RPMFLUFF:
pass
RPM = namedtuple('RPM', ['name', 'version', 'release', 'epoch', 'recommends', 'arch'])
RPM = namedtuple('RPM', ['name', 'version', 'release', 'epoch', 'recommends', 'file', 'arch'])
SPECS = [
RPM('dinginessentail', '1.0', '1', None, None, None),
RPM('dinginessentail', '1.0', '2', '1', None, None),
RPM('dinginessentail', '1.1', '1', '1', None, None),
RPM('dinginessentail-olive', '1.0', '1', None, None, None),
RPM('dinginessentail-olive', '1.1', '1', None, None, None),
RPM('landsidescalping', '1.0', '1', None, None, None),
RPM('landsidescalping', '1.1', '1', None, None, None),
RPM('dinginessentail-with-weak-dep', '1.0', '1', None, ['dinginessentail-weak-dep'], None),
RPM('dinginessentail-weak-dep', '1.0', '1', None, None, None),
RPM('noarchfake', '1.0', '1', None, None, 'noarch'),
RPM('dinginessentail', '1.0', '1', None, None, None, None),
RPM('dinginessentail', '1.0', '2', '1', None, None, None),
RPM('dinginessentail', '1.1', '1', '1', None, None, None),
RPM('dinginessentail-olive', '1.0', '1', None, None, None, None),
RPM('dinginessentail-olive', '1.1', '1', None, None, None, None),
RPM('landsidescalping', '1.0', '1', None, None, None, None),
RPM('landsidescalping', '1.1', '1', None, None, None, None),
RPM('dinginessentail-with-weak-dep', '1.0', '1', None, ['dinginessentail-weak-dep'], None, None),
RPM('dinginessentail-weak-dep', '1.0', '1', None, None, None, None),
RPM('noarchfake', '1.0', '1', None, None, None, 'noarch'),
RPM('provides_foo_a', '1.0', '1', None, None, 'foo.so', 'noarch'),
RPM('provides_foo_b', '1.0', '1', None, None, 'foo.so', 'noarch'),
]
@ -63,6 +66,14 @@ def create_repo(arch='x86_64'):
for recommend in spec.recommends:
pkg.add_recommends(recommend)
if spec.file:
pkg.add_installed_file(
"/" + spec.file,
GeneratedSourceFile(
spec.file, make_elf()
)
)
pkgs.append(pkg)
repo = YumRepoBuild(pkgs)

Loading…
Cancel
Save