index.rst 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. .. _thorium-reactor:
  2. =======================
  3. Thorium Complex Reactor
  4. =======================
  5. The original Salt Reactor is based on the idea of listening for a specific
  6. event and then reacting to it. This model comes with many logical limitations,
  7. for instance it is very difficult (and hacky) to fire a reaction based on
  8. aggregate data or based on multiple events.
  9. The Thorium reactor is intended to alleviate this problem in a very elegant way.
  10. Instead of using extensive jinja routines or complex python sls files the
  11. aggregation of data and the determination of what should run becomes isolated
  12. to the sls data logic, makes the definitions much cleaner.
  13. Starting the Thorium Engine
  14. ===========================
  15. To enable the thorium engine add the following configuration to the engines
  16. section of your Salt Master or Minion configuration file and restart the daemon:
  17. .. code-block:: yaml
  18. engines:
  19. - thorium: {}
  20. Thorium Modules
  21. ===============
  22. Because of its specialized nature, Thorium uses its own set of modules. However,
  23. many of these modules are designed to wrap the more commonly-used Salt
  24. subsystems. These modules are:
  25. * local: Execution modules
  26. * runner: Runner modules
  27. * wheel: Wheel modules
  28. There are other modules that ship with Thorium as well. Some of these will be
  29. highlighted later in this document.
  30. Writing Thorium Formulas
  31. ========================
  32. Like some other Salt subsystems, Thorium uses its own directory structure. The
  33. default location for this structure is ``/srv/thorium/``, but it can be changed
  34. using the ``thorium_roots`` setting in the ``master`` configuration file.
  35. This would explicitly set the roots to the default:
  36. .. code-block:: yaml
  37. thorium_roots:
  38. base:
  39. - /srv/thorium
  40. Example ``thorium_roots`` configuration:
  41. .. code-block:: yaml
  42. thorium_roots:
  43. base:
  44. - /etc/salt/thorium
  45. It is also possible to use gitfs with Thorium,
  46. using the ``thoriumenv`` or ``thorium_top`` settings.
  47. Example using ``thorium_top``:
  48. .. code-block:: yaml
  49. thorium_top: salt://thorium/top.sls
  50. gitfs_provider: pygit2
  51. gitfs_remotes:
  52. - git@github.com:user/repo.git:
  53. - name: salt-backend
  54. - root: salt
  55. - base: master
  56. - git@github.com:user/repo.git:
  57. - name: thorium-backend
  58. - root: thorium
  59. - base: master
  60. - mountpoint: salt://thorium
  61. .. note::
  62. When using this method don't forget to prepend the mountpoint to files served by this repo,
  63. for example ``top.sls``:
  64. .. code-block:: yaml
  65. base:
  66. '*':
  67. - thorium.key_clean
  68. Example using ``thoriumenv``:
  69. .. code-block:: yaml
  70. thoriumenv: thorium
  71. gitfs_provider: pygit2
  72. gitfs_remotes:
  73. - git@github.com:user/repo.git:
  74. - name: salt-backend
  75. - root: salt
  76. - base: master
  77. - git@github.com:user/repo.git:
  78. - name: thorium-backend
  79. - root: thorium
  80. - saltenv:
  81. - thorium:
  82. - ref: master
  83. .. note::
  84. When using this method all state will run under the defined environment,
  85. for example ``top.sls``:
  86. .. code-block:: yaml
  87. thorium:
  88. '*':
  89. - key_clean
  90. The Thorium top.sls File
  91. ------------------------
  92. Thorium uses its own ``top.sls`` file, which follows the same convention as is
  93. found in ``/srv/salt/``:
  94. .. code-block:: yaml
  95. <srv>:
  96. <target>:
  97. - <formula 1>
  98. - <formula 2>
  99. - <etc...>
  100. For instance, a ``top.sls`` using a standard ``base`` environment and a single
  101. Thorium formula called ``key_clean``, would look like:
  102. .. code-block:: yaml
  103. base:
  104. '*':
  105. - key_clean
  106. Take note that the target in a Thorium ``top.sls`` is not used; it only exists
  107. to follow the same convention as other ``top.sls`` files. Leave this set to
  108. ``'*'`` in your own Thorium ``top.sls``.
  109. Thorium Formula Files
  110. ---------------------
  111. Thorium SLS files are processed by the same state compiler that processes Salt
  112. state files. This means that features like requisites, templates, and so on are
  113. available.
  114. Let's take a look at an example, and then discuss each component of it. This
  115. formula uses Thorium to detect when a minion has disappeared and then deletes
  116. the key from the master when the minion has been gone for 60 seconds:
  117. .. code-block:: yaml
  118. statreg:
  119. status.reg
  120. keydel:
  121. key.timeout:
  122. - delete: 60
  123. - require:
  124. - status: statreg
  125. There are two stanzas in this formula, whose IDs are ``statreg`` and
  126. ``keydel``. The first stanza, ``statreg``, tells Thorium to keep track of
  127. minion status beacons in its *register*. We'll talk more about the register in
  128. a moment.
  129. The second stanza, ``keydel``, is the one that does the real work. It uses the
  130. ``key`` module to apply an expiration (using the ``timeout`` function) to a
  131. minion. Because ``delete`` is set to ``60``, this is a 60 second expiration. If
  132. a minion does not check in at least once every 60 seconds, its key will be
  133. deleted from the master. This particular function also allows you to use
  134. ``reject`` instead of ``delete``, allowing for a minion to be rejected instead
  135. of deleted if it does not check in within the specified time period.
  136. There is also a ``require`` requisite in this stanza. It states that the
  137. ``key.timeout`` function will not be called unless the ``status.reg`` function
  138. in the ``statreg`` codeblock has been successfully called first.
  139. Thorium Links to Beacons
  140. ------------------------
  141. The above example was added in the 2016.11.0 release of Salt and makes use of the
  142. ``status`` beacon also added in the 2016.11.0 release. For the above Thorium state
  143. to function properly you will also need to enable the ``status`` beacon in the
  144. ``minion`` configuration file:
  145. .. code-block:: yaml
  146. beacons:
  147. status:
  148. - interval: 10
  149. This will cause the minion to use the status beacon to check in with the master
  150. every 10 seconds.
  151. The Thorium Register
  152. ====================
  153. In order to keep track of information, Thorium uses an in-memory register (or
  154. rather, collection of registers) on the master. These registers are only
  155. populated when told to by a formula, and they normally will be erased when the
  156. master is restarted. It is possible to persist the registers to disk, but we'll
  157. get to that in a moment.
  158. The example above uses ``status.reg`` to populate a register for you, which is
  159. automatically used by the ``key.timeout`` function. However, you can set your
  160. own register values as well, using the ``reg`` module.
  161. Because Thorium watches the event bus, the ``reg`` module is designed to look
  162. for user-specified tags, and then extract data from the payload of events that
  163. match those tags. For instance, the following stanza will look for an event
  164. with a tag of ``my/custom/event``:
  165. .. code-block:: yaml
  166. foo:
  167. reg.list:
  168. - add: bar
  169. - match: my/custom/event
  170. When such an event is found, the data found in the payload dictionary key of
  171. ``bar`` will be stored in a register called ``foo``. This register will store
  172. that data in a ``list``. You may also use ``reg.set`` to add data to a ``set()``
  173. instead.
  174. If you would like to see a copy of the register as it is stored in memory, you
  175. can use the ``file.save`` function:
  176. .. code-block:: yaml
  177. myreg:
  178. file.save
  179. In this case, each time the register is updated, a copy will be saved in JSON
  180. format at ``/var/cache/salt/master/thorium/saves/myreg``. If you would like to
  181. see when particular events are added to a list-type register, you may add a
  182. ``stamp`` option to ``reg.list`` (but not ``reg.set``). With the above two
  183. stanzas put together, this would look like:
  184. .. code-block:: yaml
  185. foo:
  186. reg.list:
  187. - add: bar
  188. - match: my/custom/event
  189. - stamp: True
  190. myreg:
  191. file.save
  192. If you would like to only keep a certain number of the most recent register
  193. entries, you may also add a ``prune`` option to ``reg.list`` (but not
  194. ``reg.set``):
  195. .. code-block:: yaml
  196. foo:
  197. reg.list:
  198. - add: bar
  199. - match: my/custom/event
  200. - stamp: True
  201. - prune: 50
  202. This example will only keep the 50 most recent entries in the ``foo`` register.
  203. Using Register Data
  204. -------------------
  205. Putting data in a register is useless if you don't do anything with it. The
  206. ``check`` module is designed to examine register data and determine whether it
  207. matches the given parameters. For instance, the ``check.contains`` function
  208. will return ``True`` if the given ``value`` is contained in the specified
  209. register:
  210. .. code-block:: yaml
  211. foo:
  212. reg.list:
  213. - add: bar
  214. - match: my/custom/event
  215. - stamp: True
  216. - prune: 50
  217. check.contains:
  218. - value: somedata
  219. Used with a ``require`` requisite, we can call one of the wrapper modules and
  220. perform an operation. For example:
  221. .. code-block:: yaml
  222. shell_test:
  223. local.cmd:
  224. - tgt: dufresne
  225. - func: cmd.run
  226. - arg:
  227. - echo 'thorium success' > /tmp/thorium.txt
  228. - require:
  229. - check: foo
  230. This stanza will only run if the ``check.contains`` function under the ``foo``
  231. ID returns true (meaning the match was found).
  232. There are a number of other functions in the ``check`` module which use
  233. different means of comparing values:
  234. * ``gt``: Check whether the register entry is greater than the given value
  235. * ``gte``: Check whether the register entry is greater than or equal to the given value
  236. * ``lt``: Check whether the register entry is less than the given value
  237. * ``lte``: Check whether the register entry is less than or equal to the given value
  238. * ``eq``: Check whether the register entry is equal to the given value
  239. * ``ne``: Check whether the register entry is not equal to the given value
  240. There is also a function called ``check.event`` which does not examine the
  241. register. Instead, it looks directly at an event as it is coming in on the
  242. event bus, and returns ``True`` if that event's tag matches. For example:
  243. .. code-block:: yaml
  244. salt/foo/*/bar:
  245. check.event
  246. run_remote_ex:
  247. local.cmd:
  248. - tgt: '*'
  249. - func: test.version
  250. - require:
  251. - check: salt/foo/*/bar
  252. This formula will look for an event whose tag is ``salt/foo/<anything>/bar`` and
  253. if it comes in, issue a ``test.version`` to all minions.
  254. Register Persistence
  255. --------------------
  256. It is possible to persist the register data to disk when a master is stopped
  257. gracefully, and reload it from disk when the master starts up again. This
  258. functionality is provided by the returner subsystem, and is enabled whenever
  259. any returner containing a ``load_reg`` and a ``save_reg`` function is used.