Fix lsscsi issues for certain platforms

The lsscsi command doesn't support the '-s' flag on any RHEL/CentOs system
until RHEL7.

The command now have an option to specify 'get_size' to enable
compatibility with the older platforms.

Also fixes some issues with lsscsi not being installed and exceptions
getting thrown because of that.
This commit is contained in:
Steve Hajducko 2016-01-22 21:46:03 -08:00
parent 516919525a
commit 3544dd995e
2 changed files with 87 additions and 15 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

@ -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):
'''