Merge pull request #13268 from basepi/requisitedocs

More requisite doc cleanup
This commit is contained in:
Thomas S Hatch 2014-06-05 16:45:50 -06:00
commit 0029693d86
2 changed files with 33 additions and 227 deletions

View File

@ -144,151 +144,13 @@ more requisites. Both requisite types can also be separately declared:
In this example, the httpd service is only going to be started if the package,
user, group and file are executed successfully.
The Require Requisite
---------------------
The foundation of the requisite system is the ``require`` requisite. The
require requisite ensures that the required state(s) are executed before the
requiring state. So, if a state is declared that sets down a vimrc, then it
would be pertinent to make sure that the vimrc file would only be set down if
the vim package has been installed:
Requisite Documentation
-----------------------
.. code-block:: yaml
For detailed information on each of the individual requisites, :ref:`please
look here. <requisites>`
vim:
pkg:
- installed
file.managed:
- source: salt://vim/vimrc
- require:
- pkg: vim
In this case, the vimrc file will only be applied by Salt if and after the vim
package is installed.
The Watch Requisite
-------------------
The ``watch`` requisite is more advanced than the ``require`` requisite. The
watch requisite executes the same logic as require (therefore if something is
watched it does not need to also be required) with the addition of executing
logic if the required states have changed in some way.
The watch requisite checks to see if the watched states have returned any
changes. If the watched state returns changes, and the watched states execute
successfully, then the watching state will execute a function that reacts to
the changes in the watched states.
Perhaps an example can better explain the behavior:
.. code-block:: yaml
redis:
pkg:
- latest
file.managed:
- source: salt://redis/redis.conf
- name: /etc/redis.conf
- require:
- pkg: redis
service.running:
- enable: True
- watch:
- file: /etc/redis.conf
- pkg: redis
In this example, the redis service will only be started if the file
/etc/redis.conf is applied, and the file is only applied if the package is
installed. This is normal require behavior, but if the watched file changes,
or the watched package is installed or upgraded, then the redis service is
restarted.
.. note::
To reiterate: watch does not alter the original behavior of a function in
any way. The original behavior stays, but additional behavior (defined by
mod_watch as explored below) will be run if there are changes in the
watched state. This is why, for example, we have to have a ``cmd.wait``
state for watching purposes. If you examine the source code, you'll see
that ``cmd.wait`` is an empty function. However, you'll notice that
``mod_watch`` is actually just an alias of ``cmd.run``. So if there are
changes, we run the command, otherwise, we do nothing.
Watch and the mod_watch Function
--------------------------------
The watch requisite is based on the ``mod_watch`` function. Python state
modules can include a function called ``mod_watch`` which is then called
if the watch call is invoked. When ``mod_watch`` is called depends on the
execution of the watched state, which:
- If no changes then just run the watching state itself as usual.
``mod_watch`` is not called. This behavior is same as using a ``require``.
- If changes then run the watching state *AND* if that changes nothing then
react by calling ``mod_watch``.
When reacting, in the case of the service module the underlying service is
restarted. In the case of the cmd state the command is executed.
The ``mod_watch`` function for the service state looks like this:
.. code-block:: python
def mod_watch(name, sig=None, reload=False, full_restart=False):
'''
The service watcher, called to invoke the watch command.
name
The name of the init or rc script used to manage the service
sig
The string to search for when looking for the service process with ps
'''
if __salt__['service.status'](name, sig):
if 'service.reload' in __salt__ and reload:
restart_func = __salt__['service.reload']
elif 'service.full_restart' in __salt__ and full_restart:
restart_func = __salt__['service.full_restart']
else:
restart_func = __salt__['service.restart']
else:
restart_func = __salt__['service.start']
result = restart_func(name)
return {'name': name,
'changes': {name: result},
'result': result,
'comment': 'Service restarted' if result else \
'Failed to restart the service'
}
The watch requisite only works if the state that is watching has a
``mod_watch`` function written. If watch is set on a state that does not have
a ``mod_watch`` function (like pkg), then the listed states will behave only
as if they were under a ``require`` statement.
Also notice that a ``mod_watch`` may accept additional keyword arguments,
which, in the sls file, will be taken from the same set of arguments specified
for the state that includes the ``watch`` requisite. This means, for the
earlier ``service.running`` example above, the service can be set to
``reload`` instead of restart like this:
.. code-block:: yaml
redis:
# ... other state declarations omitted ...
service.running:
- enable: True
- reload: True
- watch:
- file: /etc/redis.conf
- pkg: redis
.. _ordering_order:
The Order Option
================

View File

