GRAINS
Salt provides an interface for obtaining information about the managed system. This is known as grains interface, because it provides information for the grains salt. Grains information related to the operating system, domain name, IP address, the kernel, operating system type, system memory, and many other attributes.
Salt components and modules may utilize grain interface to automatically obtain the correct system on the correct salt minion command parameters.
Grains are relatively static data, but if the system information is changed (e.g., if the network setting change), or if the new value assigned to the custom Grain, then the data will be refreshed grains.
This article can also refer this item on GitHub: GRAINS
Note: Grains are UNIFIED lowercase. For example, FOO and foo refer to the same grain.
LISTING GRAINS
You may be used ' grains.ls ' grains available modules listed:
salt '*' grains.ls
Grains and data can be used 'grains.items' Check module:
salt '*' grains.items
USING GRAINS IN A STATE
You can simply reference the data in this way grains in state definition file {{ grains['key'] }}
.
GRAINS IN THE MINION CONFIG
Demand can be defined grains minion in the configuration file. Just add the option grain and configuration items passed to it:
grains:
roles:
- webserver
- memcache
deployment: datacenter4
cabinet: 13
cab_u: 14-15
Then, by Salt you can retrieve specific data to the state of the server, or in the target within the State matching system. Your above example, it provides can be minions targeting based on specific data about the deployment of auxiliary properties.
GRAINS IN /ETC/SALT/GRAINS
If you do not want to customize the grains on the minion configuration file, or you can put them /etc/salt/grain
in. They are configured the same as the previous example, but not a top-level grains:
keys:
roles:
- webserver
- memcache
deployment: datacenter4
cabinet: 13
cab_u: 14-15
注意:
/etc/salt/grains
are ignored if you specify the same grains in the minion config.
Note: Grains are static, because they do not frequently changed, they need to take the initiative to refresh when you update. This is done by calling:
salt minion saltutil.refresh_modules
to do this.
Note: You can configure a custom grains as Proxy Minions. Proxy Minion Because multiple processes can run on the same machine, so you need to use
/etc/salt/proxy.d/<minion ID>/grains
at Minion ID index file. For example, Proxy Minionrouter1
of grains may/etc/salt/proxy.d/router1/grains
define, Proxy Minion andswitch7
the grains can be placed/etc/salt/proxy.d/switch7/
in.
MATCHING GRAINS IN THE TOP FILE
After the Minions configured correctly grains, topfile file Pillar or Highstate can be used very efficiently. For example the following configuration:
'roles:webserver':
- match: grain
- state0
'roles:memcache':
- match: grain
- state1
- state2
For this example to work, you need to define the role for the good grains to match minions.
WRITING GRAINS
By performing the core grains of Salt code module all "public" function (i.e., those that do not begin with an underscore function), as well as custom function module grains, grains to obtain desired data. Grain function module must return a Python dictionary, wherein the dictionary key is the name of the grain, the value of each key that the value of the grain.
Grains should be placed in a custom module named _grains
subdirectory, the subdirectory in the master configuration file specified file_roots
below. The default path is /srv/salt/_grains
. Run state.highstate
time, or by performing saltutil.sync_grains
or saltutil.sync_all
function, the module will distribute custom grains minions.
Grains module is easy to prepare, and (as mentioned above) only needs to return a data dictionary. E.g:
def yourfunction():
# initialize a grains dictionary
grains = {}
# Some code for logic that sets grains like
grains['yourcustomgrain'] = True
grains['anothergrain'] = 'somevalue'
return grains
Name of the function does not matter, will not affect grains data; only the return of key / value will become part of the grains in the data.
WHEN TO USE A CUSTOM GRAIN
In the definition of a new grain before, consider what characteristics data is and should remember grains (mostly) static type of data.
If the data may change, consider using Pillar or execution module. If it is a simple set of key / value pairs, the pillar is a good match. If you need to run system commands to compile information on the process, then this information on the implementation of the module may be a better idea.
Best practices using the grains as a data location in topfile minions file or in Salt CLI. Grains names and data structure should be designed to support multiple platforms, operating systems or applications. Also, remember, Jinja template Salt pillar of support reference data and call functions from execution module, so no information is placed in the grain to make it available for Jinja template. E.g:
...
...
{{ salt['module.function_name']('argument_1', 'argument_2') }}
{{ pillar['my_pillar_key'] }}
...
...
Warning: After executing the first time highstate, custom grains take effect topfile file. In order to perform the first in the under-highstate use minion, custom grains is effective, it is recommended to use this reator of example to ensure that the implementation process starts when the minion custom grains synchronous data.
LOADING CUSTOM GRAINS
If you use a subroutine to help generate grains data, be sure to add an underscore in front of grains subroutine name. This can prevent the grains Salt from the final grain structure in the data contained in the loaded grain function. For example, consider this custom grain file:
#!/usr/bin/env python
def _my_custom_grain():
my_grain = {'foo': 'bar', 'hello': 'world'}
return my_grain
def main():
# initialize a grains dictionary
grains = {}
grains['my_grains'] = _my_custom_grain()
return grains
The output of this example is as follows:
# salt-call --local grains.items
local:
----------
<Snipped for brevity>
my_grains:
----------
foo:
bar
hello:
world
However, if you do not have my_custom_grain
to add an underscore before the function, the function will appear in the items output by Salt twice: once for the my_custom_grain
call itself and one for the main
call to its function:
# salt-call --local grains.items
local:
----------
<Snipped for brevity>
foo:
bar
<Snipped for brevity>
hello:
world
<Snipped for brevity>
my_grains:
----------
foo:
bar
hello:
world
PRECEDENCE
The core grains can be overridden to customize grains. Because there are several ways to define self grains, so they should keep in mind when defining the priorities in force. In the following order:
- Core grains.
- Custom grains in /etc/salt/grains.
- Custom grains in /etc/salt/minion.
- Custom grain modules in _grains directory, synced to minions.
Each subsequent will overwrite the previous, and therefore the core grains by the same name as any custom grain grains module definition, when synchronized to the minions covering the core grain. Similarly, from /etc/salt/minion
the core grains and grains overwrites custom module grains, and _grains
the grains will cover any grains of the same name.
For custom grains, if the function takes the parameter grains, the first to be rendered grains it will be passed. Because the rest of the grains can be rendered in any order, so the only grains can rely on the core grains. This is the 2019.2.0 release added.
EXAMPLES OF GRAINS
Grains package of core module is loaded by the place of major grains Data Salt minion, it provides an example of how to write a grains:
https://github.com/saltstack/salt/blob/develop/salt/grains/core.py
SYNCING GRAINS
Grains data synchronization can be accomplished in various ways, when calling state.highstate
they will be automatically synchronized, or (as described above) by calling saltutil.sync_grains
or saltutil.sync_all
synchronous and manually reload function.
Note: When grain_cache set to False when constructing grain dictionary memory and stored in the minion. Every minion restart or run
saltutil.refresh_grains
time, will be rebuilt from scratch grain dictionary.