Fix DNF idempotency. (#66209)

pull/66568/head
Florian Apolloner 5 years ago committed by ansibot
parent 6b21f56b97
commit a7e4479d01

@ -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…
Cancel
Save