123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- '''\
- Welcome to the Salt repl which exposes the execution environment of a minion in
- a pre-configured Python shell
- __opts__, __salt__, __grains__, and __pillar__ are available.
- Jinja can be tested with full access to the above structures in the usual way:
- JINJA("""\\
- I am {{ salt['cmd.run']('whoami') }}.
- {% if otherstuff %}
- Some other stuff here
- {% endif %}
- """, otherstuff=True)
- A history file is maintained in ~/.saltsh_history.
- completion behavior can be customized via the ~/.inputrc file.
- '''
- # pylint: disable=file-perms
- # Import python libs
- from __future__ import absolute_import
- import atexit
- import os
- import readline
- import sys
- from code import InteractiveConsole
- # Import salt libs
- import salt.client
- import salt.config
- import salt.loader
- import salt.output
- import salt.pillar
- import salt.runner
- # Import 3rd party libs
- import jinja2
- from salt.ext.six.moves import builtins # pylint: disable=import-error
- # pylint: disable=unused-import
- # These are imported to be available in the spawned shell
- import salt.utils.yaml
- import pprint
- # pylint: enable=unused-import
- HISTFILE = '{HOME}/.saltsh_history'.format(**os.environ)
- def savehist():
- '''
- Save the history file
- '''
- readline.write_history_file(HISTFILE)
- def get_salt_vars():
- '''
- Return all the Salt-usual double-under data structures for a minion
- '''
- # Create the Salt __opts__ variable
- __opts__ = salt.config.client_config(
- os.environ.get('SALT_MINION_CONFIG', '/etc/salt/minion'))
- # Populate grains if it hasn't been done already
- if 'grains' not in __opts__ or not __opts__['grains']:
- __opts__['grains'] = salt.loader.grains(__opts__)
- # file_roots and pillar_roots should be set in the minion config
- if 'file_client' not in __opts__ or not __opts__['file_client']:
- __opts__['file_client'] = 'local'
- # ensure we have a minion id
- if 'id' not in __opts__ or not __opts__['id']:
- __opts__['id'] = 'saltsh_mid'
- # Populate template variables
- __salt__ = salt.loader.minion_mods(__opts__)
- __grains__ = __opts__['grains']
- if __opts__['file_client'] == 'local':
- __pillar__ = salt.pillar.get_pillar(
- __opts__,
- __grains__,
- __opts__.get('id'),
- __opts__.get('saltenv'),
- ).compile_pillar()
- else:
- __pillar__ = {}
- JINJA = lambda x, **y: jinja2.Template(x).render( # pylint: disable=C0103,W0612
- grains=__grains__,
- salt=__salt__,
- opts=__opts__,
- pillar=__pillar__,
- **y)
- return locals()
- def main():
- '''
- The main entry point
- '''
- salt_vars = get_salt_vars()
- def salt_outputter(value):
- '''
- Use Salt's outputters to print values to the shell
- '''
- if value is not None:
- builtins._ = value
- salt.output.display_output(value, '', salt_vars['__opts__'])
- sys.displayhook = salt_outputter
- # Set maximum number of items that will be written to the history file
- readline.set_history_length(300)
- if os.path.exists(HISTFILE):
- readline.read_history_file(HISTFILE)
- atexit.register(savehist)
- atexit.register(lambda: sys.stdout.write('Salt you later!\n'))
- saltrepl = InteractiveConsole(locals=salt_vars)
- saltrepl.interact(banner=__doc__)
- if __name__ == '__main__':
- main()
|