Fix DNF idempotency. (#66209)
This commit is contained in:
parent
6b21f56b97
commit
a7e4479d01
3 changed files with 48 additions and 32 deletions
2
changelogs/fragments/64963-dnf_idempotence.yml
Normal file
2
changelogs/fragments/64963-dnf_idempotence.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
bugfixes:
|
||||
- "dnf - Fix idempotence of `state: installed` (https://github.com/ansible/ansible/issues/64963)"
|
|
@ -724,38 +724,30 @@ class DnfModule(YumDnf):
|
|||
is_newer_version_installed = self._is_newer_version_installed(pkg_spec)
|
||||
is_installed = self._is_installed(pkg_spec)
|
||||
try:
|
||||
if self.allow_downgrade:
|
||||
# dnf only does allow_downgrade, we have to handle this ourselves
|
||||
# because it allows a possibility for non-idempotent transactions
|
||||
# on a system's package set (pending the yum repo has many old
|
||||
# NVRs indexed)
|
||||
if upgrade:
|
||||
if is_installed:
|
||||
self.base.upgrade(pkg_spec)
|
||||
if is_newer_version_installed:
|
||||
if self.allow_downgrade:
|
||||
# dnf only does allow_downgrade, we have to handle this ourselves
|
||||
# because it allows a possibility for non-idempotent transactions
|
||||
# on a system's package set (pending the yum repo has many old
|
||||
# NVRs indexed)
|
||||
if upgrade:
|
||||
if is_installed:
|
||||
self.base.upgrade(pkg_spec)
|
||||
else:
|
||||
self.base.install(pkg_spec)
|
||||
else:
|
||||
self.base.install(pkg_spec)
|
||||
else:
|
||||
self.base.install(pkg_spec)
|
||||
elif not self.allow_downgrade and is_newer_version_installed:
|
||||
return {'failed': False, 'msg': '', 'failure': '', 'rc': 0}
|
||||
elif not is_newer_version_installed:
|
||||
else: # Nothing to do, report back
|
||||
pass
|
||||
elif is_installed: # An potentially older (or same) version is installed
|
||||
if upgrade:
|
||||
if is_installed:
|
||||
self.base.upgrade(pkg_spec)
|
||||
else:
|
||||
self.base.install(pkg_spec)
|
||||
else:
|
||||
self.base.install(pkg_spec)
|
||||
else:
|
||||
if upgrade:
|
||||
if is_installed:
|
||||
self.base.upgrade(pkg_spec)
|
||||
else:
|
||||
self.base.install(pkg_spec)
|
||||
else:
|
||||
self.base.install(pkg_spec)
|
||||
self.base.upgrade(pkg_spec)
|
||||
else: # Nothing to do, report back
|
||||
pass
|
||||
else: # The package is not installed, simply install it
|
||||
self.base.install(pkg_spec)
|
||||
|
||||
return {'failed': False, 'msg': 'Installed: {0}'.format(pkg_spec), 'failure': '', 'rc': 0}
|
||||
return {'failed': False, 'msg': '', 'failure': '', 'rc': 0}
|
||||
|
||||
except dnf.exceptions.MarkingError as e:
|
||||
return {
|
||||
|
@ -1010,10 +1002,12 @@ class DnfModule(YumDnf):
|
|||
for pkg_spec in pkg_specs:
|
||||
install_result = self._mark_package_install(pkg_spec)
|
||||
if install_result['failed']:
|
||||
failure_response['msg'] += install_result['msg']
|
||||
if install_result['msg']:
|
||||
failure_response['msg'] += install_result['msg']
|
||||
failure_response['failures'].append(self._sanitize_dnf_error_msg_install(pkg_spec, install_result['failure']))
|
||||
else:
|
||||
response['results'].append(install_result['msg'])
|
||||
if install_result['msg']:
|
||||
response['results'].append(install_result['msg'])
|
||||
|
||||
elif self.state == 'latest':
|
||||
# "latest" is same as "installed" for filenames.
|
||||
|
@ -1070,10 +1064,12 @@ class DnfModule(YumDnf):
|
|||
self.base.conf.best = True
|
||||
install_result = self._mark_package_install(pkg_spec, upgrade=True)
|
||||
if install_result['failed']:
|
||||
failure_response['msg'] += install_result['msg']
|
||||
if install_result['msg']:
|
||||
failure_response['msg'] += install_result['msg']
|
||||
failure_response['failures'].append(self._sanitize_dnf_error_msg_install(pkg_spec, install_result['failure']))
|
||||
else:
|
||||
response['results'].append(install_result['msg'])
|
||||
if install_result['msg']:
|
||||
response['results'].append(install_result['msg'])
|
||||
|
||||
else:
|
||||
# state == absent
|
||||
|
|
|
@ -41,6 +41,24 @@
|
|||
that:
|
||||
- "'msg' in dnf_result"
|
||||
# ============================================================================
|
||||
- name: Install dinginessentail again (noop, module is idempotent)
|
||||
dnf:
|
||||
name: dinginessentail
|
||||
state: present
|
||||
register: dnf_result
|
||||
|
||||
- name: Check dinginessentail with rpm
|
||||
shell: rpm -q dinginessentail
|
||||
register: rpm_result
|
||||
|
||||
- name: Verify installation
|
||||
assert:
|
||||
that:
|
||||
# No upgrade happened to 1.1.1
|
||||
- "not dnf_result.changed"
|
||||
# Old version still installed
|
||||
- "rpm_result.stdout.startswith('dinginessentail-1.0-1')"
|
||||
# ============================================================================
|
||||
- name: Install dinginessentail-1:1.0-2
|
||||
dnf:
|
||||
name: "dinginessentail-1:1.0-2.{{ ansible_architecture }}"
|
||||
|
|
Loading…
Add table
Reference in a new issue