Merge pull request #36835 from jfindlay/beacon_doc

unify and expand beacon documentation
This commit is contained in:
C. R. Oldham 2016-10-07 09:59:34 -06:00 committed by GitHub
commit dc5d821be6
4 changed files with 176 additions and 84 deletions

View file

@ -73,6 +73,17 @@ Glossary
The collection of states to be applied to a system. *See also*:
:ref:`state layers <state-layers-highstate>`.
Idempotent
An action that ensures the system is in a well-known state regardless
of the system's state before the action is applied. A corollary to
this is that applying the action multiple times results in no changes
to the system. State module functions should be idempotent. Some
state module functions, such as :mod:`cmd.run <salt.states.cmd.run>`
are not idempotent by default but can be made idempotent with the
proper use of requisites such as :ref:```unless`` <unless-requisite>`
and :ref:```onlyif`` <onlyif-requisite>`. For more information, *see*
`wikipedia <https://en.wikipedia.org/wiki/Idempotent>`_.
Jinja
A templating language which allows variables and simple logic to be
dynamically inserted into static text files when they are rendered.
@ -90,7 +101,8 @@ Glossary
or stored externally.
Job ID
A unique identifier to represent a given :term:`job`.
A unique identifier to represent a given :term:`job`. This is often
shortened to JID.
Low State
The collection of processed states after requisites and order are
@ -111,7 +123,7 @@ Glossary
Mine
A facility to collect arbitrary data from minions and store that data
on the master. This data is then available to all other minions.
[Sometimes referred to as Salt Mine.] *See also*: :ref:`Salt Mine
(Sometimes referred to as Salt Mine.) *See also*: :ref:`Salt Mine
<salt-mine>`.
Minion

View file

@ -592,6 +592,8 @@ Reload
after a state finishes. ``reload_pillar`` and ``reload_grains`` can also be set.
See :ref:`Reloading Modules <reloading-modules>`.
.. _unless-requisite:
Unless
------
@ -640,6 +642,8 @@ For example:
In the above case, ``some_check`` will be run prior to _each_ name -- once for
``first_deploy_cmd`` and a second time for ``second_deploy_cmd``.
.. _onlyif-requisite:
Onlyif
------

View file

@ -7,8 +7,8 @@ Beacons
Beacons let you use the Salt event system to monitor non-Salt processes. The
beacon system allows the minion to hook into a variety of system processes and
continually monitor these processes. When monitored activity occurs in a system
process, an event is sent on the Salt event bus that can be used to trigger
a :ref:`reactor <reactor>`.
process, an event is sent on the Salt event bus that can be used to trigger a
:ref:`reactor <reactor>`.
Salt beacons can currently monitor and send Salt events for many system
activities, including:
@ -29,17 +29,18 @@ See :ref:`beacon modules <all-salt.beacons>` for a current list.
Configuring Beacons
===================
Salt beacons do not require any changes to the system process that
is being monitored, everything is configured using Salt.
Salt beacons do not require any changes to the system components that are being
monitored, everything is configured using Salt.
Beacons are typically enabled by placing a ``beacons:`` top level block in the
minion configuration file:
Beacons are typically enabled by placing a ``beacons:`` top level block in
``/etc/salt/minion`` or any file in ``/etc/salt/minion.d/`` such as
``/etc/salt/minion.d/beacons.conf``:
.. code-block:: yaml
beacons:
inotify:
/etc/httpd/conf.d: {}
/etc/important_file: {}
/opt: {}
The beacon system, like many others in Salt, can also be configured via the
@ -53,16 +54,17 @@ Beacon Monitoring Interval
--------------------------
Beacons monitor on a 1-second interval by default. To set a different interval,
provide an ``interval`` argument to a beacon. The following beacons run on
5- and 10-second intervals:
provide an ``interval`` argument to a beacon. The following beacons run on 5-
and 10-second intervals:
.. code-block:: yaml
beacons:
inotify:
/etc/httpd/conf.d: {}
/etc/important_file: {}
/opt: {}
interval: 5
disable_during_state_run: True
load:
1m:
- 0.0
@ -75,56 +77,75 @@ provide an ``interval`` argument to a beacon. The following beacons run on
- 1.0
interval: 10
.. _avoid-beacon-event-loops:
Avoiding Event Loops
--------------------
It is important to carefully consider the possibility of creating a loop
between a reactor and a beacon. For example, one might set up a beacon
which monitors whether a file is read which in turn fires a reactor to
run a state which in turn reads the file and re-fires the beacon.
between a reactor and a beacon. For example, one might set up a beacon which
monitors whether a file is read which in turn fires a reactor to run a state
which in turn reads the file and re-fires the beacon.
To avoid these types of scenarios, the ``disable_during_state_run``
argument may be set. If a state run is in progress, the beacon will
not be run on its regular interval until the minion detects that the
state run has completed, at which point the normal beacon interval
will resume.
To avoid these types of scenarios, the ``disable_during_state_run`` argument
may be set. If a state run is in progress, the beacon will not be run on its
regular interval until the minion detects that the state run has completed, at
which point the normal beacon interval will resume.
.. code-block:: yaml
beacons:
inotify:
/etc/passwd: {}
/etc/important_file: {}
disable_during_state_run: True
.. _beacon-example:
Beacon Example
==============
This example demonstrates configuring the :py:mod:`~salt.beacons.inotify`
beacon to monitor a file for changes, and then create a backup each time
a change is detected.
beacon to monitor a file for changes, and then restores the file to its
original contents if a change was made.
.. note::
The inotify beacon requires Pyinotify on the minion, install it using
``salt myminion pkg.install python-inotify``.
First, on the Salt minion, add the following beacon configuration to
``/etc/salt/minion``:
Create Watched File
-------------------
Create the file named ``/etc/important_file`` and add some simple content:
.. code-block:: yaml
beacons:
inotify:
home/user/importantfile:
mask:
- modify
important_config: True
Replace ``user`` in the previous example with the name of your user account,
and then save the configuration file and restart the minion service.
Add Beacon Configs to Minion
----------------------------
Next, create a file in your home directory named ``importantfile`` and add some
simple content. The beacon is now set up to monitor this file for
modifications.
On the Salt minion, add the following configuration to
``/etc/salt/minion.d/beacons.conf``:
.. code-block:: yaml
beacons:
inotify:
/etc/important_file:
mask:
- modify
disable_during_state_run: True
Save the configuration file and restart the minion service. The beacon is now
set up to notify salt upon modifications made to the file.
.. note::
The ``disable_during_state_run: True`` parameter :ref:`prevents
<avoid-beacon-event-loops>` the inotify beacon from generating reactor
events due to salt itself modifying the file.
.. _beacon-event-bus:
View Events on the Master
-------------------------
@ -135,22 +156,22 @@ On your Salt master, start the event runner using the following command:
salt-run state.event pretty=true
This runner displays events as they are received on the Salt event bus. To test
the beacon you set up in the previous section, make and save
a modification to the ``importantfile`` you created. You'll see an event
similar to the following on the event bus:
This runner displays events as they are received by the master on the Salt
event bus. To test the beacon you set up in the previous section, make and save
a modification to ``/etc/important_file``. You'll see an event similar to the
following on the event bus:
.. code-block:: json
salt/beacon/minion1/inotify/home/user/importantfile {
"_stamp": "2015-09-09T15:59:37.972753",
"data": {
"change": "IN_IGNORED",
"id": "minion1",
"path": "/home/user/importantfile"
},
"tag": "salt/beacon/minion1/inotify/home/user/importantfile"
}
salt/beacon/larry/inotify//etc/important_file {
"_stamp": "2015-09-09T15:59:37.972753",
"data": {
"change": "IN_IGNORED",
"id": "larry",
"path": "/etc/important_file"
},
"tag": "salt/beacon/larry/inotify//etc/important_file"
}
This indicates that the event is being captured and sent correctly. Now you can
@ -159,35 +180,74 @@ create a reactor to take action when this event occurs.
Create a Reactor
----------------
On your Salt master, create a file named ``srv/reactor/backup.sls``. If the
``reactor`` directory doesn't exist, create it. Add the following to ``backup.sls``:
This reactor reverts the file named ``/etc/important_file`` to the contents
provided by salt each time it is modified.
Reactor SLS
```````````
On your Salt master, create a file named ``/srv/reactor/revert.sls``.
.. note::
If the ``/srv/reactor`` directory doesn't exist, create it.
.. code-block:: bash
mkdir -p /srv/reactor
Add the following to ``/srv/reactor/revert.sls``:
.. code-block:: yaml
backup file:
cmd.file.copy:
- tgt: {{ data['data']['id'] }}
- arg:
- {{ data['data']['path'] }}
- {{ data['data']['path'] }}.bak
revert-file:
local.state.apply:
- tgt: {{ data['data']['id'] }}
- mods: maintain_important_file
Next, add the code to trigger the reactor to ``ect/salt/master``:
.. note::
In addition to :ref:`setting <avoid-beacon-event-loops>`
``disable_during_state_run: True`` for an inotify beacon whose reaction is
to modify the watched file, it is important to ensure the state applied is
also :term:`idempotent`.
.. note::
The expression ``{{ data['data']['id] }}`` :ref:`is correct
<beacons-and-reactors>` as it matches the event structure :ref:`shown above
<beacon-event-bus>`.
State SLS
`````````
Create the state sls file referenced by the reactor sls file. This state file
will be located at ``/srv/salt/maintain_important_file.sls``.
.. code-block:: yaml
reactor:
- salt/beacon/*/inotify/*/importantfile:
- /srv/reactor/backup.sls
important_file:
file.managed:
- name: /etc/important_file
- contents: |
important_config: True
Master Config
`````````````
This reactor creates a backup each time a file named ``importantfile`` is
modified on a minion that has the :py:mod:`~salt.beacons.inotify` beacon
configured as previously shown.
Configure the master to map the inotify beacon event to the ``revert`` reaction
in ``/etc/salt/master.d/reactor.conf``:
.. code-block:: yaml
reactor:
- salt/beacon/*/inotify//etc/important_file:
- /srv/reactor/revert.sls
.. note::
You can have only one top level ``reactor`` section, so if one already
exists, add this code to the existing section. See :ref:`Understanding
the Structure of Reactor Formulas <reactor-structure>` to learn more about
exists, add this code to the existing section. See :ref:`Understanding the
Structure of Reactor Formulas <reactor-structure>` to learn more about
reactor SLS syntax.
@ -196,7 +256,7 @@ Start the Salt Master in Debug Mode
To help with troubleshooting, start the Salt master in debug mode:
.. code-block:: yaml
.. code-block:: bash
service salt-master stop
salt-master -l debug
@ -207,13 +267,15 @@ discover syntax and other issues.
Trigger the Reactor
-------------------
On your minion, make and save another change to ``importantfile``. On the Salt
master, you'll see debug messages that indicate the event was received and the
``file.copy`` job was sent. When you list the directory on the minion, you'll now
see ``importantfile.bak``.
On your minion, make and save another change to ``/etc/important_file``. On the
Salt master, you'll see debug messages that indicate the event was received and
the ``state.apply`` job was sent. When you inspect the file on the minion,
you'll see that the file contents have been restored to ``important_config:
True``.
All beacons are configured using a similar process of enabling the beacon,
writing a reactor SLS, and mapping a beacon event to the reactor SLS.
writing a reactor SLS (and state SLS if needed), and mapping a beacon event to
the reactor SLS.
Writing Beacon Plugins
======================
@ -223,10 +285,10 @@ constructs from other plugin systems holds true, such as the ``__virtual__``
function.
The important function in the Beacon Plugin is the ``beacon`` function. When
the beacon is configured to run, this function will be executed repeatedly
by the minion. The ``beacon`` function therefore cannot block and should be
as lightweight as possible. The ``beacon`` also must return a list of dicts,
each dict in the list will be translated into an event on the master.
the beacon is configured to run, this function will be executed repeatedly by
the minion. The ``beacon`` function therefore cannot block and should be as
lightweight as possible. The ``beacon`` also must return a list of dicts, each
dict in the list will be translated into an event on the master.
Please see the :py:mod:`~salt.beacons.inotify` beacon as an example.
@ -234,10 +296,10 @@ The `beacon` Function
---------------------
The beacons system will look for a function named `beacon` in the module. If
this function is not present then the beacon will not be fired. This function is
called on a regular basis and defaults to being called on every iteration of the
minion, which can be tens to hundreds of times a second. This means that the
`beacon` function cannot block and should not be CPU or IO intensive.
this function is not present then the beacon will not be fired. This function
is called on a regular basis and defaults to being called on every iteration of
the minion, which can be tens to hundreds of times a second. This means that
the `beacon` function cannot block and should not be CPU or IO intensive.
The beacon function will be passed in the configuration for the executed
beacon. This makes it easy to establish a flexible configuration for each
@ -254,8 +316,8 @@ python dictionaries are preferred, no ordered dicts are needed).
The dictionaries represent individual events to be fired on the minion and
master event buses. Each dict is a single event. The dict can contain any
arbitrary keys but the 'tag' key will be extracted and added to the tag of
the fired event.
arbitrary keys but the 'tag' key will be extracted and added to the tag of the
fired event.
The return data structure would look something like this:
@ -274,12 +336,11 @@ available inside the beacon.
Please be careful when calling functions in `__salt__`, while this is the
preferred means of executing complicated routines in Salt not all of the
execution modules have been written with beacons in mind. Watch out for
execution modules that may be CPU intense or IO bound. Please feel free to
add new execution modules and functions to back specific beacons.
execution modules that may be CPU intense or IO bound. Please feel free to add
new execution modules and functions to back specific beacons.
Distributing Custom Beacons
---------------------------
Custom beacons can be distributed to minions using ``saltutil``, see
:ref:`Dynamic Module Distribution <dynamic-module-distribution>`.

View file

@ -188,6 +188,21 @@ For example:
- require:
- salt: do_first_thing
.. _beacons-and-reactors:
Beacons and Reactors
--------------------
An event initiated by a beacon, when it arrives at the master will be wrapped
inside a second event, such that the data object containing the beacon
information will be ``data['data']``, rather than ``data``.
For example, to access the ``id`` field of the beacon event in a reactor file,
you will need to reference ``{{ data['data']['id'] }}`` rather than ``{{
data['id'] }}`` as for events initiated directly on the event bus.
See the :ref:`beacon documentation <beacon-example>` for examples.
Fire an event
=============