diff --git a/changelogs/fragments/command_skip_stdout.yml b/changelogs/fragments/command_skip_stdout.yml new file mode 100644 index 00000000000..f048bccf5cc --- /dev/null +++ b/changelogs/fragments/command_skip_stdout.yml @@ -0,0 +1,3 @@ +--- +deprecated_features: + - command - deprecate unnecessary stdout when creates or removes is used (https://github.com/ansible/ansible/issues/84107). diff --git a/lib/ansible/modules/command.py b/lib/ansible/modules/command.py index 82d35fda668..b305bceec06 100644 --- a/lib/ansible/modules/command.py +++ b/lib/ansible/modules/command.py @@ -228,6 +228,11 @@ stderr_lines: returned: always type: list sample: [u'ls cannot access foo: No such file or directory', u'ls …'] +skip_reason: + description: The reason why the task was skipped. + returned: when task is skipped + type: str + sample: 'skipped, since /tmp/file exists' """ import datetime @@ -235,11 +240,21 @@ import glob import os import shlex +from ansible.module_utils._internal import _deprecator +from ansible.module_utils._internal._datatag import _tags from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.common.text.converters import to_native, to_bytes, to_text from ansible.module_utils.common.collections import is_iterable +_DEPRECATE_SKIPPED_STDOUT = _tags.Deprecated( + msg='`stdout` is deprecated when creates/removes is used', + version='2.24', + deprecator=_deprecator.ANSIBLE_CORE_DEPRECATOR, + help_text='Use `skip_reason` instead.', +) + + def main(): # the command module is the one ansible module that does not take key=value args @@ -313,15 +328,16 @@ def main(): if creates: if glob.glob(creates): r['msg'] = "%s not run command since '%s' exists" % (shoulda, creates) - r['stdout'] = "skipped, since %s exists" % creates # TODO: deprecate - + r['stdout'] = _DEPRECATE_SKIPPED_STDOUT.tag("skipped, since %s exists" % creates) + r['skip_reason'] = "skipped, since %s exists" % creates r['rc'] = 0 # special skips for idempotence if file does not exist (assumes command removes) if not r['msg'] and removes: if not glob.glob(removes): r['msg'] = "%s not run command since '%s' does not exist" % (shoulda, removes) - r['stdout'] = "skipped, since %s does not exist" % removes # TODO: deprecate + r['stdout'] = _DEPRECATE_SKIPPED_STDOUT.tag("skipped, since %s does not exist" % removes) + r['skip_reason'] = "skipped, since %s does not exist" % removes r['rc'] = 0 if r['msg']: @@ -343,6 +359,7 @@ def main(): if creates is None and removes is None: r['skipped'] = True # skipped=True and changed=True are mutually exclusive + r['skip_reason'] = r['msg'] r['changed'] = False # convert to text for jsonization and usability diff --git a/test/integration/targets/command_shell/tasks/main.yml b/test/integration/targets/command_shell/tasks/main.yml index b1d7f78d8d9..420bc4d3b0e 100644 --- a/test/integration/targets/command_shell/tasks/main.yml +++ b/test/integration/targets/command_shell/tasks/main.yml @@ -204,6 +204,27 @@ that: - command_result3 is not changed +- name: verify that skip.txt is absent + file: + path: "{{ remote_tmp_dir_test }}/skip.txt" + state: absent + +- name: Create a file which allow to skip the command execution + file: + state: touch + path: "{{ remote_tmp_dir_test }}/skip.txt" + +- name: Skip running command as the file already exists + command: + cmd: echo "Hello" + creates: "{{ remote_tmp_dir_test }}/skip.txt" + register: command_skip_reason + +- name: Check if we present skip_reason in output + assert: + that: + - command_skip_reason.skip_reason == "skipped, since " ~ remote_tmp_dir_test ~ "/skip.txt exists" + # removes - name: remove afile.txt with remote_afile.sh via command (check mode) @@ -255,6 +276,23 @@ that: - command_result4.changed != True +- name: verify that skip.txt is absent + file: + path: "{{ remote_tmp_dir_test }}/skip.txt" + state: absent + +- name: Skip running command as the file does not exist + command: + cmd: echo "Hello" + removes: "{{ remote_tmp_dir_test }}/skip.txt" + register: command_skip_reason + +- name: Check if we present skip_reason in output + assert: + that: + - command_skip_reason.skip_reason == "skipped, since " ~ remote_tmp_dir_test ~ "/skip.txt does not exist" + + - name: pass stdin to cat via command command: cat args: