From fa405031919bbfafbb8aad4f29b317ff86ce5186 Mon Sep 17 00:00:00 2001 From: Matt Clay Date: Tue, 9 Jul 2024 13:49:07 -0700 Subject: [PATCH] [stable-2.17] dnf: follow-up on is_newer_installed arches fix (#83556) (#83563) * dnf: follow-up on is_newer_installed arches fix * fix for the non package object case * prevent early bailout in dnf _is_newer_version_installed * non-installed available arches would fail out of the check early --------- (cherry picked from commit 28cef00576c243b87b59961bffb110f9df855c23) Co-authored-by: Martin Krizek --- lib/ansible/modules/dnf.py | 23 ++++++++----- test/integration/targets/dnf/tasks/repo.yml | 37 +++++++++++++++++++++ 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/lib/ansible/modules/dnf.py b/lib/ansible/modules/dnf.py index a241d9b9ca8..72f62aab0c0 100644 --- a/lib/ansible/modules/dnf.py +++ b/lib/ansible/modules/dnf.py @@ -743,18 +743,25 @@ class DnfModule(YumDnf): else: return bool(installed_query) - def _is_newer_version_installed(self, pkg_name): + def _is_newer_version_installed(self, pkg_spec): try: - if isinstance(pkg_name, dnf.package.Package): - available = pkg_name + if isinstance(pkg_spec, dnf.package.Package): + installed = sorted(self.base.sack.query().installed().filter(name=pkg_spec.name, arch=pkg_spec.arch))[-1] + return installed.evr_gt(pkg_spec) else: - available = sorted( - dnf.subject.Subject(pkg_name).get_best_query(sack=self.base.sack).available().run() - )[-1] - installed = sorted(self.base.sack.query().installed().filter(name=available.name).run())[-1] + available = dnf.subject.Subject(pkg_spec).get_best_query(sack=self.base.sack).available() + installed = self.base.sack.query().installed().filter(name=available[0].name) + for arch in sorted(set(p.arch for p in installed)): # select only from already-installed arches for this case + installed_pkg = sorted(installed.filter(arch=arch))[-1] + try: + available_pkg = sorted(available.filter(arch=arch))[-1] + except IndexError: + continue # nothing currently available for this arch; keep going + if installed_pkg.evr_gt(available_pkg): + return True + return False except IndexError: return False - return installed.evr_gt(available) and installed.arch == available.arch def _mark_package_install(self, pkg_spec, upgrade=False): """Mark the package for install.""" diff --git a/test/integration/targets/dnf/tasks/repo.yml b/test/integration/targets/dnf/tasks/repo.yml index 634b46f48ca..31ad9633343 100644 --- a/test/integration/targets/dnf/tasks/repo.yml +++ b/test/integration/targets/dnf/tasks/repo.yml @@ -562,3 +562,40 @@ dnf: name: dinginessentail state: absent + +- block: + - name: make sure dinginessentail is not installed + dnf: + name: dinginessentail + state: absent + + - name: install dinginessentail both archs + dnf: + name: + - "{{ repodir }}/dinginessentail-1.1-1.x86_64.rpm" + - "{{ repodir_i686 }}/dinginessentail-1.1-1.i686.rpm" + state: present + disable_gpg_check: true + + - name: try to install lower version of dinginessentail from rpm file, without allow_downgrade, just one arch + dnf: + name: "{{ repodir_i686 }}/dinginessentail-1.0-1.i686.rpm" + state: present + register: dnf_result + + - name: check dinginessentail with rpm + shell: rpm -q dinginessentail + register: rpm_result + + - name: verify installation + assert: + that: + - "not dnf_result.changed" + - "rpm_result.stdout_lines[0].startswith('dinginessentail-1.1-1')" + - "rpm_result.stdout_lines[1].startswith('dinginessentail-1.1-1')" + always: + - name: Clean up + dnf: + name: dinginessentail + state: absent + when: ansible_architecture == "x86_64"