Merge branch 'develop' into win_fix_integration_tests

This commit is contained in:
Nicole Thomas 2017-12-07 10:31:09 -05:00 committed by GitHub
commit becb75a9ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 112 additions and 39 deletions

View File

@ -176,8 +176,9 @@ def _query(function,
if result.get('status', None) == salt.ext.six.moves.http_client.OK: if result.get('status', None) == salt.ext.six.moves.http_client.OK:
response = hipchat_functions.get(api_version).get(function).get('response') response = hipchat_functions.get(api_version).get(function).get('response')
return result.get('dict', {}).get(response, None) return result.get('dict', {}).get(response, None)
elif result.get('status', None) == salt.ext.six.moves.http_client.NO_CONTENT: elif result.get('status', None) == salt.ext.six.moves.http_client.NO_CONTENT and \
return False api_version == 'v2':
return True
else: else:
log.debug(url) log.debug(url)
log.debug(query_params) log.debug(query_params)

View File

@ -166,6 +166,98 @@ def _snapper_post(opts, jid, pre_num):
log.error('Failed to create snapper pre snapshot for jid: {0}'.format(jid)) log.error('Failed to create snapper pre snapshot for jid: {0}'.format(jid))
def _get_pause(jid, state_id=None):
'''
Return the pause information for a given jid
'''
pause_dir = os.path.join(__opts__[u'cachedir'], 'state_pause')
pause_path = os.path.join(pause_dir, jid)
if not os.path.exists(pause_dir):
try:
os.makedirs(pause_dir)
except OSError:
# File created in the gap
pass
data = {}
if state_id is not None:
if state_id not in data:
data[state_id] = {}
if os.path.exists(pause_path):
with salt.utils.files.fopen(pause_path, 'rb') as fp_:
data = msgpack.loads(fp_.read())
return data, pause_path
def get_pauses(jid=None):
'''
Get a report on all of the currently paused state runs and pause
run settings.
Optionally send in a jid if you only desire to see a single pause
data set.
'''
ret = {}
active = __salt__['saltutil.is_running']('state.*')
pause_dir = os.path.join(__opts__[u'cachedir'], 'state_pause')
if not os.path.exists(pause_dir):
return ret
if jid is None:
jids = os.listdir(pause_dir)
elif isinstance(jid, list):
jids = jid
else:
jids = [str(jid)]
for scan_jid in jids:
is_active = False
for active_data in active:
if active_data['jid'] == scan_jid:
is_active = True
if not is_active:
try:
pause_path = os.path.join(pause_dir, scan_jid)
os.remove(pause_path)
except OSError:
# Already gone
pass
continue
data, pause_path = _get_pause(scan_jid)
ret[scan_jid] = data
return ret
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 begining of the next state run.
The given state id is the id got a given state execution, so given a state
that looks like this:
.. code-block:: yaml
vim:
pkg.installed: []
The state_id to pass to `soft_kill` is `vim`
CLI Examples:
.. code-block:: bash
salt '*' state.soft_kill 20171130110407769519
salt '*' state.soft_kill 20171130110407769519 vim
'''
jid = str(jid)
if state_id is None:
state_id = '__all__'
data, pause_path = _get_pause(jid, state_id)
data[state_id]['kill'] = True
with salt.utils.files.fopen(pause_path, 'wb') as fp_:
fp_.write(msgpack.dumps(data))
def pause(jid, state_id=None, 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 Set up a state id pause, this instructs a running state to pause at a given
@ -194,20 +286,7 @@ def pause(jid, state_id=None, duration=None):
jid = str(jid) jid = str(jid)
if state_id is None: if state_id is None:
state_id = '__all__' state_id = '__all__'
pause_dir = os.path.join(__opts__[u'cachedir'], 'state_pause') data, pause_path = _get_pause(jid, state_id)
pause_path = os.path.join(pause_dir, jid)
if not os.path.exists(pause_dir):
try:
os.makedirs(pause_dir)
except OSError:
# File created in the gap
pass
data = {}
if os.path.exists(pause_path):
with salt.utils.files.fopen(pause_path, 'rb') as fp_:
data = msgpack.loads(fp_.read())
if state_id not in data:
data[state_id] = {}
if duration: if duration:
data[state_id]['duration'] = int(duration) data[state_id]['duration'] = int(duration)
with salt.utils.files.fopen(pause_path, 'wb') as fp_: with salt.utils.files.fopen(pause_path, 'wb') as fp_:
@ -239,22 +318,11 @@ def resume(jid, state_id=None):
jid = str(jid) jid = str(jid)
if state_id is None: if state_id is None:
state_id = '__all__' state_id = '__all__'
pause_dir = os.path.join(__opts__[u'cachedir'], 'state_pause') data, pause_path = _get_pause(jid, state_id)
pause_path = os.path.join(pause_dir, jid)
if not os.path.exists(pause_dir):
try:
os.makedirs(pause_dir)
except OSError:
# File created in the gap
pass
data = {}
if os.path.exists(pause_path):
with salt.utils.files.fopen(pause_path, 'rb') as fp_:
data = msgpack.loads(fp_.read())
else:
return True
if state_id in data: if state_id in data:
data.pop(state_id) data.pop(state_id)
if state_id == '__all__':
data = {}
with salt.utils.files.fopen(pause_path, 'wb') as fp_: with salt.utils.files.fopen(pause_path, 'wb') as fp_:
fp_.write(msgpack.dumps(data)) fp_.write(msgpack.dumps(data))

View File

@ -1925,8 +1925,6 @@ class State(object):
if self.mocked: if self.mocked:
ret = mock_ret(cdata) ret = mock_ret(cdata)
else: else:
# Check if this low chunk is paused
self.check_pause(low)
# Execute the state function # Execute the state function
if not low.get(u'__prereq__') and low.get(u'parallel'): if not low.get(u'__prereq__') and low.get(u'parallel'):
# run the state call in parallel, but only if not in a prereq # run the state call in parallel, but only if not in a prereq
@ -2112,6 +2110,10 @@ class State(object):
return running return running
tag = _gen_tag(low) tag = _gen_tag(low)
if tag not in running: if tag not in running:
# Check if this low chunk is paused
action = self.check_pause(low)
if action == u'kill':
break
running = self.call_chunk(low, running, chunks) running = self.call_chunk(low, running, chunks)
if self.check_failhard(low, running): if self.check_failhard(low, running):
return running return running
@ -2170,13 +2172,16 @@ class State(object):
if u'duration' in pdat[key]: if u'duration' in pdat[key]:
now = time.time() now = time.time()
if now - start > pdat[key][u'duration']: if now - start > pdat[key][u'duration']:
return return u'run'
if u'kill' in pdat[key]:
return u'kill'
else: else:
return return u'run'
time.sleep(1) time.sleep(1)
except Exception as exc: except Exception as exc:
log.error('Failed to read in pause data for file located at: %s', pause_path) log.error('Failed to read in pause data for file located at: %s', pause_path)
return return u'run'
return u'run'
def reconcile_procs(self, running): def reconcile_procs(self, running):
''' '''

View File

@ -287,7 +287,8 @@ def present(name=None,
if not table_exists: if not table_exists:
if __opts__['test']: if __opts__['test']:
ret['result'] = None ret['result'] = None
comments.append('DynamoDB table {0} is set to be created.'.format(name)) ret['comment'] = 'DynamoDB table {0} would be created.'.format(name)
return ret
else: else:
is_created = __salt__['boto_dynamodb.create_table']( is_created = __salt__['boto_dynamodb.create_table'](
name, name,

View File

@ -56,9 +56,7 @@ class BotoDynamodbTestCase(TestCase, LoaderModuleMockMixin):
self.assertDictEqual(boto_dynamodb.present(name), ret) self.assertDictEqual(boto_dynamodb.present(name), ret)
with patch.dict(boto_dynamodb.__opts__, {'test': True}): with patch.dict(boto_dynamodb.__opts__, {'test': True}):
comt = ('DynamoDB table {0} is set to be created.,\n' comt = ('DynamoDB table {0} would be created.'.format(name))
'DynamoDB table {0} throughput matches,\n'
'All global secondary indexes match,\n'.format(name))
ret.update({'comment': comt, 'result': None}) ret.update({'comment': comt, 'result': None})
self.assertDictEqual(boto_dynamodb.present(name), ret) self.assertDictEqual(boto_dynamodb.present(name), ret)