Fixed HP raid parser when disks are in JBOD

The function parsing the RAID logical volumes in the HP module did not
manage the case where disks were set in JBOD mode, thus having no RAID
array set.

This patch fixes this by checking if arrays are defined on pdisks before
parsing the logical disks.

Also added returncode read when executing the RAID related commands to
raise a more precise error.
This commit is contained in:
Christophe Simon 2022-03-11 15:55:07 +01:00
parent b53dfa9b59
commit ad951b9288
3 changed files with 66 additions and 14 deletions

View file

@ -7,10 +7,26 @@ import re
REGEXP_CONTROLLER_HP = re.compile(r'Smart Array ([a-zA-Z0-9- ]+) in Slot ([0-9]+)')
class HPRaidControllerError(Exception):
pass
def ssacli(command):
output = subprocess.getoutput('ssacli {}'.format(command) )
lines = output.split('\n')
def ssacli(sub_command):
command = ["ssacli"]
command.extend(sub_command.split())
p = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
)
p.wait()
stdout = p.stdout.read().decode("utf-8")
if p.returncode != 0:
mesg = "Failed to execute command '{}':\n{}".format(
" ".join(command), stdout
)
raise HPRaidControllerError(mesg)
lines = stdout.split('\n')
lines = list(filter(None, lines))
return lines
@ -92,8 +108,10 @@ class HPRaidController(RaidController):
self.controller_name = controller_name
self.data = data
self.pdrives = self._get_physical_disks()
self.ldrives = self._get_logical_drives()
self._get_virtual_drives_map()
arrays = [d['Array'] for d in self.pdrives.values() if d.get('Array')]
if arrays:
self.ldrives = self._get_logical_drives()
self._get_virtual_drives_map()
def get_product_name(self):
return self.controller_name
@ -135,6 +153,7 @@ class HPRaidController(RaidController):
'Type': 'SSD' if attrs.get('Interface Type') == 'Solid State SATA'
else 'HDD',
'_src': self.__class__.__name__,
'custom_fields': {'pd_identifier': name}
}
return ret
@ -164,8 +183,7 @@ class HPRaidController(RaidController):
" Ignoring.".format(name)
)
continue
attrs['custom_fields'] = ld
attrs['custom_fields']['pd_identifier'] = name
attrs['custom_fields'].update(ld)
def get_physical_disks(self):
return list(self.pdrives.values())

View file

@ -6,15 +6,32 @@ import logging
import re
class OmreportControllerError(Exception):
pass
def omreport(sub_command):
command = 'omreport {}'.format(sub_command)
output = subprocess.getoutput(command)
command = ["omreport"]
command.extend(sub_command.split())
p = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
)
p.wait()
stdout = p.stdout.read().decode("utf-8")
if p.returncode != 0:
mesg = "Failed to execute command '{}':\n{}".format(
" ".join(command), stdout
)
raise OmreportControllerError(mesg)
res = {}
section_re = re.compile('^[A-Z]')
current_section = None
current_obj = None
for line in output.split('\n'):
for line in stdout.split('\n'):
if ': ' in line:
attr, value = line.split(': ', 1)
attr = attr.strip()

View file

@ -8,10 +8,27 @@ import re
import os
class StorcliControllerError(Exception):
pass
def storecli(sub_command):
command = 'storcli {} J'.format(sub_command)
output = subprocess.getoutput(command)
data = json.loads(output)
command = ["storcli"]
command.extend(sub_command.split())
command.append("J")
p = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
)
p.wait()
stdout = p.stdout.read().decode("utf-8")
if p.returncode != 0:
mesg = "Failed to execute command '{}':\n{}".format(
" ".join(command), stdout
)
raise StorcliControllerError(mesg)
data = json.loads(stdout)
controllers = dict([
(
c['Command Status']['Controller'],
@ -22,7 +39,7 @@ def storecli(sub_command):
if not controllers:
logging.error(
"Failed to execute command '{}'. "
"Ignoring data.".format(command)
"Ignoring data.".format(" ".join(command))
)
return {}
return controllers