2
0
mirror of https://opendev.org/x/pyghmi synced 2025-01-20 19:23:23 +00:00

Implement extensible BMC configuration

In much the same way system_configuration permits a system to
extensibly describe UEFI/BIOS type configuration, offer OEM modules
a mechanism to do the same for BMC specific settings.

Change-Id: Ic6be1b90247afe9b43af498e90e4d139343a5124
This commit is contained in:
Jarrod Johnson 2019-08-26 14:56:45 -04:00
parent d5786feede
commit 40cb397ae7
6 changed files with 114 additions and 0 deletions

@ -774,6 +774,18 @@ class Command(object):
else:
raise Exception("Unrecognized data format " + repr(fetchdata))
def get_bmc_configuration(self):
self.oem_init()
return self._oem.get_bmc_configuration()
def set_bmc_configuration(self, changeset):
self.oem_init()
return self._oem.set_bmc_configuration(changeset)
def clear_bmc_configuration(self):
self.oem_init()
return self._oem.clear_bmc_configuration()
def get_system_configuration(self, hideadvanced=True):
self.oem_init()
return self._oem.get_system_configuration(hideadvanced)

@ -60,6 +60,10 @@ class OEMHandler(object):
raise exc.UnsupportedFunctionality(
'Clearing system configuration not implemented for this platform')
def clear_bmc_configuration(self):
raise exc.UnsupportedFunctionality(
'Clearing BMC configuration not implemented for this platform')
def get_oem_inventory_descriptions(self):
"""Get descriptions of available additional inventory items
@ -335,6 +339,12 @@ class OEMHandler(object):
"""
return False
def get_bmc_configuration(self):
return {}
def set_bmc_configuration(self, changeset):
raise exc.UnsupportedFunctionality('Platform does not support setting bmc attributes')
def get_system_configuration(self, hideadvanced):
"""Retrieve system configuration

@ -938,6 +938,16 @@ class OEMHandler(generic.OEMHandler):
return {'height': self._fpc_variant, 'slot': 0}
return super(OEMHandler, self).get_description()
def get_bmc_configuration(self):
if self.has_xcc:
return self.immhandler.get_bmc_configuration()
return super(OEMHandler, self).get_bmc_configuration()
def set_bmc_configuration(self, changeset):
if self.has_xcc:
return self.immhandler.set_bmc_configuration(changeset)
return super(OEMHandler, self).set_bmc_configuration(changeset)
def get_system_configuration(self, hideadvanced):
if self.has_imm or self.has_xcc:
return self.immhandler.get_system_configuration(hideadvanced)
@ -948,6 +958,13 @@ class OEMHandler(generic.OEMHandler):
return self.immhandler.set_system_configuration(changeset)
return super(OEMHandler, self).set_system_configuration(changeset)
def clear_bmc_configuration(self):
if self.has_xcc:
return self.immhandler.clear_bmc_configuration()
elif self.is_fpc:
return self.smmhandler.clear_bmc_configuration()
return super(OEMHandler, self).clear_system_configuration()
def clear_system_configuration(self):
if self.has_xcc:
return self.immhandler.clear_system_configuration()

@ -265,6 +265,9 @@ class IMMClient(object):
self.fwo = None
raise
def clear_bmc_configuration(self):
self.ipmicmd.xraw_command(0x2e, 0xcc, data=(0x5e, 0x2b, 0, 0xa, 1, 0xff, 0, 0, 0))
def set_property(self, propname, value):
if not isinstance(value, int) or value > 255:
raise Exception('Unsupported property value')
@ -806,6 +809,40 @@ class XCCClient(IMMClient):
return {}
return {'height': int(dsc['u-height']), 'slot': int(dsc['slot'])}
def get_bmc_configuration(self):
try:
enclosureinfo = self.ipmicmd.xraw_command(0x3a, 0xf1, data=[0])
except pygexc.IpmiException:
return {}
settings = {
'smm': {
'default': 'Disable',
'possible': ['Enable', 'Disable'],
}
}
if enclosureinfo['data'][0] == '\x02':
settings['smm']['value'] = 'Disable'
elif enclosureinfo['data'][0] == '\x01':
settings['smm']['value'] = 'Enable'
else:
settings['smm']['value'] = None
return settings
def set_bmc_configuration(self, changeset):
for key in changeset:
if (isinstance(changeset[key], str) or
isinstance(changeset[key], unicode)):
changeset[key] = {'value': changeset[key]}
currval = changeset[key].get('value', None)
if 'smm'.startswith(key.lower()):
if currval == 'Enable':
self.ipmicmd.xraw_command(0x3a, 0xf1, data=[1])
elif currval == 'Disable':
self.ipmicmd.xraw_command(0x3a, 0xf1, data=[2])
else:
raise pygexc.InvalidParameterValue(
'{0} not a known setting'.format(key))
def clear_system_configuration(self):
res = self.wc.grab_json_response_with_status(
'/redfish/v1/Systems/1/Bios/Actions/Bios.ResetBios',

@ -251,6 +251,9 @@ class SMMClient(object):
self.password = ipmicmd.ipmi_session.password
self._wc = None
def clear_bmc_configuration(self):
self.ipmicmd.xraw_command(0x32, 0xad)
def set_user_priv(self, uid, priv):
if priv.lower() == 'administrator':
rsp = self.ipmicmd.xraw_command(netfn=6, command=0x46, data=(uid,))

@ -847,6 +847,41 @@ class Command(object):
}
return addon, valtodisplay, displaytoval, reg
def get_bmc_configuration(self):
"""Get miscellaneous BMC configuration
In much the same way a bmc can present arbitrary key-value
structure for BIOS/UEFI configuration, provide a mechanism
for a BMC to provide arbitrary key-value for BMC specific
settings.
"""
# For now, this is a stub, no implementation for redfish currently
return {}
def set_bmc_configuration(self, changeset):
"""Get miscellaneous BMC configuration
In much the same way a bmc can present arbitrary key-value
structure for BIOS/UEFI configuration, provide a mechanism
for a BMC to provide arbitrary key-value for BMC specific
settings.
"""
# For now, this is a stub, no implementation for redfish currently
raise exc.UnsupportedFunctionality(
'Set BMC configuration not supported in redfish yet')
def clear_bmc_configuration(self):
"""Reset BMC to factory default
Call appropriate function to clear BMC to factory default settings.
In many cases, this may render remote network access impracticle or
impossible."
"""
raise exc.UnsupportedFunctionality(
'Clear BMC configuration not supported in redfish yet')
def get_system_configuration(self, hideadvanced=True):
return self._getsyscfg()[0]