add check_mode option for tasks (#16056)

* add check_mode option for tasks

includes example testcases for the template module

* extend check_mode option

* replace always_run, see also proposal rename_always_run
* rename always_run where used and add deprecation warning
* add some documentation

* have check_mode overwrite always_run

* use unique template name to prevent conflicts

test_check_mode was right before, but failed due to using the same filename as other roles

* still mention always_run in the docs

* set deprecation of always_run to version 2.4

* fix rst style

* expand documentation on per-task check mode
This commit is contained in:
Robin Roth 2016-07-23 02:40:14 +02:00 committed by Brian Coca
parent 243af8f727
commit 2b28beb1d7
8 changed files with 107 additions and 28 deletions

View file

@ -20,31 +20,50 @@ Example::
.. _forcing_to_run_in_check_mode:
Running a task in check mode
````````````````````````````
Enabling or disabling check mode for tasks
``````````````````````````````````````````
.. versionadded:: 1.3
.. versionadded:: 2.2
Sometimes you may want to have a task to be executed even in check
mode. To achieve this, use the `always_run` clause on the task. Its
value is a Jinja2 expression, just like the `when` clause. In simple
cases a boolean YAML value would be sufficient as a value.
Sometimes you may want to modify the check mode behavior of individual tasks. This is done via the ``check_mode`` option, which can
be added to tasks.
There are two options:
1. Force a task to **run in check mode**, even when the playbook is called **without** ``--check``. This is called ``check_mode: yes``.
2. Force a task to **run in normal mode** and make changes to the system, even when the playbook is called **with** ``--check``. This is called ``check_mode: no``.
.. note:: Prior to version 2.2 only the the equivalent of ``check_mode: no`` existed. The notation for that was ``always_run: yes``.
Instead of ``yes``/``no`` you can use a Jinja2 expression, just like the ``when`` clause.
Example::
tasks:
- name: this task is run even in check mode
- name: this task will make changes to the system even in check mode
command: /something/to/run --even-in-check-mode
always_run: yes
check_mode: no
As a reminder, a task with a `when` clause evaluated to false, will
still be skipped even if it has a `always_run` clause evaluated to
true.
- name: this task will always run under checkmode and not change the system
lineinfile: line="important config" dest=/path/to/myconfig.conf state=present
check_mode: yes
Also if you want to skip, or ignore errors on some tasks in check mode
you can use a boolean magic variable `ansible_check_mode` (added in version 2.1)
which will be set to `True` during check mode.
Running single tasks with ``check_mode: yes`` can be useful to write tests for
ansible modules, either to test the module itself or to the the conditions under
which a module would make changes.
With ``register`` (see :doc:`playbooks_conditionals`) you can check the
potential changes.
Information about check mode in variables
`````````````````````````````````````````
.. versionadded:: 2.1
If you want to skip, or ignore errors on some tasks in check mode
you can use a boolean magic variable ``ansible_check_mode``
which will be set to ``True`` during check mode.
Example::

View file

@ -42,7 +42,7 @@ existing system, using the `--check` flag to the `ansible` command will report i
bring the system into a desired state.
This can let you know up front if there is any need to deploy onto the given system. Ordinarily scripts and commands don't run in check mode, so if you
want certain steps to always execute in check mode, such as calls to the script module, add the 'always_run' flag::
want certain steps to always execute in check mode, such as calls to the script module, disable check mode for those tasks::
roles:
@ -50,7 +50,7 @@ want certain steps to always execute in check mode, such as calls to the script
tasks:
- script: verify.sh
always_run: True
check_mode: no
Modules That Are Useful for Testing
```````````````````````````````````

View file

@ -63,6 +63,7 @@ class Base:
_always_run = FieldAttribute(isa='bool')
_run_once = FieldAttribute(isa='bool')
_ignore_errors = FieldAttribute(isa='bool')
_check_mode = FieldAttribute(isa='bool')
# param names which have been deprecated/removed
DEPRECATED_ATTRIBUTES = [

View file

@ -440,10 +440,15 @@ class PlayContext(Base):
# set become defaults if not previouslly set
task.set_become_defaults(new_info.become, new_info.become_method, new_info.become_user)
# have always_run override check mode
if task.always_run:
display.deprecated("always_run is deprecated. Use check_mode = no instead.", version="2.4", removed=False)
new_info.check_mode = False
# check_mode replaces always_run, overwrite always_run if both are given
if task.check_mode is not None:
new_info.check_mode = task.check_mode
return new_info
def make_become_cmd(self, cmd, executable=None):

View file

@ -18,7 +18,7 @@
- name: run a command while in check mode
shell: echo "running"
always_run: yes
check_mode: no
register: result
- name: assert that the command was run

View file

@ -17,23 +17,30 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: fill in a basic template in check mode
template: src=foo.j2 dest={{output_dir}}/foo.templated mode=0644
template: src=foo.j2 dest={{output_dir}}/checkmode_foo.templated mode=0644
register: template_result
- name: check whether file exists
stat: path={{output_dir}}/checkmode_foo.templated
register: foo
- name: verify that the file was marked as changed in check mode
assert:
that:
- "template_result.changed == true"
- "template_result|changed"
- "not foo.stat.exists"
- name: Actually create the file
template: src=foo.j2 dest={{output_dir}}/foo.templated2 mode=0644
always_run: True
- name: Actually create the file, disable check mode
template: src=foo.j2 dest={{output_dir}}/checkmode_foo.templated2 mode=0644
check_mode: no
register: checkmode_disabled
- name: fill in a basic template in check mode
template: src=foo.j2 dest={{output_dir}}/foo.templated2 mode=0644
- name: fill in template with new content
template: src=foo.j2 dest={{output_dir}}/checkmode_foo.templated2 mode=0644
register: template_result2
- name: verify that the file was marked as not changed in check mode
- name: verify that the file was not changed
assert:
that:
- "template_result2.changed == false"
- "checkmode_disabled|changed"
- "not template_result2|changed"

View file

@ -179,3 +179,49 @@
that:
- "template_result.changed == False"
# check_mode
- name: fill in a basic template in check mode
template: src=short.j2 dest={{output_dir}}/short.templated
register: template_result
check_mode: True
- name: check file exists
stat: path={{output_dir}}/short.templated
register: templated
- name: verify that the file was marked as changed in check mode but was not created
assert:
that:
- "not templated.stat.exists"
- "template_result|changed"
- name: fill in a basic template
template: src=short.j2 dest={{output_dir}}/short.templated
- name: fill in a basic template in check mode
template: src=short.j2 dest={{output_dir}}/short.templated
register: template_result
check_mode: True
- name: verify that the file was marked as not changes in check mode
assert:
that:
- "not template_result|changed"
- "'templated_var_loaded' in lookup('file', '{{output_dir | expanduser}}/short.templated')"
- name: change var for the template
set_fact:
templated_var: "changed"
- name: fill in a basic template with changed var in check mode
template: src=short.j2 dest={{output_dir}}/short.templated
register: template_result
check_mode: True
- name: verify that the file was marked as changed in check mode but the content was not changed
assert:
that:
- "'templated_var_loaded' in lookup('file', '{{output_dir | expanduser }}/short.templated')"
- "template_result|changed"

View file

@ -0,0 +1 @@
{{ templated_var }}