aggregate.rst 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. .. _mod-aggregate-state:
  2. =========================================
  3. Mod Aggregate State Runtime Modifications
  4. =========================================
  5. .. versionadded:: 2014.7.0
  6. The mod_aggregate system was added in the 2014.7.0 release of Salt and allows for
  7. runtime modification of the executing state data. Simply put, it allows for the
  8. data used by Salt's state system to be changed on the fly at runtime, kind of
  9. like a configuration management JIT compiler or a runtime import system. All in
  10. all, it makes Salt much more dynamic.
  11. How it Works
  12. ============
  13. The best example is the ``pkg`` state. One of the major requests in Salt has long
  14. been adding the ability to install all packages defined at the same time. The
  15. mod_aggregate system makes this a reality. While executing Salt's state system,
  16. when a ``pkg`` state is reached the ``mod_aggregate`` function in the state module
  17. is called. For ``pkg`` this function scans all of the other states that are slated
  18. to run, and picks up the references to ``name`` and ``pkgs``, then adds them to
  19. ``pkgs`` in the first state. The result is a single call to yum, apt-get,
  20. pacman, etc as part of the first package install.
  21. How to Use it
  22. =============
  23. .. note::
  24. Since this option changes the basic behavior of the state runtime, after
  25. it is enabled states should be executed using `test=True` to ensure that
  26. the desired behavior is preserved.
  27. In config files
  28. ---------------
  29. The first way to enable aggregation is with a configuration option in either
  30. the master or minion configuration files. Salt will invoke ``mod_aggregate``
  31. the first time it encounters a state module that has aggregate support.
  32. If this option is set in the master config it will apply to all state runs on
  33. all minions, if set in the minion config it will only apply to said minion.
  34. Enable for all states:
  35. .. code-block:: yaml
  36. state_aggregate: True
  37. Enable for only specific state modules:
  38. .. code-block:: yaml
  39. state_aggregate:
  40. - pkg
  41. In states
  42. ---------
  43. The second way to enable aggregation is with the state-level ``aggregate``
  44. keyword. In this configuration, Salt will invoke the ``mod_aggregate`` function
  45. the first time it encounters this keyword. Any additional occurrences of the
  46. keyword will be ignored as the aggregation has already taken place.
  47. The following example will trigger ``mod_aggregate`` when the ``lamp_stack``
  48. state is processed resulting in a single call to the underlying package
  49. manager.
  50. .. code-block:: yaml
  51. lamp_stack:
  52. pkg.installed:
  53. - pkgs:
  54. - php
  55. - mysql-client
  56. - aggregate: True
  57. memcached:
  58. pkg.installed:
  59. - name: memcached
  60. Adding mod_aggregate to a State Module
  61. ======================================
  62. Adding a mod_aggregate routine to an existing state module only requires adding
  63. an additional function to the state module called mod_aggregate.
  64. The mod_aggregate function just needs to accept three parameters and return the
  65. low data to use. Since mod_aggregate is working on the state runtime level it
  66. does need to manipulate `low data`.
  67. The three parameters are `low`, `chunks`, and `running`. The `low` option is the
  68. low data for the state execution which is about to be called. The `chunks` is
  69. the list of all of the low data dictionaries which are being executed by the
  70. runtime and the `running` dictionary is the return data from all of the state
  71. executions which have already be executed.
  72. This example, simplified from the pkg state, shows how to create mod_aggregate functions:
  73. .. code-block:: python
  74. def mod_aggregate(low, chunks, running):
  75. """
  76. The mod_aggregate function which looks up all packages in the available
  77. low chunks and merges them into a single pkgs ref in the present low data
  78. """
  79. pkgs = []
  80. # What functions should we aggregate?
  81. agg_enabled = [
  82. "installed",
  83. "latest",
  84. "removed",
  85. "purged",
  86. ]
  87. # The `low` data is just a dict with the state, function (fun) and
  88. # arguments passed in from the sls
  89. if low.get("fun") not in agg_enabled:
  90. return low
  91. # Now look into what other things are set to execute
  92. for chunk in chunks:
  93. # The state runtime uses "tags" to track completed jobs, it may
  94. # look familiar with the _|-
  95. tag = __utils__["state.gen_tag"](chunk)
  96. if tag in running:
  97. # Already ran the pkg state, skip aggregation
  98. continue
  99. if chunk.get("state") == "pkg":
  100. if "__agg__" in chunk:
  101. continue
  102. # Check for the same function
  103. if chunk.get("fun") != low.get("fun"):
  104. continue
  105. # Pull out the pkg names!
  106. if "pkgs" in chunk:
  107. pkgs.extend(chunk["pkgs"])
  108. chunk["__agg__"] = True
  109. elif "name" in chunk:
  110. pkgs.append(chunk["name"])
  111. chunk["__agg__"] = True
  112. if pkgs:
  113. if "pkgs" in low:
  114. low["pkgs"].extend(pkgs)
  115. else:
  116. low["pkgs"] = pkgs
  117. # The low has been modified and needs to be returned to the state
  118. # runtime for execution
  119. return low