Some fixes to the set_pause and rm_pause function in the state runner, renaming to in line with the functions in the state module. Including aliases to previous names for back-ward compatibility. Including a soft_kill function to kill running orchestration states. A new test to test soft_kill functionality.

This commit is contained in:
Gareth J. Greenaway 2018-05-31 12:01:39 -07:00 committed by rallytime
parent 9aada36c1c
commit 4b0ff496fa
No known key found for this signature in database
GPG key ID: E8F1A4B90D0DEA19
2 changed files with 84 additions and 4 deletions

View file

@ -15,22 +15,38 @@ from salt.exceptions import SaltInvocationError
LOGGER = logging.getLogger(__name__)
def set_pause(jid, state_id, duration=None):
def pause(jid, state_id=None, duration=None):
'''
Set up a state id pause, this instructs a running state to pause at a given
state id. This needs to pass in the jid of the running state and can
optionally pass in a duration in seconds.
'''
minion = salt.minion.MasterMinion(__opts__)
minion['state.set_pause'](jid, state_id, duration)
minion.functions['state.pause'](jid, state_id, duration)
set_pause = salt.utils.functools.alias_function(pause, 'pause')
def rm_pause(jid, state_id, duration=None):
def resume(jid, state_id=None):
'''
Remove a pause from a jid, allowing it to continue
'''
minion = salt.minion.MasterMinion(__opts__)
minion['state.rm_pause'](jid, state_id)
minion.functions['state.resume'](jid, state_id)
rm_pause = salt.utils.functools.alias_function(resume, 'rm_pause')
def soft_kill(jid, state_id=None):
'''
Set up a state run to die before executing the given state id,
this instructs a running state to safely exit at a given
state id. This needs to pass in the jid of the running state.
If a state_id is not passed then the jid referenced will be safely exited
at the beginning of the next state run.
'''
minion = salt.minion.MasterMinion(__opts__)
minion.functions['state.soft_kill'](jid, state_id)
def orchestrate(mods,

View file

@ -21,6 +21,7 @@ from tests.support.case import ShellCase
from tests.support.unit import skipIf
from tests.support.paths import TMP
from tests.support.helpers import flaky
from tests.support.mock import MagicMock, patch
# Import Salt Libs
import salt.utils.platform
@ -450,3 +451,66 @@ class OrchEventTest(ShellCase):
self.assertTrue(received)
del listener
signal.alarm(0)
def test_orchestration_soft_kill(self):
'''
Test to confirm that the parallel state requisite works in orch
we do this by running 10 test.sleep's of 10 seconds, and insure it only takes roughly 10s
'''
self.write_conf({
'fileserver_backend': ['roots'],
'file_roots': {
'base': [self.base_env],
},
})
orch_sls = os.path.join(self.base_env, 'two_stage_orch_kill.sls')
with salt.utils.files.fopen(orch_sls, 'w') as fp_:
fp_.write(textwrap.dedent('''
stage_one:
test.succeed_without_changes
stage_two:
test.fail_without_changes
'''))
listener = salt.utils.event.get_event(
'master',
sock_dir=self.master_opts['sock_dir'],
transport=self.master_opts['transport'],
opts=self.master_opts)
mock_jid = '20131219120000000000'
self.run_run('state.soft_kill {0} stage_two'.format(mock_jid))
with patch('salt.utils.jid.gen_jid', MagicMock(return_value=mock_jid)):
jid = self.run_run_plus(
'state.orchestrate',
'two_stage_orch_kill',
__reload_config=True).get('jid')
if jid is None:
raise Exception('jid missing from run_run_plus output')
signal.signal(signal.SIGALRM, self.alarm_handler)
signal.alarm(self.timeout)
received = False
try:
while True:
event = listener.get_event(full=True)
if event is None:
continue
# Ensure that stage_two of the state does not run
if event['tag'] == 'salt/run/{0}/ret'.format(jid):
received = True
# Don't wrap this in a try/except. We want to know if the
# data structure is different from what we expect!
ret = event['data']['return']['data']['master']
self.assertNotIn('test_|-stage_two_|-stage_two_|-fail_without_changes', ret)
break
finally:
self.assertTrue(received)
del listener
signal.alarm(0)