diff --git a/doc/topics/targeting/grains.rst b/doc/topics/targeting/grains.rst index e98662e783..352d4a4a53 100644 --- a/doc/topics/targeting/grains.rst +++ b/doc/topics/targeting/grains.rst @@ -205,15 +205,15 @@ defining custom grains, there is an order of precedence which should be kept in mind when defining them. The order of evaluation is as follows: 1. Core grains. -2. Custom grains in ``/etc/salt/grains``. -3. Custom grains in ``/etc/salt/minion``. -4. Custom grain modules in ``_grains`` directory, synced to minions. +2. Custom grain modules in ``_grains`` directory, synced to minions. +3. Custom grains in ``/etc/salt/grains``. +4. Custom grains in ``/etc/salt/minion``. Each successive evaluation overrides the previous ones, so any grains defined -in ``/etc/salt/grains`` that have the same name as a core grain will override -that core grain. Similarly, ``/etc/salt/minion`` overrides both core grains and -grains set in ``/etc/salt/grains``, and custom grain modules will override -*any* grains of the same name. +by custom grains modules synced to minions that have the same name as a core +grain will override that core grain. Similarly, grains from +``/etc/salt/grains`` override both core grains and custom grain modules, and +grains in ``/etc/salt/minion`` will override *any* grains of the same name. Examples of Grains diff --git a/salt/loader.py b/salt/loader.py index 80bca2e982..02af51d3e4 100644 --- a/salt/loader.py +++ b/salt/loader.py @@ -18,6 +18,7 @@ from collections import MutableMapping from salt.exceptions import LoaderError from salt.template import check_render_pipe_str from salt.utils.decorators import Depends +from salt.utils.odict import OrderedDict # Solve the Chicken and egg problem where grains need to run before any # of the modules are loaded and are generally available for any usage. @@ -714,7 +715,7 @@ class Loader(object): ''' Return a dict of functions found in the defined module_dirs ''' - funcs = {} + funcs = OrderedDict() self.load_modules() for mod in self.modules: # If this is a proxy minion then MOST modules cannot work. Therefore, require that @@ -824,7 +825,7 @@ class Loader(object): self.modules = [] log.trace('loading {0} in {1}'.format(self.tag, self.module_dirs)) - names = {} + names = OrderedDict() disable = set(self.opts.get('disable_{0}s'.format(self.tag), [])) cython_enabled = False @@ -1238,15 +1239,6 @@ class Loader(object): grains_data = {} funcs = self.gen_functions() for key, fun in funcs.items(): - if not key.startswith('core.'): - continue - ret = fun() - if not isinstance(ret, dict): - continue - grains_data.update(ret) - for key, fun in funcs.items(): - if key.startswith('core.'): - continue try: ret = fun() except Exception: @@ -1260,7 +1252,10 @@ class Loader(object): continue if not isinstance(ret, dict): continue - grains_data.update(ret) + # The OrderedDict of funcs has core grains at the end. So earlier + # grains are the ones which should override + ret.update(grains_data) + grains_data = ret # Write cache if enabled if self.opts.get('grains_cache', False): cumask = os.umask(077)