Merge remote-tracking branch 'upstream/2015.5' into merge-forward-2015.8

Conflicts:
    salt/returners/local_cache.py
This commit is contained in:
Colton Myers 2016-01-29 14:57:31 -07:00
commit 84eeab7720
3 changed files with 96 additions and 16 deletions

View file

@ -6,6 +6,7 @@ from __future__ import absolute_import
import os.path
import logging
import salt.utils
log = logging.getLogger(__name__)
@ -14,26 +15,57 @@ __func_alias__ = {
}
def ls_():
def ls_(get_size=True):
'''
List SCSI devices, with details
CLI Example:
CLI Examples:
.. code-block:: bash
salt '*' scsi.ls
salt '*' scsi.ls get_size=False
get_size : True
Get the size information for scsi devices. This option
should be set to False for older OS distributions (RHEL6 and older)
due to lack of support for the '-s' option in lsscsi.
.. versionadded:: 2015.5.10
'''
cmd = 'lsscsi -dLsv'
if not salt.utils.which('lsscsi'):
__context__['retcode'] = 1
return 'scsi.ls not available - lsscsi command not found'
if get_size:
cmd = 'lsscsi -dLsv'
else:
cmd = 'lsscsi -dLv'
ret = {}
for line in __salt__['cmd.run'](cmd).splitlines():
res = __salt__['cmd.run_all'](cmd)
rc = res.get('retcode', -1)
if rc != 0:
__context__['retcode'] = rc
error = res.get('stderr', '').split('\n')[0]
if error == "lsscsi: invalid option -- 's'":
return '{0} - try get_size=False'.format(error)
return res.get('stderr', '').split('\n')[0]
data = res.get('stdout', '')
for line in data.splitlines():
if line.startswith('['):
mode = 'start'
size = None
major = None
minor = None
comps = line.strip().split()
key = comps[0]
size = comps.pop()
if get_size:
size = comps.pop()
majmin = comps.pop()
major, minor = majmin.replace('[', '').replace(']', '').split(':')
if majmin.startswith('['):
major, minor = majmin.replace('[', '').replace(']', '').split(':')
device = comps.pop()
model = ' '.join(comps[3:])
ret[key] = {

View file

@ -173,7 +173,7 @@ def returner(load):
)
def save_load(jid, clear_load, minions=None):
def save_load(jid, clear_load, minions=None, recurse_count=0):
'''
Save the load to the specified jid
@ -181,6 +181,11 @@ def save_load(jid, clear_load, minions=None):
the job, for cases when this function can't compute that list itself (such
as for salt-ssh)
'''
if recurse_count >= 5:
err = 'save_load could not write job cache file after {0} retries.'.format(recurse_count)
log.error(err)
raise salt.exceptions.SaltCacheError(err)
jid_dir = _jid_dir(jid)
serial = salt.payload.Serial(__opts__)
@ -203,6 +208,9 @@ def save_load(jid, clear_load, minions=None):
)
except IOError as exc:
log.warning('Could not write job invocation cache file: {0}'.format(exc))
time.sleep(0.1)
return save_load(jid=jid, clear_load=clear_load,
recurse_count=recurse_count+1)
# if you have a tgt, save that for the UI etc
if 'tgt' in clear_load:

View file

@ -21,10 +21,12 @@ ensure_in_syspath('../../')
# Import Salt Libs
from salt.modules import scsi
import os
import salt.utils
import copy
# Globals
scsi.__salt__ = {}
scsi.__context__ = {}
@skipIf(NO_MOCK, NO_MOCK_REASON)
@ -36,13 +38,51 @@ class ScsiTestCase(TestCase):
'''
Test for list SCSI devices, with details
'''
with patch.dict(scsi.__salt__,
{'cmd.run':
MagicMock(return_value='[A:a B:b C:c D:d]')}):
self.assertDictEqual(scsi.ls_(),
{'[A:a':
{'major': 'C', 'lun': 'A:a', 'device': 'B:b',
'model': '', 'minor': 'c', 'size': 'D:d]'}})
lsscsi = {
'stdout': '[0:0:0:0] disk HP LOGICAL VOLUME 6.68 /dev/sda [8:0]',
'stderr': '',
'retcode': 0
}
lsscsi_size = {
'stdout': '[0:0:0:0] disk HP LOGICAL VOLUME 6.68 /dev/sda [8:0] 1.20TB',
'stderr': '',
'retcode': 0
}
result = {
'[0:0:0:0]': {
'major': '8',
'lun': '0:0:0:0',
'device': '/dev/sda',
'model': 'LOGICAL VOLUME 6.68',
'minor': '0',
'size': None,
}
}
result_size = copy.deepcopy(result)
result_size['[0:0:0:0]']['size'] = '1.20TB'
mock = MagicMock(return_value='/usr/bin/lsscsi')
with patch.object(salt.utils, 'which', mock):
# get_size = True
cmd_mock = MagicMock(return_value=lsscsi_size)
with patch.dict(scsi.__salt__, {'cmd.run_all': cmd_mock}):
self.assertDictEqual(scsi.ls_(), result_size)
with patch.dict(lsscsi_size, {'retcode': 1, 'stderr': 'An error occurred'}):
self.assertEqual(scsi.ls_(), 'An error occurred')
with patch.dict(lsscsi_size, {'retcode': 1, 'stderr': "lsscsi: invalid option -- 's'\nUsage:"}):
self.assertEqual(scsi.ls_(), "lsscsi: invalid option -- 's' - try get_size=False")
# get_size = False
cmd_mock = MagicMock(return_value=lsscsi)
with patch.dict(scsi.__salt__, {'cmd.run_all': cmd_mock}):
self.assertDictEqual(scsi.ls_(get_size=False), result)
mock = MagicMock(return_value=None)
with patch.object(salt.utils, 'which', mock):
self.assertEqual(scsi.ls_(), 'scsi.ls not available - lsscsi command not found')
def test_rescan_all(self):
'''