dnf5: fix is_installed check for provided packages (#84802)

Fixes #84578
pull/79469/head
Martin Krizek 9 months ago committed by GitHub
parent 7e0d8398ff
commit 7fbaf6cfcf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,2 @@
bugfixes:
- "dnf5 - fix ``is_installed`` check for packages that are not installed but listed as provided by an installed package (https://github.com/ansible/ansible/issues/84578)"

@ -378,10 +378,20 @@ def is_installed(base, spec):
# If users wish to target the `sssd` binary they can by specifying the full path `name=/usr/sbin/sssd` explicitly # If users wish to target the `sssd` binary they can by specifying the full path `name=/usr/sbin/sssd` explicitly
# due to settings.set_with_filenames(True) being default. # due to settings.set_with_filenames(True) being default.
settings.set_with_binaries(False) settings.set_with_binaries(False)
# Disable checking whether SPEC is provided by an installed package.
# Consider following real scenario from the rpmfusion repo:
# * the `ffmpeg-libs` package is installed and provides `libavcodec-freeworld`
# * but `libavcodec-freeworld` is NOT installed (???)
# * due to `set_with_provides(True)` being default `is_installed(base, "libavcodec-freeworld")`
# would "unexpectedly" return True
# We disable provides only for this `is_installed` check, for actual installation we leave the default
# setting to mirror the dnf cmdline behavior.
settings.set_with_provides(False)
except AttributeError: except AttributeError:
# dnf5 < 5.2.0.0 # dnf5 < 5.2.0.0
settings.group_with_name = True settings.group_with_name = True
settings.with_binaries = False settings.with_binaries = False
settings.with_provides = False
installed_query = libdnf5.rpm.PackageQuery(base) installed_query = libdnf5.rpm.PackageQuery(base)
installed_query.filter_installed() installed_query.filter_installed()

@ -587,3 +587,35 @@
- provides-binary - provides-binary
- package-name - package-name
state: absent state: absent
# https://github.com/ansible/ansible/issues/84578
- name: Test installing a package that is listed in `provides` in different package
block:
- dnf:
name: provides-package
state: present
- command: rpm -q provided-package
ignore_errors: true
register: r
- assert:
that:
- r is failed
- dnf:
name: provided-package
state: present
register: r
- assert:
that:
- r is changed
always:
- name: Clean up
dnf:
name: "{{ item }}"
state: absent
loop:
- provides-package
- provided-package

@ -33,6 +33,7 @@ class RPM:
requires: list[str] | None = None requires: list[str] | None = None
file: str | None = None file: str | None = None
binary: str | None = None binary: str | None = None
provides: list[str] | None = None
SPECS = [ SPECS = [
@ -63,6 +64,8 @@ SPECS = [
RPM(name='broken-d', version='1.0', requires=['broken-a']), RPM(name='broken-d', version='1.0', requires=['broken-a']),
RPM(name='provides-binary', version='1.0', arch=[expectedArch], binary='/usr/sbin/package-name'), RPM(name='provides-binary', version='1.0', arch=[expectedArch], binary='/usr/sbin/package-name'),
RPM(name='package-name', version='1.0'), RPM(name='package-name', version='1.0'),
RPM(name='provides-package', version='1.0', provides=['provided-package']),
RPM(name='provided-package', version='1.0'),
] ]
@ -78,6 +81,9 @@ def create_repo():
for recommend in spec.recommends or []: for recommend in spec.recommends or []:
pkg.add_recommends(recommend) pkg.add_recommends(recommend)
for provide in spec.provides or []:
pkg.add_provides(provide)
if spec.file: if spec.file:
pkg.add_installed_file( pkg.add_installed_file(
"/" + spec.file, "/" + spec.file,

Loading…
Cancel
Save