Search code examples
pythonsalt-project

Salt custom grains


I am trying to write custom grains. I put this code in /etc/salt/grains

#!/usr/bin/env python
def function():
    grains = {}
    grains['test'] = "test"
    return grains

and to test it I created this script:

import salt.config
import salt.loader
__opts__ = salt.config.minion_config('/etc/salt/minion')
__grains__ = salt.loader.grains(__opts__)
test = __grains__['test']
print test

I've got this error:

dirs = __grains__['test']
KeyError: 'test'

What's wrong with this ?


Solution

  • /etc/salt/grains is where salt stores grains set by salt targetid grains.setval and friends. It is a flat, static yaml file.

    Custom grains via python go in /srv/salt/_grains, and are then synced to minions with salt \* saltutil.sync_grains. This is where you should put your python script.

    Here is an example similar to your code with logging and verification:

    $ cat /srv/salt/_grains/spam.py 
    #!/usr/bin/env python
    import logging
    log = logging.getLogger(__name__)
    
    def function():
        log.trace('Setting grains["spam"] to "eggs"')
        grains = {}
        grains['spam'] = "eggs"
        return grains
    
    $ sudo salt lead saltutil.sync_grains
    lead:
        - grains.spam
    
    $ sudo salt-call grains.item spam -l trace 2>&1 \
      | egrep '^local|spam'
    [TRACE   ] Added spam.function to grain
    [TRACE   ] Setting grains["spam"] to "eggs"
    local:
      spam: eggs
    
    $ cat /tmp/spam_taster.py 
    #!/usr/bin/env python
    import salt.config
    import salt.loader
    __opts__ = salt.config.minion_config('/etc/salt/minion')
    __grains__ = salt.loader.grains(__opts__)
    spam = __grains__['spam']
    print spam
    
    $ python /tmp/spam_taster.py 
    eggs