From de5fbe457fb4a9f3dd0016b207395c416ef0997b Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 14 Jun 2022 16:30:42 +0200 Subject: [PATCH] Fix alternatives module (#4836) (#4840) * Only pass subcommands when they are specified as module arguments. * When 'subcommands' is specified, 'link' must be given for every subcommand. * Extend subcommand tests. (cherry picked from commit 84d8ca9234bee2e3926fbc64f6558d8704085fb5) Co-authored-by: Felix Fontein --- changelogs/fragments/4836-alternatives.yml | 3 + plugins/modules/system/alternatives.py | 5 +- .../targets/alternatives/tasks/main.yml | 2 + .../alternatives/tasks/subcommands.yml | 141 +++++++++++++++++- .../targets/alternatives/vars/Debian.yml | 1 + .../targets/alternatives/vars/Suse-42.3.yml | 1 + .../targets/alternatives/vars/default.yml | 1 + 7 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/4836-alternatives.yml diff --git a/changelogs/fragments/4836-alternatives.yml b/changelogs/fragments/4836-alternatives.yml new file mode 100644 index 0000000000..d627ddf1ad --- /dev/null +++ b/changelogs/fragments/4836-alternatives.yml @@ -0,0 +1,3 @@ +bugfixes: + - "alternatives - only pass subcommands when they are specified as module arguments (https://github.com/ansible-collections/community.general/issues/4803, https://github.com/ansible-collections/community.general/issues/4804, https://github.com/ansible-collections/community.general/pull/4836)." + - "alternatives - when ``subcommands`` is specified, ``link`` must be given for every subcommand. This was already mentioned in the documentation, but not enforced by the code (https://github.com/ansible-collections/community.general/pull/4836)." diff --git a/plugins/modules/system/alternatives.py b/plugins/modules/system/alternatives.py index 56ae57fe8b..01867d4cb0 100644 --- a/plugins/modules/system/alternatives.py +++ b/plugins/modules/system/alternatives.py @@ -77,6 +77,7 @@ options: description: - The path to the symbolic link that should point to the real subcommand executable. type: path + required: true version_added: 5.1.0 requirements: [ update-alternatives ] ''' @@ -204,7 +205,7 @@ class AlternativesModule(object): cmd = [self.UPDATE_ALTERNATIVES, '--install', self.link, self.name, self.path, str(self.priority)] - if self.subcommands is not None: + if self.module.params['subcommands'] is not None: subcommands = [['--slave', subcmd['link'], subcmd['name'], subcmd['path']] for subcmd in self.subcommands] cmd += [item for sublist in subcommands for item in sublist] @@ -384,7 +385,7 @@ def main(): subcommands=dict(type='list', elements='dict', aliases=['slaves'], options=dict( name=dict(type='str', required=True), path=dict(type='path', required=True), - link=dict(type='path'), + link=dict(type='path', required=True), )), ), supports_check_mode=True, diff --git a/tests/integration/targets/alternatives/tasks/main.yml b/tests/integration/targets/alternatives/tasks/main.yml index 70853e8005..587022755b 100644 --- a/tests/integration/targets/alternatives/tasks/main.yml +++ b/tests/integration/targets/alternatives/tasks/main.yml @@ -66,6 +66,8 @@ state: absent with_items: - '{{ alternatives_dir }}/dummy' + - '{{ alternatives_dir }}/dummymain' + - '{{ alternatives_dir }}/dummysubcmd' - file: path: '/usr/bin/dummy{{ item }}' diff --git a/tests/integration/targets/alternatives/tasks/subcommands.yml b/tests/integration/targets/alternatives/tasks/subcommands.yml index ba4ecbbafe..d4ad086099 100644 --- a/tests/integration/targets/alternatives/tasks/subcommands.yml +++ b/tests/integration/targets/alternatives/tasks/subcommands.yml @@ -32,6 +32,15 @@ that: - cmd.stdout == "dummy2" +- name: Get dummymain alternatives output + command: + cmd: '{{ alternatives_command }} --display dummymain' + register: result + +- name: Print result + debug: + var: result.stdout_lines + - name: Subcommands are not removed if not specified alternatives: name: dummymain @@ -75,4 +84,134 @@ assert: that: - cmd.rc == 2 - - '"No such file" in cmd.msg' \ No newline at end of file + - '"No such file" in cmd.msg' + +- name: Get dummymain alternatives output + command: + cmd: '{{ alternatives_command }} --display dummymain' + register: result + +- name: Print result + debug: + var: result.stdout_lines + +- name: Install other alternative with subcommands + alternatives: + name: dummymain + path: '/usr/bin/dummy3' + link: '/usr/bin/dummymain' + subcommands: + - name: dummysubcmd + path: '/usr/bin/dummy4' + link: '/usr/bin/dummysubcmd' + register: alternative + +- name: Check expected command was executed + assert: + that: + - 'alternative is changed' + +- name: Execute the current dummymain command + command: dummymain + register: cmd + +- name: Ensure that the expected command was executed + assert: + that: + - cmd.stdout == "dummy3" + +- name: Execute the current dummysubcmd command + command: dummysubcmd + register: cmd + +- name: Ensure that the expected command was executed + assert: + that: + - cmd.stdout == "dummy4" + +- name: Get dummymain alternatives output + command: + cmd: '{{ alternatives_command }} --display dummymain' + register: result + +- name: Print result + debug: + var: result.stdout_lines + +- name: Switch to first alternative + alternatives: + name: dummymain + path: '/usr/bin/dummy1' + register: alternative + +- name: Check expected command was executed + assert: + that: + - 'alternative is changed' + +- name: Execute the current dummymain command + command: dummymain + register: cmd + +- name: Ensure that the expected command was executed + assert: + that: + - cmd.stdout == "dummy1" + +- name: Execute the current dummysubcmd command + command: dummysubcmd + register: cmd + ignore_errors: True + +- name: Ensure that the subcommand is gone + assert: + that: + - cmd.rc == 2 + - '"No such file" in cmd.msg' + +- name: Get dummymain alternatives output + command: + cmd: '{{ alternatives_command }} --display dummymain' + register: result + +- name: Print result + debug: + var: result.stdout_lines + +- name: Switch to second alternative + alternatives: + name: dummymain + path: '/usr/bin/dummy3' + register: alternative + +- name: Check expected command was executed + assert: + that: + - 'alternative is changed' + +- name: Execute the current dummymain command + command: dummymain + register: cmd + +- name: Ensure that the expected command was executed + assert: + that: + - cmd.stdout == "dummy3" + +- name: Execute the current dummysubcmd command + command: dummysubcmd + register: cmd + +- name: Ensure that the expected command was executed + assert: + that: + - cmd.stdout == "dummy4" + +- name: Get dummymain alternatives output + command: + cmd: '{{ alternatives_command }} --display dummymain' + register: result + +- name: Print result + debug: + var: result.stdout_lines diff --git a/tests/integration/targets/alternatives/vars/Debian.yml b/tests/integration/targets/alternatives/vars/Debian.yml index 1e83283e4d..d2cdd0cd0e 100644 --- a/tests/integration/targets/alternatives/vars/Debian.yml +++ b/tests/integration/targets/alternatives/vars/Debian.yml @@ -1,2 +1,3 @@ --- alternatives_dir: /var/lib/dpkg/alternatives/ +alternatives_command: update-alternatives diff --git a/tests/integration/targets/alternatives/vars/Suse-42.3.yml b/tests/integration/targets/alternatives/vars/Suse-42.3.yml index 37664ddb56..14958db39a 100644 --- a/tests/integration/targets/alternatives/vars/Suse-42.3.yml +++ b/tests/integration/targets/alternatives/vars/Suse-42.3.yml @@ -1,2 +1,3 @@ --- alternatives_dir: /var/lib/rpm/alternatives/ +alternatives_command: update-alternatives diff --git a/tests/integration/targets/alternatives/vars/default.yml b/tests/integration/targets/alternatives/vars/default.yml index d00123ded3..7aeb9bb562 100644 --- a/tests/integration/targets/alternatives/vars/default.yml +++ b/tests/integration/targets/alternatives/vars/default.yml @@ -1,2 +1,3 @@ --- alternatives_dir: /var/lib/alternatives/ +alternatives_command: update-alternatives