[dnf] Make "remove" filtering closer to dnf CLI (#73033)
Change: - Internally, use dnf.subject.Subject#get_best_query for state: absent - Add a bunch of tests for removing packages, given a bunch of different pkg specs (nv, nvr, nvra, wildcard, etc.) Test Plan: - New tests - Local experiments with DNF API via PDB. Tickets: - Fixes #72809 Signed-off-by: Rick Elrod <rick@elrod.me>
This commit is contained in:
parent
77942acefc
commit
44ee04bd1f
4 changed files with 76 additions and 15 deletions
2
changelogs/fragments/72809-dnf-remove-NV.yml
Normal file
2
changelogs/fragments/72809-dnf-remove-NV.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- "dnf - When ``state: absent``, package names are now matched similarly to how the ``dnf`` CLI matches them (https://github.com/ansible/ansible/issues/72809)."
|
|
@ -1155,21 +1155,11 @@ class DnfModule(YumDnf):
|
|||
response['results'].append(handled_remove_error)
|
||||
continue
|
||||
|
||||
installed_pkg = list(map(str, installed.filter(name=pkg_spec).run()))
|
||||
if installed_pkg:
|
||||
candidate_pkg = self._packagename_dict(installed_pkg[0])
|
||||
installed_pkg = installed.filter(name=candidate_pkg['name']).run()
|
||||
else:
|
||||
candidate_pkg = self._packagename_dict(pkg_spec)
|
||||
installed_pkg = installed.filter(nevra=pkg_spec).run()
|
||||
if installed_pkg:
|
||||
installed_pkg = installed_pkg[0]
|
||||
evr_cmp = self._compare_evr(
|
||||
installed_pkg.epoch, installed_pkg.version, installed_pkg.release,
|
||||
candidate_pkg['epoch'], candidate_pkg['version'], candidate_pkg['release'],
|
||||
)
|
||||
if evr_cmp == 0:
|
||||
self.base.remove(pkg_spec)
|
||||
installed_pkg = dnf.subject.Subject(pkg_spec).get_best_query(
|
||||
sack=self.base.sack).installed().run()
|
||||
|
||||
for pkg in installed_pkg:
|
||||
self.base.remove(str(pkg))
|
||||
|
||||
# Like the dnf CLI we want to allow recursive removal of dependent
|
||||
# packages
|
||||
|
|
|
@ -772,3 +772,53 @@
|
|||
that:
|
||||
- wildcard_absent is successful
|
||||
- wildcard_absent is not changed
|
||||
|
||||
- name: Test removing with various package specs
|
||||
block:
|
||||
- name: Ensure sos is installed
|
||||
dnf:
|
||||
name: sos
|
||||
state: present
|
||||
|
||||
- name: Determine version of sos
|
||||
command: rpm -q --queryformat=%{version} sos
|
||||
register: sos_version_command
|
||||
|
||||
- name: Determine release of sos
|
||||
command: rpm -q --queryformat=%{release} sos
|
||||
register: sos_release_command
|
||||
|
||||
- name: Determine arch of sos
|
||||
command: rpm -q --queryformat=%{arch} sos
|
||||
register: sos_arch_command
|
||||
|
||||
- set_fact:
|
||||
sos_version: "{{ sos_version_command.stdout | trim }}"
|
||||
sos_release: "{{ sos_release_command.stdout | trim }}"
|
||||
sos_arch: "{{ sos_arch_command.stdout | trim }}"
|
||||
|
||||
# We are just trying to remove the package by specifying its spec in a
|
||||
# bunch of different ways. Each "item" here is a test (a name passed, to make
|
||||
# sure it matches, with how we call Hawkey in the dnf module).
|
||||
- include_tasks: test_sos_removal.yml
|
||||
with_items:
|
||||
- sos
|
||||
- sos-{{ sos_version }}
|
||||
- sos-{{ sos_version }}-{{ sos_release }}
|
||||
- sos-{{ sos_version }}-{{ sos_release }}.{{ sos_arch }}
|
||||
- sos-*-{{ sos_release }}
|
||||
- sos-{{ sos_version[0] }}*
|
||||
- sos-{{ sos_version[0] }}*-{{ sos_release }}
|
||||
- sos-{{ sos_version[0] }}*{{ sos_arch }}
|
||||
|
||||
- name: Ensure deleting a non-existing package fails correctly
|
||||
dnf:
|
||||
name: a-non-existent-package
|
||||
state: absent
|
||||
ignore_errors: true
|
||||
register: nonexisting
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- nonexisting is success
|
||||
- nonexisting.msg == 'Nothing to do'
|
||||
|
|
19
test/integration/targets/dnf/tasks/test_sos_removal.yml
Normal file
19
test/integration/targets/dnf/tasks/test_sos_removal.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
# These are safe to just check in check_mode, because in the module, the
|
||||
# logic to match packages will happen anyway. check_mode will just prevent
|
||||
# the transaction from actually running once the matches are found.
|
||||
- name: Remove {{ item }}
|
||||
dnf:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
check_mode: true
|
||||
register: sos_rm
|
||||
|
||||
- debug:
|
||||
var: sos_rm
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- sos_rm is successful
|
||||
- sos_rm is changed
|
||||
- "'Removed: sos-{{ sos_version }}-{{ sos_release }}' in sos_rm.results[0]"
|
||||
- sos_rm.results|length == 1
|
Loading…
Reference in a new issue