Merge pull request #48555 from Ch3LL/ssh_id

Fix state.sls_id not running on ssh minion
This commit is contained in:
Nicole Thomas 2018-07-16 09:24:41 -04:00 committed by GitHub
commit 61572b6780
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 22 deletions

View File

@ -32,6 +32,60 @@ __func_alias__ = {
log = logging.getLogger(__name__)
def _ssh_state(chunks, __opts__, __context__, __pillar__, __salt__, st_kwargs,
kwargs, test=False):
'''
funciton to run a state with the given chunk via salt-ssh
'''
file_refs = salt.client.ssh.state.lowstate_file_refs(
chunks,
_merge_extra_filerefs(
kwargs.get('extra_filerefs', ''),
__opts__.get('extra_filerefs', '')
)
)
# Create the tar containing the state pkg and relevant files.
trans_tar = salt.client.ssh.state.prep_trans_tar(
__opts__,
__context__['fileclient'],
chunks,
file_refs,
__pillar__,
st_kwargs['id_'])
trans_tar_sum = salt.utils.get_hash(trans_tar, __opts__['hash_type'])
cmd = 'state.pkg {0}/salt_state.tgz test={1} pkg_sum={2} hash_type={3}'.format(
__opts__['thin_dir'],
test,
trans_tar_sum,
__opts__['hash_type'])
single = salt.client.ssh.Single(
__opts__,
cmd,
fsclient=__context__['fileclient'],
minion_opts=__salt__.minion_opts,
**st_kwargs)
single.shell.send(
trans_tar,
'{0}/salt_state.tgz'.format(__opts__['thin_dir']))
stdout, stderr, _ = single.cmd_block()
# Clean up our tar
try:
os.remove(trans_tar)
except (OSError, IOError):
pass
# Read in the JSON data and return the data structure
try:
return json.loads(stdout, object_hook=salt.utils.decode_dict)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(str(e))
# If for some reason the json load fails, return the stdout
return stdout
def _set_retcode(ret, highstate=None):
'''
Set the return code based on the data back from the state system
@ -835,6 +889,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
salt '*' state.sls_id my_state my_module,a_common_module
'''
st_kwargs = __salt__.kwargs
conflict = _check_queue(queue, kwargs)
if conflict is not None:
return conflict
@ -847,13 +902,11 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
if opts['environment'] is None:
opts['environment'] = 'base'
try:
st_ = salt.state.HighState(opts,
proxy=__proxy__,
initial_pillar=_get_initial_pillar(opts))
except NameError:
st_ = salt.state.HighState(opts,
initial_pillar=_get_initial_pillar(opts))
st_ = salt.client.ssh.state.SSHHighState(
__opts__,
__pillar__,
__salt__,
__context__['fileclient'])
if not _check_pillar(kwargs, st_.opts['pillar']):
__context__['retcode'] = 5
@ -864,10 +917,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
if isinstance(mods, six.string_types):
split_mods = mods.split(',')
st_.push_active()
try:
high_, errors = st_.render_highstate({opts['environment']: split_mods})
finally:
st_.pop_active()
high_, errors = st_.render_highstate({opts['environment']: split_mods})
errors += st_.state.verify_high(high_)
# Apply requisites to high data
high_, req_in_errors = st_.state.requisite_in(high_)
@ -879,20 +929,26 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
__context__['retcode'] = 1
return errors
chunks = st_.state.compile_high_data(high_)
ret = {}
for chunk in chunks:
if chunk.get('__id__', '') == id_:
ret.update(st_.state.call_chunk(chunk, {}, chunks))
chunk = [x for x in chunks if x.get('__id__', '') == id_]
_set_retcode(ret, highstate=highstate)
# Work around Windows multiprocessing bug, set __opts__['test'] back to
# value from before this function was run.
__opts__['test'] = orig_test
if not ret:
if not chunk:
raise SaltInvocationError(
'No matches for ID \'{0}\' found in SLS \'{1}\' within saltenv '
'\'{2}\''.format(id_, mods, opts['environment'])
)
ret = _ssh_state(chunk,
__opts__,
__context__,
__pillar__,
__salt__,
st_kwargs,
kwargs,
test=test)
_set_retcode(ret, highstate=highstate)
# Work around Windows multiprocessing bug, set __opts__['test'] back to
# value from before this function was run.
__opts__['test'] = orig_test
return ret

View File

@ -3,3 +3,7 @@ ssh-file-test:
file.managed:
- name: /tmp/{{ jinja }}
- contents: 'test'
second_id:
cmd.run:
- name: echo test

View File

@ -24,9 +24,12 @@ class SSHStateTest(SSHCase):
'''
testing the state system with salt-ssh
'''
def _check_dict_ret(self, ret, val, exp_ret):
def _check_dict_ret(self, ret, val, exp_ret, equal=True):
for key, value in ret.items():
self.assertEqual(value[val], exp_ret)
if equal:
self.assertEqual(value[val], exp_ret)
else:
self.assertNotEqual(value[val], exp_ret)
def _check_request(self, empty=False):
check = self.run_function('state.check_request', wipe=False)
@ -50,12 +53,31 @@ class SSHStateTest(SSHCase):
'''
test state.sls_id with salt-ssh
'''
# check state.sls_id with test=True
ret = self.run_function('state.sls_id', ['ssh-file-test', SSH_SLS,
'test=True'])
self._check_dict_ret(ret=ret, val='comment',
exp_ret='The file /tmp/test is set to be changed')
# check state.sls_id without test=True
ret = self.run_function('state.sls_id', ['ssh-file-test', SSH_SLS])
self._check_dict_ret(ret=ret, val='__sls__', exp_ret=SSH_SLS)
# make sure the other id in the state was not run
self._check_dict_ret(ret=ret, val='__id__',
exp_ret='second_id', equal=False)
check_file = self.run_function('file.file_exists', ['/tmp/test'])
self.assertTrue(check_file)
def test_state_sls_wrong_id(self):
'''
test state.sls_id when id does not exist
'''
# check state.sls_id with test=True
ret = self.run_function('state.sls_id', ['doesnotexist', SSH_SLS])
assert 'No matches for ID' in ret
def test_state_show_sls(self):
'''
test state.show_sls with salt-ssh