diff --git a/changelogs/fragments/yum-consistent-output-checkmode.yaml b/changelogs/fragments/yum-consistent-output-checkmode.yaml new file mode 100644 index 0000000000..7a8d936522 --- /dev/null +++ b/changelogs/fragments/yum-consistent-output-checkmode.yaml @@ -0,0 +1,2 @@ +minor_changes: + - yum - provide consistent return data structure when run in check mode and not in check mode diff --git a/lib/ansible/modules/packaging/os/yum.py b/lib/ansible/modules/packaging/os/yum.py index 31e8b3c63d..b74e7dd221 100644 --- a/lib/ansible/modules/packaging/os/yum.py +++ b/lib/ansible/modules/packaging/os/yum.py @@ -808,6 +808,8 @@ class YumModule(YumDnf): if self.module.check_mode: self.module.exit_json(changed=True, results=res['results'], changes=dict(installed=pkgs)) + else: + res['changes'] = dict(installed=pkgs) lang_env = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C') rc, out, err = self.module.run_command(cmd, environ_update=lang_env) @@ -1043,6 +1045,8 @@ class YumModule(YumDnf): if pkgs: if self.module.check_mode: self.module.exit_json(changed=True, results=res['results'], changes=dict(removed=pkgs)) + else: + res['changes'] = dict(removed=pkgs) # run an actual yum transaction if self.autoremove: @@ -1273,38 +1277,38 @@ class YumModule(YumDnf): self.module.fail_json(**res) # check_mode output - if self.module.check_mode: - to_update = [] - for w in will_update: - if w.startswith('@'): - to_update.append((w, None)) - elif w not in updates: - other_pkg = will_update_from_other_package[w] - to_update.append( - ( - w, - 'because of (at least) %s-%s.%s from %s' % ( - other_pkg, - updates[other_pkg]['version'], - updates[other_pkg]['dist'], - updates[other_pkg]['repo'] - ) + to_update = [] + for w in will_update: + if w.startswith('@'): + to_update.append((w, None)) + elif w not in updates: + other_pkg = will_update_from_other_package[w] + to_update.append( + ( + w, + 'because of (at least) %s-%s.%s from %s' % ( + other_pkg, + updates[other_pkg]['version'], + updates[other_pkg]['dist'], + updates[other_pkg]['repo'] ) ) - else: - to_update.append((w, '%s.%s from %s' % (updates[w]['version'], updates[w]['dist'], updates[w]['repo']))) - - if self.update_only: - res['changes'] = dict(installed=[], updated=to_update) + ) else: - res['changes'] = dict(installed=pkgs['install'], updated=to_update) + to_update.append((w, '%s.%s from %s' % (updates[w]['version'], updates[w]['dist'], updates[w]['repo']))) + if self.update_only: + res['changes'] = dict(installed=[], updated=to_update) + else: + res['changes'] = dict(installed=pkgs['install'], updated=to_update) + + if obsoletes: + res['obsoletes'] = obsoletes + + # return results before we actually execute stuff + if self.module.check_mode: if will_update or pkgs['install']: res['changed'] = True - - if obsoletes: - res['obsoletes'] = obsoletes - return res # run commands @@ -1340,9 +1344,6 @@ class YumModule(YumDnf): if rc: res['failed'] = True - if obsoletes: - res['obsoletes'] = obsoletes - return res def ensure(self, repoq): diff --git a/test/integration/targets/yum/tasks/check_mode_consistency.yml b/test/integration/targets/yum/tasks/check_mode_consistency.yml new file mode 100644 index 0000000000..e2a99d95bd --- /dev/null +++ b/test/integration/targets/yum/tasks/check_mode_consistency.yml @@ -0,0 +1,61 @@ +- name: install htop in check mode to verify changes dict returned + yum: + name: htop + state: present + check_mode: yes + register: yum_changes_check_mode_result + +- name: install verify changes dict returned in check mode + assert: + that: + - "yum_changes_check_mode_result is success" + - "yum_changes_check_mode_result is changed" + - "'changes' in yum_changes_check_mode_result" + - "'installed' in yum_changes_check_mode_result['changes']" + - "'htop' in yum_changes_check_mode_result['changes']['installed']" + +- name: install htop to verify changes dict returned + yum: + name: htop + state: present + register: yum_changes_result + +- name: install verify changes dict returned + assert: + that: + - "yum_changes_result is success" + - "yum_changes_result is changed" + - "'changes' in yum_changes_result" + - "'installed' in yum_changes_result['changes']" + - "'htop' in yum_changes_result['changes']['installed']" + +- name: remove htop in check mode to verify changes dict returned + yum: + name: htop + state: absent + check_mode: yes + register: yum_changes_check_mode_result + +- name: remove verify changes dict returned in check mode + assert: + that: + - "yum_changes_check_mode_result is success" + - "yum_changes_check_mode_result is changed" + - "'changes' in yum_changes_check_mode_result" + - "'removed' in yum_changes_check_mode_result['changes']" + - "'htop' in yum_changes_check_mode_result['changes']['removed']" + +- name: remove htop to verify changes dict returned + yum: + name: htop + state: absent + register: yum_changes_result + +- name: remove verify changes dict returned + assert: + that: + - "yum_changes_result is success" + - "yum_changes_result is changed" + - "'changes' in yum_changes_result" + - "'removed' in yum_changes_result['changes']" + - "'htop' in yum_changes_result['changes']['removed']" diff --git a/test/integration/targets/yum/tasks/main.yml b/test/integration/targets/yum/tasks/main.yml index 6733857fe8..4f75d9a5c7 100644 --- a/test/integration/targets/yum/tasks/main.yml +++ b/test/integration/targets/yum/tasks/main.yml @@ -71,3 +71,7 @@ - (ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] and ansible_distribution_major_version|int > 6) - include: 'proxy.yml' + +- include: 'check_mode_consistency.yml' + when: + - (ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] and ansible_distribution_major_version|int == 7)