"""
LsSCSI - command ``/usr/bin/lsscsi``
====================================
This module provides processing for the output of the ``/usr/bin/lsscsi`` command.
"""
from insights.core import CommandParser
from insights.core.exceptions import ParseException
from insights.core.plugins import parser
from insights.specs import Specs
[docs]
@parser(Specs.lsscsi)
class LsSCSI(CommandParser):
"""
This parser reads the output of ``/usr/bin/lsscsi`` into a list of dictionarys.
Each item is a dictionary with six keys:
* ``HCTL`` - the scsi_host,channel,target_number,LUN tuple
* ``Peripheral-Type`` - the SCSI peripheral type
* ``Vendor`` - the vendor name
* ``Model`` - the model name
* ``Revision`` - the revision string
* ``Primary-Device-Node`` - the primary device node name
Attributes:
data (list of dict): List of the input lines, where each line is a dictionary having the keys identified above.
Parsing refers to http://sg.danny.cz/scsi/lsscsi.html.
Sample input::
[1:0:0:0] storage IET Controller 0001 -
[1:0:0:1] cd/dvd QEMU QEMU DVD-ROM 2.5+ /dev/sr0
[1:0:0:2] disk IET VIRTUAL-DISK 0001 /dev/sdb
[3:0:5:0] tape HP C5713A H910 /dev/st0
Examples:
>>> lsscsi[0] == {'Model': 'Controller', 'Vendor': 'IET', 'HCTL': '[1:0:0:0]', 'Peripheral-Type': 'storage', 'Primary-Device-Node': '-', 'Revision': '0001'}
True
>>> lsscsi.device_nodes
['-', '/dev/sr0', '/dev/sdb', '/dev/st0']
>>> len(lsscsi.data)
4
>>> lsscsi[1]['Peripheral-Type']
'cd/dvd'
"""
[docs]
def parse_content(self, content):
if len(content) == 0:
raise ParseException("Empty content of command output.")
LSSCSI_TABLE_HEADER_ITEMS = ['HCTL', 'Peripheral-Type', 'Vendor', 'Model', 'Revision', 'Primary-Device-Node']
LEN = len(LSSCSI_TABLE_HEADER_ITEMS)
col_index = []
pre_col_index = []
# Try to find the index of a proper six column line.
# If col_index can't be found in the above proper way,
# set it by squeezing redundant items to 'Model' column as a workaround.
for l in content:
col_split = l.strip().split()
if len(col_split) < LEN:
break
elif len(col_split) == LEN:
col_index = [l.index(c) for c in col_split]
break
elif not pre_col_index and len(col_split) > LEN:
unfixed_index = [l.index(c) for c in col_split]
forth_str = l.split(col_split[2], 1)[-1].strip()
pre_col_index = unfixed_index[:3] + [l.index(forth_str)] + unfixed_index[-2:]
if not col_index and pre_col_index:
col_index = pre_col_index
if len(col_index) != LEN:
raise ParseException("Invalid format of content, unparsable.")
self.data = []
for line in content:
col_data = dict((LSSCSI_TABLE_HEADER_ITEMS[i],
line[col_index[i]:col_index[i + 1]].strip())
for i in range(LEN - 1))
col_data[LSSCSI_TABLE_HEADER_ITEMS[-1]] = line[col_index[-1]:].strip()
self.data.append(col_data)
def __getitem__(self, idx):
return self.data[idx]
@property
def device_nodes(self):
"""
list: All lines' Primary-Device-Node values.
"""
return [v['Primary-Device-Node'] for v in self.data]
@property
def device_vendors(self):
"""
list: All lines' Vendor values
"""
return [v['Vendor'] for v in self.data]