From 1fae3aecc7d8e3bbd022f4c2be2a447b2e38d940 Mon Sep 17 00:00:00 2001 From: mulkieran Date: Thu, 1 Dec 2016 17:32:55 -0500 Subject: [PATCH] Modify instances of the use of the word idempotence to be correct. (#18704) Idempotence has a very specific meaning and it is generally not used correctly in the manual. My attention was first drawn to this problem by the incorrect definition in the glossary, but on further reading of the docs I found that the problem occurred in a number of places. Signed-off-by: mulhern --- docsite/rst/dev_guide/developing_modules.rst | 11 ++++----- docsite/rst/developing_modules.rst | 11 ++++----- docsite/rst/glossary.rst | 25 ++++++++++++-------- docsite/rst/guide_cloudstack.rst | 2 +- docsite/rst/intro_adhoc.rst | 10 ++++---- docsite/rst/modules_intro.rst | 6 +++-- docsite/rst/playbooks_intro.rst | 16 +++++++------ 7 files changed, 45 insertions(+), 36 deletions(-) diff --git a/docsite/rst/dev_guide/developing_modules.rst b/docsite/rst/dev_guide/developing_modules.rst index 7e03e88e630..7fa928e287c 100644 --- a/docsite/rst/dev_guide/developing_modules.rst +++ b/docsite/rst/dev_guide/developing_modules.rst @@ -149,12 +149,11 @@ a lot shorter than this:: if key == "time": # now we'll affect the change. Many modules - # will strive to be 'idempotent', meaning they - # will only make changes when the desired state - # expressed to the module does not match - # the current state. Look at 'service' - # or 'yum' in the main git tree for an example - # of how that might look. + # will strive to be idempotent, generally + # by not performing any actions if the current + # state is the same as the desired state. + # See 'service' or 'yum' in the main git tree + # for an illustrative example. rc = os.system("date -s \"%s\"" % value) diff --git a/docsite/rst/developing_modules.rst b/docsite/rst/developing_modules.rst index 22db87fa384..9325c215d6d 100644 --- a/docsite/rst/developing_modules.rst +++ b/docsite/rst/developing_modules.rst @@ -149,12 +149,11 @@ a lot shorter than this:: if key == "time": # now we'll affect the change. Many modules - # will strive to be 'idempotent', meaning they - # will only make changes when the desired state - # expressed to the module does not match - # the current state. Look at 'service' - # or 'yum' in the main git tree for an example - # of how that might look. + # will strive to be idempotent, generally + # by not performing any actions if the current + # state is the same as the desired state. + # See 'service' or 'yum' in the main git tree + # for an illustrative example. rc = os.system("date -s \"%s\"" % value) diff --git a/docsite/rst/glossary.rst b/docsite/rst/glossary.rst index c66180559bd..199abc9de06 100644 --- a/docsite/rst/glossary.rst +++ b/docsite/rst/glossary.rst @@ -67,6 +67,18 @@ when a term comes up on the mailing list. Ansible's conditionals are powered by the 'when' statement, which are discussed in the :doc:`playbook documentation `. + Declarative + An approach to achieving a task that uses a description of the + final state rather than a description of the sequence of steps + necessary to achieve that state. For a real world example, a + declarative specification of a task would be: "put me in California". + Depending on your current location, the sequence of steps to get you to + California may vary, and if you are already in California, nothing + at all needs to be done. Ansible's Resources are declarative; it + figures out the steps needed to achieve the final state. It also lets + you know whether or not any steps needed to be taken to get to the + final state. + Diff Mode A ``--diff`` flag can be passed to Ansible to show what changed on modules that support it. You can combine it with ``--check`` to get a @@ -174,16 +186,9 @@ when a term comes up on the mailing list. data structures that can't be represented in the inventory file. Idempotency - The concept that change commands should only be applied when they need - to be applied, and that it is better to describe the desired state of - a system than the process of how to get to that state. As an analogy, - the path from North Carolina in the United States to California - involves driving a very long way West but if I were instead in - Anchorage, Alaska, driving a long way west is no longer the right way - to get to California. Ansible's Resources like you to say "put me in - California" and then decide how to get there. If you were already in - California, nothing needs to happen, and it will let you know it - didn't need to change anything. + An operation is idempotent if the result of performing it once is + exactly the same as the result of performing it repeatedly without + any intervening actions. Includes The idea that :term:`playbook ` files (which are nothing diff --git a/docsite/rst/guide_cloudstack.rst b/docsite/rst/guide_cloudstack.rst index ac293f8ee16..a3b37ae9876 100644 --- a/docsite/rst/guide_cloudstack.rst +++ b/docsite/rst/guide_cloudstack.rst @@ -7,7 +7,7 @@ Introduction ```````````` The purpose of this section is to explain how to put Ansible modules together to use Ansible in a CloudStack context. You will find more usage examples in the details section of each module. -Ansible contains a number of extra modules for interacting with CloudStack based clouds. All modules support check mode and are designed to use idempotence and have been created, tested and are maintained by the community. +Ansible contains a number of extra modules for interacting with CloudStack based clouds. All modules support check mode, are designed to be idempotent, have been created and tested, and are maintained by the community. .. note:: Some of the modules will require domain admin or root admin privileges. diff --git a/docsite/rst/intro_adhoc.rst b/docsite/rst/intro_adhoc.rst index 92d1c7a6e91..4d7a31de75a 100644 --- a/docsite/rst/intro_adhoc.rst +++ b/docsite/rst/intro_adhoc.rst @@ -108,10 +108,12 @@ the local shell doesn't eat a variable before it gets passed to Ansible. For example, using double rather than single quotes in the above example would evaluate the variable on the box you were on. -So far we've been demoing simple command execution, but most Ansible modules usually do not work like -simple scripts. They make the remote system look like a state, and run the commands necessary to -get it there. This is commonly referred to as 'idempotence', and is a core design goal of Ansible. -However, we also recognize that running arbitrary commands is equally important, so Ansible easily supports both. +So far we've been demoing simple command execution, but most Ansible modules are not simple imperative scripts. Instead, they use a declarative model, +calculating and executing the actions required to reach a specified final state. +Furthermore, they achieve a form of idempotence by checking the current state +before they begin, and if the current state matches the specified final state, +doing nothing. +However, we also recognize that running arbitrary commands can be valuable, so Ansible easily supports both. .. _file_transfer: diff --git a/docsite/rst/modules_intro.rst b/docsite/rst/modules_intro.rst index bb17bd6a19d..8b9027b5223 100644 --- a/docsite/rst/modules_intro.rst +++ b/docsite/rst/modules_intro.rst @@ -35,8 +35,10 @@ Another way to pass arguments to a module is using yaml syntax also called 'comp All modules technically return JSON format data, though if you are using the command line or playbooks, you don't really need to know much about that. If you're writing your own module, you care, and this means you do not have to write modules in any particular language -- you get to choose. -Modules strive to be `idempotent`, meaning they will seek to avoid changes to the system unless a change needs to be made. When using Ansible -playbooks, these modules can trigger 'change events' in the form of notifying 'handlers' to run additional tasks. +Modules should be idempotent, and should avoid making any changes if +they detect that the current state matches the desired final state. When using +Ansible playbooks, these modules can trigger 'change events' in the form of +notifying 'handlers' to run additional tasks. Documentation for each module can be accessed from the command line with the ansible-doc tool:: diff --git a/docsite/rst/playbooks_intro.rst b/docsite/rst/playbooks_intro.rst index 6e05080df6a..957b7f1ccd0 100644 --- a/docsite/rst/playbooks_intro.rst +++ b/docsite/rst/playbooks_intro.rst @@ -246,11 +246,13 @@ taken out of the rotation for the entire playbook. If things fail, simply corre The goal of each task is to execute a module, with very specific arguments. Variables, as mentioned above, can be used in arguments to modules. -Modules are 'idempotent', meaning if you run them -again, they will make only the changes they must in order to bring the -system to the desired state. This makes it very safe to rerun -the same playbook multiple times. They won't change things -unless they have to change things. +Modules should be idempotent, that is, running a module multiple times +in a sequence should have the same effect as running it just once. One +way to achieve idempotency is to have a module check whether its desired +final state has already been achieved, and if that state has been achieved, +to exit without performing any actions. If all the modules a playbook uses +are idempotent, then the playbook itself is likely to be idempotent, so +re-running the playbook should be safe. The **command** and **shell** modules will typically rerun the same command again, which is totally ok if the command is something like @@ -259,7 +261,7 @@ be used to make these modules also idempotent. Every task should have a ``name``, which is included in the output from running the playbook. This is human readable output, and so it is -useful to have provide good descriptions of each task step. If the name +useful to provide good descriptions of each task step. If the name is not provided though, the string fed to 'action' will be used for output. @@ -340,7 +342,7 @@ The old form continues to work in newer versions without any plan of deprecation Handlers: Running Operations On Change `````````````````````````````````````` -As we've mentioned, modules are written to be 'idempotent' and can relay when +As we've mentioned, modules should be idempotent and can relay when they have made a change on the remote system. Playbooks recognize this and have a basic event system that can be used to respond to change.