mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 09:23:56 +00:00
330 lines
11 KiB
ReStructuredText
330 lines
11 KiB
ReStructuredText
=================
|
|
Execution Modules
|
|
=================
|
|
|
|
Salt execution modules are the functions called by the :command:`salt` command.
|
|
|
|
.. note::
|
|
|
|
Salt execution modules are different from state modules and cannot be
|
|
called directly within state files. You must use the :mod:`module <salt.states.module>`
|
|
state module to call execution modules within state runs.
|
|
|
|
.. seealso:: :ref:`Full list of builtin modules <all-salt.modules>`
|
|
|
|
Salt ships with many modules that cover a wide variety of tasks.
|
|
|
|
.. _writing-execution-modules:
|
|
|
|
Modules Are Easy to Write!
|
|
==========================
|
|
|
|
Writing Salt execution modules is straightforward.
|
|
|
|
A Salt execution modules is a Python or `Cython`_ module
|
|
placed in a directory called ``_modules/``
|
|
within the :conf_master:`file_roots` as specified by the master config file. By
|
|
default this is `/srv/salt/_modules` on Linux systems.
|
|
|
|
|
|
Modules placed in ``_modules/`` will be synced to the minions when any of the following
|
|
Salt functions are called:
|
|
|
|
:mod:`state.highstate <salt.modules.state.highstate>`
|
|
|
|
:mod:`saltutil.sync_modules <salt.modules.saltutil.sync_modules>`
|
|
|
|
:mod:`saltutil.sync_all <salt.modules.saltutil.sync_all>`
|
|
|
|
Note that a module's default name is its filename
|
|
(i.e. ``foo.py`` becomes module ``foo``), but that its name can be overridden
|
|
by using a :ref:`__virtual__ function <virtual-modules>`.
|
|
|
|
If a Salt module has errors and cannot be imported, the Salt minion will continue
|
|
to load without issue and the module with errors will simply be omitted.
|
|
|
|
If adding a Cython module the file must be named ``<modulename>.pyx`` so that
|
|
the loader knows that the module needs to be imported as a Cython module. The
|
|
compilation of the Cython module is automatic and happens when the minion
|
|
starts, so only the ``*.pyx`` file is required.
|
|
|
|
.. _`Cython`: http://cython.org/
|
|
|
|
Cross-Calling Modules
|
|
=====================
|
|
|
|
All of the Salt execution modules are available to each other and modules can call
|
|
functions available in other execution modules.
|
|
|
|
The variable ``__salt__`` is packed into the modules after they are loaded into
|
|
the Salt minion.
|
|
|
|
The ``__salt__`` variable is a :ref:`Python dictionary <python2:typesmapping>`
|
|
containing all of the Salt functions. Dictionary keys are strings representing the
|
|
names of the modules and the values are the functions themselves.
|
|
|
|
Salt modules can be cross-called by accessing the value in the ``__salt__`` dict:
|
|
|
|
.. code-block:: python
|
|
|
|
def foo(bar):
|
|
return __salt__['cmd.run'](bar)
|
|
|
|
This code will call the `run` function in the :mod:`cmd <salt.modules.cmdmod>` and pass the argument
|
|
``bar`` to it.
|
|
|
|
|
|
Preloaded Execution Module Data
|
|
===============================
|
|
|
|
When interacting with execution modules often it is nice to be able to read information
|
|
dynamically about the minion or to load in configuration parameters for a module.
|
|
|
|
Salt allows for different types of data to be loaded into the modules by the
|
|
minion.
|
|
|
|
Grains Data
|
|
-----------
|
|
|
|
The values detected by the Salt Grains on the minion are available in a
|
|
:ref:`dict <python2:typesmapping>` named ``__grains__`` and can be accessed
|
|
from within callable objects in the Python modules.
|
|
|
|
To see the contents of the grains dictionary for a given system in your deployment
|
|
run the :func:`grains.items` function:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt 'hostname' grains.items --output=pprint
|
|
|
|
Any value in a grains dictionary can be accessed as any other Python dictionary. For
|
|
example, the grain representing the minion ID is stored in the ``id`` key and from
|
|
an execution module, the value would be stored in ``__grains__['id']``.
|
|
|
|
|
|
Module Configuration
|
|
--------------------
|
|
|
|
Since parameters for configuring a module may be desired, Salt allows for
|
|
configuration information from the minion configuration file to be passed to
|
|
execution modules.
|
|
|
|
Since the minion configuration file is a YAML document, arbitrary configuration
|
|
data can be passed in the minion config that is read by the modules. It is therefore
|
|
**strongly** recommended that the values passed in the configuration file match
|
|
the module name. A value intended for the ``test`` execution module should be named
|
|
``test.<value>``.
|
|
|
|
The test execution module contains usage of the module configuration and the default
|
|
configuration file for the minion contains the information and format used to
|
|
pass data to the modules. :mod:`salt.modules.test`, :file:`conf/minion`.
|
|
|
|
Printout Configuration
|
|
======================
|
|
|
|
Since execution module functions can return different data, and the way the data is
|
|
printed can greatly change the presentation, Salt has a printout configuration.
|
|
|
|
When writing a module the ``__outputter__`` dictionary can be declared in the module.
|
|
The ``__outputter__`` dictionary contains a mapping of function name to Salt
|
|
Outputter.
|
|
|
|
.. code-block:: python
|
|
|
|
__outputter__ = {
|
|
'run': 'txt'
|
|
}
|
|
|
|
This will ensure that the text outputter is used.
|
|
|
|
|
|
.. _virtual-modules:
|
|
|
|
Virtual Modules
|
|
===============
|
|
|
|
Sometimes an execution module should be presented in a generic way. A good example of this
|
|
can be found in the package manager modules. The package manager changes from
|
|
one operating system to another, but the Salt execution module that interfaces with the
|
|
package manager can be presented in a generic way.
|
|
|
|
The Salt modules for package managers all contain a ``__virtual__`` function
|
|
which is called to define what systems the module should be loaded on.
|
|
|
|
The ``__virtual__`` function is used to return either a
|
|
:ref:`string <python2:typesseq>` or :py:data:`False`. If
|
|
False is returned then the module is not loaded, if a string is returned then
|
|
the module is loaded with the name of the string.
|
|
|
|
This means that the package manager modules can be presented as the ``pkg`` module
|
|
regardless of what the actual module is named.
|
|
|
|
The package manager modules are the best example of using the ``__virtual__``
|
|
function. Some examples:
|
|
|
|
- :blob:`pacman.py <salt/modules/pacman.py>`
|
|
- :blob:`yumpkg.py <salt/modules/yumpkg.py>`
|
|
- :blob:`aptpkg.py <salt/modules/aptpkg.py>`
|
|
|
|
.. note::
|
|
Modules which return a string from ``__virtual__`` that is already used by a module that
|
|
ships with Salt will _override_ the stock module.
|
|
|
|
|
|
Documentation
|
|
=============
|
|
|
|
Salt execution modules are documented. The :func:`sys.doc` function will return the
|
|
documentation for all available modules:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' sys.doc
|
|
|
|
The ``sys.doc`` function simply prints out the docstrings found in the modules; when
|
|
writing Salt execution modules, please follow the formatting conventions for docstrings as
|
|
they appear in the other modules.
|
|
|
|
Adding Documentation to Salt Modules
|
|
------------------------------------
|
|
|
|
It is strongly suggested that all Salt modules have documentation added.
|
|
|
|
To add documentation add a `Python docstring`_ to the function.
|
|
|
|
.. code-block:: python
|
|
|
|
def spam(eggs):
|
|
'''
|
|
A function to make some spam with eggs!
|
|
|
|
CLI Example::
|
|
|
|
salt '*' test.spam eggs
|
|
'''
|
|
return eggs
|
|
|
|
Now when the sys.doc call is executed the docstring will be cleanly returned
|
|
to the calling terminal.
|
|
|
|
.. _`Python docstring`: http://docs.python.org/2/glossary.html#term-docstring
|
|
|
|
Documentation added to execution modules in docstrings will automatically be added
|
|
to the online web-based documentation.
|
|
|
|
|
|
Add Execution Module Metadata
|
|
-----------------------------
|
|
|
|
When writing a Python docstring for an execution module, add information about the module
|
|
using the following field lists:
|
|
|
|
.. code-block:: text
|
|
|
|
:maintainer: Thomas Hatch <thatch@saltstack.com, Seth House <shouse@saltstack.com>
|
|
:maturity: new
|
|
:depends: python-mysqldb
|
|
:platform: all
|
|
|
|
The maintainer field is a comma-delimited list of developers who help maintain
|
|
this module.
|
|
|
|
The maturity field indicates the level of quality and testing for this module.
|
|
Standard labels will be determined.
|
|
|
|
The depends field is a comma-delimited list of modules that this module depends
|
|
on.
|
|
|
|
The platform field is a comma-delimited list of platforms that this module is
|
|
known to run on.
|
|
|
|
Private Functions
|
|
=================
|
|
|
|
In Salt, Python callable objects contained within an execution module are made available
|
|
to the Salt minion for use. The only exception to this rule is a callable
|
|
object with a name starting with an underscore ``_``.
|
|
|
|
Objects Loaded Into the Salt Minion
|
|
-----------------------------------
|
|
|
|
.. code-block:: python
|
|
|
|
def foo(bar):
|
|
return bar
|
|
|
|
class baz:
|
|
def __init__(self, quo):
|
|
pass
|
|
|
|
Objects NOT Loaded into the Salt Minion
|
|
---------------------------------------
|
|
|
|
.. code-block:: python
|
|
|
|
def _foobar(baz): # Preceded with an _
|
|
return baz
|
|
|
|
cheese = {} # Not a callable Python object
|
|
|
|
.. note::
|
|
|
|
Some callable names also end with an underscore ``_``, to avoid keyword clashes
|
|
with Python keywords. When using execution modules, or state modules, with these
|
|
in them the trailing underscore should be omitted.
|
|
|
|
Useful Decorators for Modules
|
|
=============================
|
|
|
|
Depends Decorator
|
|
-----------------
|
|
When writing execution modules there are many times where some of the module will
|
|
work on all hosts but some functions have an external dependency, such as a service
|
|
that needs to be installed or a binary that needs to be present on the system.
|
|
|
|
Instead of trying to wrap much of the code in large try/except blocks, a decorator can
|
|
be used.
|
|
|
|
If the dependencies passed to the decorator don't exist, then the salt minion will remove
|
|
those functions from the module on that host.
|
|
|
|
If a "fallback_function" is defined, it will replace the function instead of removing it
|
|
|
|
.. code-block:: python
|
|
|
|
import logging
|
|
|
|
from salt.utils.decorators import depends
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
try:
|
|
import dependency_that_sometimes_exists
|
|
except ImportError as e:
|
|
log.trace('Failed to import dependency_that_sometimes_exists: {0}'.format(e))
|
|
|
|
@depends('dependency_that_sometimes_exists')
|
|
def foo():
|
|
'''
|
|
Function with a dependency on the "dependency_that_sometimes_exists" module,
|
|
if the "dependency_that_sometimes_exists" is missing this function will not exist
|
|
'''
|
|
return True
|
|
|
|
def _fallback():
|
|
'''
|
|
Fallback function for the depends decorator to replace a function with
|
|
'''
|
|
return '"dependency_that_sometimes_exists" needs to be installed for this function to exist'
|
|
|
|
@depends('dependency_that_sometimes_exists', fallback_function=_fallback)
|
|
def foo():
|
|
'''
|
|
Function with a dependency on the "dependency_that_sometimes_exists" module.
|
|
If the "dependency_that_sometimes_exists" is missing this function will be
|
|
replaced with "_fallback"
|
|
'''
|
|
return True
|
|
|
|
|