123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- ======================
- Developing New Modules
- ======================
- Interactive Debugging
- =====================
- Sometimes debugging with ``print()`` and extra logs sprinkled everywhere is not
- the best strategy.
- IPython is a helpful debug tool that has an interactive python environment
- which can be embedded in python programs.
- First the system will require IPython to be installed.
- .. code-block:: bash
- # Debian
- apt-get install ipython
- # Arch Linux
- pacman -Syu ipython2
- # RHEL/CentOS (via EPEL)
- yum install python-ipython
- Now, in the troubling python module, add the following line at a location where
- the debugger should be started:
- .. code-block:: python
- test = "test123"
- import IPython
- IPython.embed_kernel()
- After running a Salt command that hits that line, the following will show up in
- the log file:
- .. code-block:: text
- [CRITICAL] To connect another client to this kernel, use:
- [IPKernelApp] --existing kernel-31271.json
- Now on the system that invoked ``embed_kernel``, run the following command from
- a shell:
- .. code-block:: bash
- # NOTE: use ipython2 instead of ipython for Arch Linux
- ipython console --existing
- This provides a console that has access to all the vars and functions, and even
- supports tab-completion.
- .. code-block:: python
- print(test)
- test123
- To exit IPython and continue running Salt, press ``Ctrl-d`` to logout.
- Special Module Contents
- =======================
- These are things that may be defined by the module to influence various things.
- __virtual__
- -----------
- __virtual_aliases__
- -------------------
- __virtualname__
- ---------------
- __init__
- --------
- Called before ``__virtual__()``
- __proxyenabled__
- ----------------
- grains and proxy modules
- __proxyenabled__ as a list containing the names of the proxy types that the module supports.
- __load__
- --------
- __func_alias__
- --------------
- __outputter__
- -------------
- .. _dunder-dictionaries:
- Dunder Dictionaries
- ===================
- Salt provides several special "dunder" dictionaries as a convenience for Salt
- development. These include ``__opts__``, ``__context__``, ``__salt__``, and
- others. This document will describe each dictionary and detail where they exist
- and what information and/or functionality they provide.
- The following dunder dictionaries are always defined, but may be empty
- * ``__context__``
- * ``__grains__``
- * ``__pillar__``
- * ``__opts__``
- __opts__
- --------
- Defined in: All modules
- The ``__opts__`` dictionary contains all of the options passed in the
- configuration file for the master or minion.
- .. note::
- In many places in salt, instead of pulling raw data from the __opts__
- dict, configuration data should be pulled from the salt `get` functions
- such as config.get, aka - ``__salt__['config.get']('foo:bar')``
- The `get` functions also allow for dict traversal via the *:* delimiter.
- Consider using get functions whenever using ``__opts__`` or ``__pillar__``
- and ``__grains__`` (when using grains for configuration data)
- The configuration file data made available in the ``__opts__`` dictionary is the
- configuration data relative to the running daemon. If the modules are loaded and
- executed by the master, then the master configuration data is available, if the
- modules are executed by the minion, then the minion configuration is
- available. Any additional information passed into the respective configuration
- files is made available
- __salt__
- --------
- Defined in: Auth, Beacons, Engines, Execution, Executors, Outputters, Pillars,
- Proxies, Renderers, Returners, Runners, SDB, SSH Wrappers, State, Thorium
- ``__salt__`` contains the execution module functions. This allows for all
- functions to be called as they have been set up by the salt loader.
- .. code-block:: python
- __salt__["cmd.run"]("fdisk -l")
- __salt__["network.ip_addrs"]()
- .. note::
- When used in runners or outputters, ``__salt__`` references other
- runner/outputter modules, and not execution modules.
- __grains__
- ----------
- Filled in for: Execution, Pillar, Renderer, Returner, SSH Wrapper, State.
- The ``__grains__`` dictionary contains the grains data generated by the minion
- that is currently being worked with. In execution modules, state modules and
- returners this is the grains of the minion running the calls, when generating
- the external pillar the ``__grains__`` is the grains data from the minion that
- the pillar is being generated for.
- While ``__grains__`` is defined for every module, it's only filled in for some.
- __pillar__
- -----------
- Filled in for: Execution, Renderer, Returner, SSH Wrapper, State
- The ``__pillar__`` dictionary contains the pillar for the respective minion.
- While ``__pillar__`` is defined for every module, it's only filled in for some.
- __ext_pillar__
- --------------
- Filled in for: Pillar
- The ``__ext_pillar__`` dictionary contains the external pillar modules.
- .. _dunder-context:
- __context__
- -----------
- During a state run the ``__context__`` dictionary persists across all states
- that are run and then is destroyed when the state ends.
- When running an execution module ``__context__`` persists across all module
- executions until the modules are refreshed; such as when
- :py:func:`saltutil.sync_all <salt.modules.saltutil.sync_all>` or
- :py:func:`state.apply <salt.modules.state.apply_>` are executed.
- A great place to see how to use ``__context__`` is in the cp.py module in
- salt/modules/cp.py. The fileclient authenticates with the master when it is
- instantiated and then is used to copy files to the minion. Rather than create a
- new fileclient for each file that is to be copied down, one instance of the
- fileclient is instantiated in the ``__context__`` dictionary and is reused for
- each file. Here is an example from salt/modules/cp.py:
- .. code-block:: python
- if not "cp.fileclient" in __context__:
- __context__["cp.fileclient"] = salt.fileclient.get_file_client(__opts__)
- .. note:: Because __context__ may or may not have been destroyed, always be
- sure to check for the existence of the key in __context__ and
- generate the key before using it.
- __utils__
- ---------
- Defined in: Cloud, Engine, Execution, File Server, Grain, Pillar, Proxy, Roster, Runner, SDB, State
- __proxy__
- ---------
- Defined in: Beacon, Engine, Execution, Executor, Proxy, Renderer, Returner, State, Util
- __runner__
- -----------
- Defined in: Engine, Roster, Thorium
- .. note:: When used in engines, it should be called __runners__ (plural)
- __executors__
- -------------
- Defined in: Executor
- __ret__
- -------
- Defined in: Proxy
- __thorium__
- -----------
- Defined in: Thorium
- __states__
- ----------
- Defined in: Renderers, State
- __serializers__
- ---------------
- Defined in: State
- __sdb__
- -------
- Defined in: SDB
- Additional Globals
- ==================
- Defined for: Runners, Execution Modules, Wheels
- * ``__jid__``: The job ID
- * ``__user__``: The user
- * ``__tag__``: The jid tag
- * ``__jid_event__``: A :py:class:`salt.utils.event.NamespacedEvent`.
- :py:class:`NamespacedEvent <salt.utils.event.NamespacedEvent>` defines a single
- method :py:meth:`fire_event <salt.utils.event.NamespacedEvent.fire_event>`, that takes data and tag. The :ref:`Runner docs <runners>` has examples.
|