Merge pull request #25238 from DSRCompany/pillarenv_backport_2015.5

Pillarenv backport 2015.5
This commit is contained in:
Thomas S Hatch 2015-07-09 19:25:07 -06:00
commit 0f82ac3e30
8 changed files with 140 additions and 44 deletions

View File

@ -87,6 +87,7 @@ VALID_OPTS = {
'failhard': bool,
'autoload_dynamic_modules': bool,
'environment': str,
'pillarenv': str,
'state_top': str,
'startup_states': str,
'sls_list': list,
@ -321,6 +322,7 @@ DEFAULT_MINION_OPTS = {
'failhard': False,
'autoload_dynamic_modules': True,
'environment': None,
'pillarenv': None,
'extension_modules': '',
'state_top': 'top.sls',
'startup_states': '',

View File

@ -1216,7 +1216,8 @@ class AESFuncs(object):
load['id'],
load.get('saltenv', load.get('env')),
ext=load.get('ext'),
pillar=load.get('pillar_override', {}))
pillar=load.get('pillar_override', {}),
pillarenv=load.get('pillarenv'))
data = pillar.compile_pillar(pillar_dirs=pillar_dirs)
self.fs_.update_opts()
if self.opts.get('minion_data_cache', False):

View File

@ -331,7 +331,8 @@ class SMinion(object):
self.opts,
self.opts['grains'],
self.opts['id'],
self.opts['environment']
self.opts['environment'],
pillarenv=self.opts.get('pillarenv'),
).compile_pillar()
self.functions = salt.loader.minion_mods(self.opts, include_errors=True)
# TODO: remove
@ -688,7 +689,8 @@ class Minion(MinionBase):
opts,
opts['grains'],
opts['id'],
opts['environment']
opts['environment'],
pillarenv=opts.get('pillarenv'),
).compile_pillar()
self.functions, self.returners, self.function_errors = self._load_modules()
self.serial = salt.payload.Serial(self.opts)
@ -1575,6 +1577,7 @@ class Minion(MinionBase):
self.opts['grains'],
self.opts['id'],
self.opts['environment'],
pillarenv=self.opts.get('pillarenv'),
).compile_pillar()
except SaltClientError:
# Do not exit if a pillar refresh fails.
@ -2931,7 +2934,8 @@ class ProxyMinion(Minion):
opts,
opts['grains'],
opts['id'],
opts['environment']
opts['environment'],
pillarenv=opts.get('pillarenv'),
).compile_pillar()
self.functions, self.returners, self.function_errors = self._load_modules()
self.serial = salt.payload.Serial(self.opts)

View File