@ -8,11 +8,11 @@ The Salt requisite system is used to create relationships between states. The
core idea being that, when one state is dependent somehow on another, that
inter-dependency can be easily defined.
Requisites come in two types: Direct requisites (such as ``require`` and ``watch``),
and requisite_ins (such as ``require_in`` and ``watch_in``). The relationships are
directional: a direct requisite requires something from another state, while
requisite_ins operate in the other direction. A requisite_in contains something that
is required by another state. The following example demonstrates a direct requisite:
Requisites come in two types: Direct requisites (such as ``require``),
and requisite_ins (such as ``require_in``). The relationships are
directional: a direct requisite requires something from another state.
However, a requisite_in inserts a requisite into the targeted state pointing to
the targeting state. The following example demonstrates a direct requisite:
.. code-block:: yaml
@ -43,7 +43,8 @@ something", requisite_ins say "Someone depends on me":
So here, with a requisite_in, the same thing is accomplished as in the first
example, but the other way around. The vim package is saying "/etc/vimrc depends
on me".
on me". This will result in a ``require`` being inserted into the
``/etc/vimrc`` state which targets the ``vim`` state.
In the end, a single dependency map is created and everything is executed in a
finite and predictable order.
@ -65,11 +66,12 @@ finite and predictable order.
Direct Requisite and Requisite_in types
=======================================
There are four direct requisite statements that can be used in Salt: ``require``,
``watch``, ``prereq``, and ``use``. Each direct requisite also has a corresponding
requisite_in: ``require_in``, ``watch_in``, ``prereq_in`` and ``use_in``. All of the
requisites define specific relationships and always work with the dependency
logic defined above.
There are six direct requisite statements that can be used in Salt:
``require``, ``watch``, ``prereq``, ``use``, ``onchanges``, and ``onfail``.
Each direct requisite also has a corresponding requisite_in: ``require_in``,
``watch_in``, ``prereq_in``, ``use_in``, ``onchanges_in``, and ``onfail_in``.
All of the requisites define specific relationships and always work with the
dependency logic defined above.
require
-------
@ -268,8 +270,8 @@ onchanges
.. versionadded:: Helium
The ``onchanges`` requisite makes a state only apply if the required states
generate changes. This can be a useful way to execute a post hook after
changing aspects of a system.
generate changes, and if the watched state's "result" is ``True``. This can be
a useful way to execute a post hook after changing aspects of a system.
use
---
@ -304,13 +306,22 @@ targeted state. This means also a chain of ``use`` requisites would not
inherit inherited options.
.. _requisites-require-in:
.. _requisites-watch-in:
require_in
----------
The _in versions of requisites
------------------------------
The ``require_in`` requisite is the literal reverse of ``require``. If
a state declaration needs to be required by another state declaration then
require_in can accommodate it. Therefore, these two sls files would be the
All of the requisites also have corresponding requisite_in versions, which do
the reverse of their normal counterparts. The examples below all use
``require_in`` as the example, but note that all of the ``_in`` requisites work
the same way: They result in a normal requisite in the targeted state, which
targets the state which has defines the requisite_in. Thus, a ``require_in``
causes the target state to ``require`` the targeting state. Similarly, a
``watch_in`` causes the target state to ``watch`` the targeting state. This
pattern continues for the rest of the requisites.
If a state declaration needs to be required by another state declaration then
``require_in`` can accommodate it. Therefore, these two sls files would be the
same in the end:
Using ``require``
@ -383,73 +394,6 @@ mod_python.sls
Now the httpd server will only start if php or mod_python are first verified to
be installed. Thus allowing for a requisite to be defined "after the fact".
.. _requisites-watch-in:
watch_in
--------
``watch_in`` functions the same way as ``require_in``, but applies
a ``watch`` statement rather than a ``require`` statement to the external state
declaration.
A good example of when to use ``watch_in`` versus ``watch`` is in regards to writing
an Apache state in conjunction with a git state for a Django application. On the most
basic level, using either the ``watch`` or the ``watch_in`` requisites, the resulting
behavior will be the same: Apache restarts each time the Django git state changes.
.. code-block:: yaml
apache:
pkg:
- installed
- name: httpd
service:
- watch:
- git: django_git
django_git:
git:
- latest
- name: git@github.com/example/mydjangoproject.git
However, by using ``watch_in``, the approach is improved. By writing ``watch_in`` in
the depending states (such as the Django state and any other states that require Apache
to restart), the dependent state (Apache state) is de-coupled from the depending states:
.. code-block:: yaml
apache:
pkg:
- installed
- name: httpd
django_git:
git:
- latest
- name: git@github.com/example/mydjangoproject.git
- watch_in:
- service: apache
prereq_in
---------
The ``prereq_in`` requisite_in follows the same assignment logic as the
``require_in`` requisite_in. The ``prereq_in`` call simply assigns
``prereq`` to the state referenced. The above example for ``prereq`` can
be modified to function in the same way using ``prereq_in``:
.. code-block:: yaml
graceful-down:
cmd.run:
- name: service apache graceful
site-code:
file.recurse:
- name: /opt/site_code
- source: salt://site/code
- prereq_in:
- cmd: graceful-down
Altering Statefulness
=====================