@ -84,7 +84,7 @@ def _chroot_pids(chroot):
return pids
def _render_cmd(cmd, cwd, template, saltenv='base'):
def _render_cmd(cmd, cwd, template, saltenv='base', pillarenv=None, pillar_override=None):
'''
If template is a valid template engine, process the cmd and cwd through
that engine.
@ -101,7 +101,11 @@ def _render_cmd(cmd, cwd, template, saltenv='base'):
kwargs = {}
kwargs['salt'] = __salt__
kwargs['pillar'] = __pillar__
if pillarenv is not None or pillar_override is not None:
pillarenv = pillarenv or __opts__['pillarenv']
kwargs['pillar'] = _gather_pillar(pillarenv, pillar_override)
else:
kwargs['pillar'] = __pillar__
kwargs['grains'] = __grains__
kwargs['opts'] = __opts__
kwargs['saltenv'] = saltenv
@ -172,6 +176,24 @@ def _parse_env(env):
return env
def _gather_pillar(pillarenv, pillar_override):
'''
Whenever a state run starts, gather the pillar data fresh
'''
pillar = salt.pillar.get_pillar(
__opts__,
__grains__,
__opts__['id'],
__opts__['environment'],
pillar=pillar_override,
pillarenv=pillarenv
)
ret = pillar.compile_pillar()
if pillar_override and isinstance(pillar_override, dict):
ret.update(pillar_override)
return ret
def _run(cmd,
cwd=None,
stdin=None,
@ -191,6 +213,8 @@ def _run(cmd,
reset_system_locale=True,
ignore_retcode=False,
saltenv='base',
pillarenv=None,
pillar_override=None,
use_vt=False):
'''
Do the DRY thing and only call subprocess.Popen() once
@ -242,7 +266,7 @@ def _run(cmd,
cmd = 'Powershell -NonInteractive "{0}"'.format(cmd.replace('"', '\\"'))
# munge the cmd and cwd through the template
(cmd, cwd) = _render_cmd(cmd, cwd, template, saltenv)
(cmd, cwd) = _render_cmd(cmd, cwd, template, saltenv, pillarenv, pillar_override)
ret = {}
@ -504,7 +528,9 @@ def _run_quiet(cmd,
umask=None,
timeout=None,
reset_system_locale=True,
saltenv='base'):
saltenv='base',
pillarenv=None,
pillar_override=None):
'''
Helper for running commands quietly for minion startup
'''
@ -521,7 +547,9 @@ def _run_quiet(cmd,
umask=umask,
timeout=timeout,
reset_system_locale=reset_system_locale,
saltenv=saltenv)['stdout']
saltenv=saltenv,
pillarenv=pillarenv,
pillar_override=pillar_override)['stdout']
def _run_all_quiet(cmd,
@ -535,7 +563,9 @@ def _run_all_quiet(cmd,
umask=None,
timeout=None,
reset_system_locale=True,
saltenv='base'):
saltenv='base',
pillarenv=None,
pillar_override=None):
'''
Helper for running commands quietly for minion startup.
Returns a dict of return data
@ -552,7 +582,9 @@ def _run_all_quiet(cmd,
umask=umask,
timeout=timeout,
reset_system_locale=reset_system_locale,
saltenv=saltenv)
saltenv=saltenv,
pillarenv=pillarenv,
pillar_override=pillar_override)
def run(cmd,
@ -648,6 +680,8 @@ def run(cmd,
reset_system_locale=reset_system_locale,
ignore_retcode=ignore_retcode,
saltenv=saltenv,
pillarenv=kwargs.get('pillarenv'),
pillar_override=kwargs.get('pillar'),
use_vt=use_vt)
if 'pid' in ret and '__pub_jid' in kwargs:
@ -843,6 +877,8 @@ def run_stdout(cmd,
reset_system_locale=reset_system_locale,
ignore_retcode=ignore_retcode,
saltenv=saltenv,
pillarenv=kwargs.get('pillarenv'),
pillar_override=kwargs.get('pillar'),
use_vt=use_vt)
lvl = _check_loglevel(output_loglevel)
@ -927,7 +963,9 @@ def run_stderr(cmd,
reset_system_locale=reset_system_locale,
ignore_retcode=ignore_retcode,
use_vt=use_vt,
saltenv=saltenv)
saltenv=saltenv,
pillarenv=kwargs.get('pillarenv'),
pillar_override=kwargs.get('pillar'))
lvl = _check_loglevel(output_loglevel)
if lvl is not None:
@ -1011,6 +1049,8 @@ def run_all(cmd,
reset_system_locale=reset_system_locale,
ignore_retcode=ignore_retcode,
saltenv=saltenv,
pillarenv=kwargs.get('pillarenv'),
pillar_override=kwargs.get('pillar'),
use_vt=use_vt)
lvl = _check_loglevel(output_loglevel)
@ -1096,6 +1136,8 @@ def retcode(cmd,
reset_system_locale=reset_system_locale,
ignore_retcode=ignore_retcode,
saltenv=saltenv,
pillarenv=kwargs.get('pillarenv'),
pillar_override=kwargs.get('pillar'),
use_vt=use_vt)
lvl = _check_loglevel(output_loglevel)
@ -1218,6 +1260,9 @@ def script(source,
path = salt.utils.mkstemp(dir=cwd, suffix=os.path.splitext(source)[1])
if template:
if 'pillarenv' in kwargs or 'pillar' in kwargs:
pillarenv = kwargs.get('pillarenv', __opts__.get('pillarenv'))
kwargs['pillar'] = _gather_pillar(pillarenv, kwargs.get('pillar'))
fn_ = __salt__['cp.get_template'](source,
path,
template,
@ -1255,6 +1300,8 @@ def script(source,
timeout=timeout,
reset_system_locale=reset_system_locale,
saltenv=saltenv,
pillarenv=kwargs.get('pillarenv'),
pillar_override=kwargs.get('pillar'),
use_vt=use_vt)
_cleanup_tempfile(path)
return ret
@ -1305,17 +1352,6 @@ def script_retcode(source,
salt '*' cmd.script_retcode salt://scripts/runme.sh stdin='one\\ntwo\\nthree\\nfour\\nfive\\n'
'''
python_shell = _python_shell_default(python_shell,
kwargs.get('__pub_jid', ''))
if isinstance(__env__, string_types):
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' not '
'\'env\'. This functionality will be removed in Salt Boron.'
)
# Backwards compatibility
saltenv = __env__
return script(source=source,
args=args,
cwd=cwd,
@ -1328,6 +1364,7 @@ def script_retcode(source,
umask=umask,
timeout=timeout,
reset_system_locale=reset_system_locale,
__env__=__env__,
saltenv=saltenv,
output_loglevel=output_loglevel,
use_vt=use_vt,
@ -1519,6 +1556,8 @@ def run_chroot(root,
reset_system_locale=reset_system_locale,
ignore_retcode=ignore_retcode,
saltenv=saltenv,
pillarenv=kwargs.get('pillarenv'),
pillar=kwargs.get('pillar'),
use_vt=use_vt)
# Kill processes running in the chroot

View File

@ -29,6 +29,24 @@ def _auth():
return __context__['auth']
def _gather_pillar(pillarenv, pillar_override):
'''
Whenever a state run starts, gather the pillar data fresh
'''
pillar = salt.pillar.get_pillar(
__opts__,
__grains__,
__opts__['id'],
__opts__['environment'],
pillar=pillar_override,
pillarenv=pillarenv
)
ret = pillar.compile_pillar()
if pillar_override and isinstance(pillar_override, dict):
ret.update(pillar_override)
return ret
def recv(files, dest):
'''
Used with salt-cp, pass the files dict, and the destination.
@ -66,7 +84,7 @@ def _mk_client():
salt.fileclient.get_file_client(__opts__)
def _render_filenames(path, dest, saltenv, template):
def _render_filenames(path, dest, saltenv, template, **kw):
'''
Process markup in the :param:`path` and :param:`dest` variables (NOT the
files under the paths they ultimately point to) according to the markup
@ -84,7 +102,11 @@ def _render_filenames(path, dest, saltenv, template):
kwargs = {}
kwargs['salt'] = __salt__
kwargs['pillar'] = __pillar__
if 'pillarenv' in kw or 'pillar' in kw:
pillarenv = kw.get('pillarenv', __opts__.get('pillarenv'))
kwargs['pillar'] = _gather_pillar(pillarenv, kw.get('pillar'))
else:
kwargs['pillar'] = __pillar__
kwargs['grains'] = __grains__
kwargs['opts'] = __opts__
kwargs['saltenv'] = saltenv
@ -125,7 +147,8 @@ def get_file(path,
makedirs=False,
template=None,
gzip=None,
env=None):
env=None,
**kwargs):
'''
Used to get a single file from the salt master
@ -163,7 +186,7 @@ def get_file(path,
# Backwards compatibility
saltenv = env
(path, dest) = _render_filenames(path, dest, saltenv, template)
(path, dest) = _render_filenames(path, dest, saltenv, template, **kwargs)
if not hash_file(path, saltenv):
return ''
@ -222,7 +245,7 @@ def get_template(path,
**kwargs)
def get_dir(path, dest, saltenv='base', template=None, gzip=None, env=None):
def get_dir(path, dest, saltenv='base', template=None, gzip=None, env=None, **kwargs):
'''
Used to recursively copy a directory from the salt master
@ -243,7 +266,7 @@ def get_dir(path, dest, saltenv='base', template=None, gzip=None, env=None):
# Backwards compatibility
saltenv = env
(path, dest) = _render_filenames(path, dest, saltenv, template)
(path, dest) = _render_filenames(path, dest, saltenv, template, **kwargs)
_mk_client()
return __context__['cp.fileclient'].get_dir(path, dest, saltenv, gzip)

View File

@ -512,6 +512,9 @@ def highstate(test=None,
'Pillar data must be formatted as a dictionary'
)
if 'pillarenv' in kwargs:
opts['pillarenv'] = kwargs['pillarenv']
st_ = salt.state.HighState(opts, pillar, kwargs.get('__pub_jid'))
st_.push_active()
try:
@ -545,6 +548,7 @@ def sls(mods,
exclude=None,
queue=False,
env=None,
pillarenv=None,
**kwargs):
'''
Execute a set list of state files from an environment.
@ -572,6 +576,9 @@ def sls(mods,
Defaults to None. If no saltenv is specified, the minion config will
be checked for a saltenv and if found, it will be used. If none is found,
base will be used.
pillarenv : None
Specify a ``pillar_roots`` environment. By default all pillar environments
merged together will be used.
concurrent:
WARNING: This flag is potentially dangerous. It is designed
for use when multiple state runs can safely be run at the same
@ -601,10 +608,18 @@ def sls(mods,
# Backwards compatibility
saltenv = env
if not saltenv:
if __opts__.get('saltenv', None):
saltenv = __opts__['saltenv']
if __opts__.get('environment', None):
saltenv = __opts__['environment']
else:
saltenv = 'base'
else:
__opts__['environment'] = saltenv
if not pillarenv:
if __opts__.get('pillarenv', None):
pillarenv = __opts__['pillarenv']
else:
__opts__['pillarenv'] = pillarenv
if queue:
_wait(kwargs.get('__pub_jid'))
@ -849,6 +864,8 @@ def sls_id(
opts['test'] = True
else:
opts['test'] = __opts__.get('test', None)
if 'pillarenv' in kwargs:
opts['pillarenv'] = kwargs['pillarenv']
st_ = salt.state.HighState(opts)
if isinstance(mods, string_types):
split_mods = mods.split(',')
@ -911,6 +928,8 @@ def show_low_sls(mods,
opts['test'] = True
else:
opts['test'] = __opts__.get('test', None)
if 'pillarenv' in kwargs:
opts['pillarenv'] = kwargs['pillarenv']
st_ = salt.state.HighState(opts)
if isinstance(mods, string_types):
mods = mods.split(',')
@ -972,6 +991,9 @@ def show_sls(mods, saltenv='base', test=None, queue=False, env=None, **kwargs):
'Pillar data must be formatted as a dictionary'
)
if 'pillarenv' in kwargs:
opts['pillarenv'] = kwargs['pillarenv']
st_ = salt.state.HighState(opts, pillar)
if isinstance(mods, string_types):
mods = mods.split(',')

View File

@ -28,7 +28,7 @@ log = logging.getLogger(__name__)
def get_pillar(opts, grains, id_, saltenv=None, ext=None, env=None, funcs=None,
pillar=None):
pillar=None, pillarenv=None):
'''
Return the correct pillar driver based on the file_client option
'''
@ -45,7 +45,7 @@ def get_pillar(opts, grains, id_, saltenv=None, ext=None, env=None, funcs=None,
'local': Pillar
}.get(opts['file_client'], Pillar)
return ptype(opts, grains, id_, saltenv, ext, functions=funcs,
pillar=pillar)
pillar=pillar, pillarenv=pillarenv)
class RemotePillar(object):
@ -53,13 +53,14 @@ class RemotePillar(object):
Get the pillar from the master
'''
def __init__(self, opts, grains, id_, saltenv, ext=None, functions=None,
pillar=None):
pillar=None, pillarenv=None):
self.opts = opts
self.opts['environment'] = saltenv
self.ext = ext
self.grains = grains
self.id_ = id_
self.channel = salt.transport.Channel.factory(opts)
self.opts['pillarenv'] = pillarenv
self.pillar_override = {}
if pillar is not None:
if isinstance(pillar, dict):
@ -74,6 +75,7 @@ class RemotePillar(object):
load = {'id': self.id_,
'grains': self.grains,
'saltenv': self.opts['environment'],
'pillarenv': self.opts['pillarenv'],
'pillar_override': self.pillar_override,
'ver': '2',
'cmd': '_pillar'}
@ -97,11 +99,11 @@ class Pillar(object):
Read over the pillar top files and render the pillar data
'''
def __init__(self, opts, grains, id_, saltenv, ext=None, functions=None,
pillar=None):
pillar=None, pillarenv=None):
# Store the file_roots path so we can restore later. Issue 5449
self.actual_file_roots = opts['file_roots']
# use the local file client
self.opts = self.__gen_opts(opts, grains, id_, saltenv, ext)
self.opts = self.__gen_opts(opts, grains, id_, saltenv=saltenv, ext=ext, pillarenv=pillarenv)
self.client = salt.fileclient.get_file_client(self.opts, True)
if opts.get('file_client', '') == 'local':
@ -145,7 +147,7 @@ class Pillar(object):
return {}
return ext
def __gen_opts(self, opts_in, grains, id_, saltenv=None, ext=None, env=None):
def __gen_opts(self, opts_in, grains, id_, saltenv=None, ext=None, env=None, pillarenv=None):
'''
The options need to be altered to conform to the file client
'''
@ -168,6 +170,8 @@ class Pillar(object):
opts['id'] = id_
if 'environment' not in opts:
opts['environment'] = saltenv
if 'pillarenv' not in opts:
opts['pillarenv'] = pillarenv
if opts['state_top'].startswith('salt://'):
opts['state_top'] = opts['state_top']
elif opts['state_top'].startswith('/'):
@ -200,16 +204,16 @@ class Pillar(object):
errors = []
# Gather initial top files
try:
if self.opts['environment']:
tops[self.opts['environment']] = [
if self.opts['pillarenv']:
tops[self.opts['pillarenv']] = [
compile_template(
self.client.cache_file(
self.opts['state_top'],
self.opts['environment']
self.opts['pillarenv']
),
self.rend,
self.opts['renderer'],
self.opts['environment'],
self.opts['pillarenv'],
_pillar_rend=True
)
]
@ -343,8 +347,8 @@ class Pillar(object):
'''
matches = {}
for saltenv, body in top.items():
if self.opts['environment']:
if saltenv != self.opts['environment']:
if self.opts['pillarenv']:
if saltenv != self.opts['pillarenv']:
continue
for match, data in body.items():
if self.matcher.confirm_top(

View File

@ -595,7 +595,8 @@ class State(object):
self.opts['grains'],
self.opts['id'],
self.opts['environment'],
pillar=self._pillar_override
pillar=self._pillar_override,
pillarenv=self.opts.get('pillarenv')
)
ret = pillar.compile_pillar()
if self._pillar_override and isinstance(self._pillar_override, dict):