2
0
mirror of https://opendev.org/x/pyghmi synced 2025-01-27 19:37:44 +00:00

Provide opt-in performance boost to firmware

The fast path may be sufficient for certain queries,
enable a way to opt into faster, but less thorough firmware
enumeration.

Change-Id: If33db84a3ce965d5e528c65f3db4f190867b0b92
This commit is contained in:
Jarrod Johnson 2018-02-13 16:24:07 -05:00
parent 4665b98b2a
commit 05b973dff0
4 changed files with 142 additions and 118 deletions

View File

@ -1790,14 +1790,14 @@ class Command(object):
self.set_user_password(uid, mode)
return True
def get_firmware(self):
def get_firmware(self, components=()):
"""Retrieve OEM Firmware information
"""
self.oem_init()
mcinfo = self.xraw_command(netfn=6, command=1)
bmcver = '{0}.{1}'.format(
ord(mcinfo['data'][2]), hex(ord(mcinfo['data'][3]))[2:])
return self._oem.get_oem_firmware(bmcver)
return self._oem.get_oem_firmware(bmcver, components)
def get_capping_enabled(self):
"""Get PSU based power capping status

View File

@ -159,12 +159,18 @@ class OEMHandler(object):
fru['oem_parser'] = None
return fru
def get_oem_firmware(self, bmcver):
def get_oem_firmware(self, bmcver, components):
"""Get Firmware information.
"""
# Here the bmc version is passed into the OEM handler, to allow
# the handler to enrich the data. For the generic case, just
# provide the generic BMC version, which is all that is possible
# Additionally, components may be provided for an advisory guide
# on interesting firmware. The OEM library is permitted to return
# more than requested, and it is the responsibility of the calling
# code to know whether it cares or not. The main purpose of the
# components argument is to indicate when certain performance
# optimizations can be performed.
yield ('BMC Version', {'version': bmcver})
def get_oem_capping_enabled(self):

View File

@ -595,13 +595,13 @@ class OEMHandler(generic.OEMHandler):
self._hasimm = (rdata[1] & 1 == 1) or (rdata[1] & 16 == 16)
return self._hasimm
def get_oem_firmware(self, bmcver):
def get_oem_firmware(self, bmcver, components):
if self.has_tsm:
command = firmware.get_categories()["firmware"]
rsp = self.ipmicmd.xraw_command(**command["command"])
return command["parser"](rsp["data"])
elif self.has_imm:
return self.immhandler.get_firmware_inventory(bmcver)
return self.immhandler.get_firmware_inventory(bmcver, components)
elif self.is_fpc:
return nextscale.get_fpc_firmware(bmcver, self.ipmicmd,
self._fpc_variant)

View File

@ -469,55 +469,63 @@ class IMMClient(object):
self.weblogout()
return hwmap
def get_firmware_inventory(self, bmcver):
def get_firmware_inventory(self, bmcver, components):
# First we fetch the system firmware found in imm properties
# then check for agentless, if agentless, get adapter info using
# https, using the caller TLS verification scheme
rsp = self.ipmicmd.xraw_command(netfn=0x3a, command=0x50)
immverdata = self.parse_imm_buildinfo(rsp['data'])
bdata = {
'version': bmcver, 'build': immverdata[0], 'date': immverdata[1]}
yield (self.bmcname, bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/dm/fw/imm2/backup_build_id',
'version': '/v2/ibmc/dm/fw/imm2/backup_build_version',
'date': '/v2/ibmc/dm/fw/imm2/backup_build_date'})
if bdata:
yield ('{0} Backup'.format(self.bmcname), bdata)
components = set(components)
if not components or set(('imm', 'xcc', 'bmc', 'core')) & components:
rsp = self.ipmicmd.xraw_command(netfn=0x3a, command=0x50)
immverdata = self.parse_imm_buildinfo(rsp['data'])
bdata = {
'version': bmcver, 'build': immverdata[0],
'date': immverdata[1]}
yield (self.bmcname, bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/trusted_buildid',
})
if bdata:
yield ('{0} Trusted Image'.format(self.bmcname), bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/bios/build_id',
'version': '/v2/bios/build_version',
'date': '/v2/bios/build_date'})
if bdata:
yield ('UEFI', bdata)
else:
yield ('UEFI', {'version': 'unknown'})
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/dm/fw/bios/backup_build_id',
'version': '/v2/ibmc/dm/fw/bios/backup_build_version'})
if bdata:
yield ('UEFI Backup', bdata)
# Note that the next pending could be pending for either primary
# or backup, so can't promise where it will go
bdata = self.fetch_grouped_properties({
'build': '/v2/bios/pending_build_id'})
if bdata:
yield ('UEFI Pending Update', bdata)
try:
fpga = self.ipmicmd.xraw_command(netfn=0x3a, command=0x6b,
data=(0,))
fpga = '{0}.{1}.{2}'.format(*[ord(x) for x in fpga['data']])
yield ('FPGA', {'version': fpga})
except pygexc.IpmiException as ie:
if ie.ipmicode != 193:
raise
for firm in self.fetch_agentless_firmware():
yield firm
'build': '/v2/ibmc/dm/fw/imm2/backup_build_id',
'version': '/v2/ibmc/dm/fw/imm2/backup_build_version',
'date': '/v2/ibmc/dm/fw/imm2/backup_build_date'})
if bdata:
yield ('{0} Backup'.format(self.bmcname), bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/trusted_buildid',
})
if bdata:
yield ('{0} Trusted Image'.format(self.bmcname), bdata)
if not components or set(('uefi', 'bios', 'core')) & components:
bdata = self.fetch_grouped_properties({
'build': '/v2/bios/build_id',
'version': '/v2/bios/build_version',
'date': '/v2/bios/build_date'})
if bdata:
yield ('UEFI', bdata)
else:
yield ('UEFI', {'version': 'unknown'})
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/dm/fw/bios/backup_build_id',
'version': '/v2/ibmc/dm/fw/bios/backup_build_version'})
if bdata:
yield ('UEFI Backup', bdata)
# Note that the next pending could be pending for either primary
# or backup, so can't promise where it will go
bdata = self.fetch_grouped_properties({
'build': '/v2/bios/pending_build_id'})
if bdata:
yield ('UEFI Pending Update', bdata)
if not components or set(('fpga', 'core')) & components:
try:
fpga = self.ipmicmd.xraw_command(netfn=0x3a, command=0x6b,
data=(0,))
fpga = '{0}.{1}.{2}'.format(*[ord(x) for x in fpga['data']])
yield ('FPGA', {'version': fpga})
except pygexc.IpmiException as ie:
if ie.ipmicode != 193:
raise
if (not components or (components - set((
'core', 'uefi', 'bios', 'bmc', 'xcc', 'imm', 'fpga',
'lxpm')))):
for firm in self.fetch_agentless_firmware():
yield firm
class XCCClient(IMMClient):
@ -883,85 +891,95 @@ class XCCClient(IMMClient):
def keepalive(self):
self._refresh_token_wc(self._keepalivesession)
def get_firmware_inventory(self, bmcver):
def get_firmware_inventory(self, bmcver, components):
# First we fetch the system firmware found in imm properties
# then check for agentless, if agentless, get adapter info using
# https, using the caller TLS verification scheme
rsp = self.ipmicmd.xraw_command(netfn=0x3a, command=0x50)
immverdata = self.parse_imm_buildinfo(rsp['data'])
bdata = {
'version': bmcver, 'build': immverdata[0], 'date': immverdata[1]}
yield (self.bmcname, bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/dm/fw/imm3/backup_pending_build_id',
'version': '/v2/ibmc/dm/fw/imm3/backup_pending_build_version',
'date': '/v2/ibmc/dm/fw/imm3/backup_pending_build_date'})
if bdata:
yield ('{0} Backup'.format(self.bmcname), bdata)
else:
components = set(components)
if (not components or
set(('core', 'imm', 'bmc', 'xcc')) & components):
rsp = self.ipmicmd.xraw_command(netfn=0x3a, command=0x50)
immverdata = self.parse_imm_buildinfo(rsp['data'])
bdata = {'version': bmcver,
'build': immverdata[0],
'date': immverdata[1]}
yield (self.bmcname, bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/dm/fw/imm3/backup_build_id',
'version': '/v2/ibmc/dm/fw/imm3/backup_build_version',
'date': '/v2/ibmc/dm/fw/imm3/backup_build_date'})
'build': '/v2/ibmc/dm/fw/imm3/backup_pending_build_id',
'version': '/v2/ibmc/dm/fw/imm3/backup_pending_build_version',
'date': '/v2/ibmc/dm/fw/imm3/backup_pending_build_date'})
if bdata:
yield ('{0} Backup'.format(self.bmcname), bdata)
else:
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/dm/fw/imm3/backup_build_id',
'version': '/v2/ibmc/dm/fw/imm3/backup_build_version',
'date': '/v2/ibmc/dm/fw/imm3/backup_build_date'})
if bdata:
yield ('{0} Backup'.format(self.bmcname), bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/trusted_buildid',
})
if bdata:
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/trusted_buildid',
})
if bdata:
if bdata:
yield ('{0} Trusted Image'.format(self.bmcname), bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/trusted_buildid',
'build': '/v2/ibmc/dm/fw/imm3/primary_pending_build_id',
'version': '/v2/ibmc/dm/fw/imm3/primary_pending_build_version',
'date': '/v2/ibmc/dm/fw/imm3/primary_pending_build_date'})
if bdata:
yield ('{0} Pending Update'.format(self.bmcname), bdata)
if (not components or set(('core', 'uefi', 'bios')) & components):
bdata = self.fetch_grouped_properties({
'build': '/v2/bios/build_id',
'version': '/v2/bios/build_version',
'date': '/v2/bios/build_date'})
if bdata:
yield ('UEFI', bdata)
# Note that the next pending could be pending for either primary
# or backup, so can't promise where it will go
bdata = self.fetch_grouped_properties({
'build': '/v2/bios/pending_build_id'})
if bdata:
yield ('UEFI Pending Update', bdata)
if not components or set(('lxpm', 'core')) & components:
bdata = self.fetch_grouped_properties({
'build': '/v2/tdm/build_id',
'version': '/v2/tdm/build_version',
'date': '/v2/tdm/build_date'})
if bdata:
yield ('LXPM', bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/drvwn/build_id',
'version': '/v2/drvwn/build_version',
'date': '/v2/drvwn/build_date',
})
if bdata:
yield ('{0} Trusted Image'.format(self.bmcname), bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/ibmc/dm/fw/imm3/primary_pending_build_id',
'version': '/v2/ibmc/dm/fw/imm3/primary_pending_build_version',
'date': '/v2/ibmc/dm/fw/imm3/primary_pending_build_date'})
if bdata:
yield ('{0} Pending Update'.format(self.bmcname), bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/bios/build_id',
'version': '/v2/bios/build_version',
'date': '/v2/bios/build_date'})
if bdata:
yield ('UEFI', bdata)
# Note that the next pending could be pending for either primary
# or backup, so can't promise where it will go
bdata = self.fetch_grouped_properties({
'build': '/v2/bios/pending_build_id'})
if bdata:
yield ('UEFI Pending Update', bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/tdm/build_id',
'version': '/v2/tdm/build_version',
'date': '/v2/tdm/build_date'})
if bdata:
yield ('LXPM', bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/drvwn/build_id',
'version': '/v2/drvwn/build_version',
'date': '/v2/drvwn/build_date',
})
if bdata:
yield ('LXPM Windows Driver Bundle', bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/drvln/build_id',
'version': '/v2/drvln/build_version',
'date': '/v2/drvln/build_date',
})
if bdata:
yield ('LXPM Linux Driver Bundle', bdata)
try:
fpga = self.ipmicmd.xraw_command(netfn=0x3a, command=0x6b,
data=(0,))
fpga = '{0}.{1}.{2}'.format(*[ord(x) for x in fpga['data']])
yield ('FPGA', {'version': fpga})
except pygexc.IpmiException as ie:
if ie.ipmicode != 193:
raise
for firm in self.fetch_agentless_firmware():
yield firm
if bdata:
yield ('LXPM Windows Driver Bundle', bdata)
bdata = self.fetch_grouped_properties({
'build': '/v2/drvln/build_id',
'version': '/v2/drvln/build_version',
'date': '/v2/drvln/build_date',
})
if bdata:
yield ('LXPM Linux Driver Bundle', bdata)
if not components or set(('core', 'fpga')) in components:
try:
fpga = self.ipmicmd.xraw_command(netfn=0x3a, command=0x6b,
data=(0,))
fpga = '{0}.{1}.{2}'.format(*[ord(x) for x in fpga['data']])
yield ('FPGA', {'version': fpga})
except pygexc.IpmiException as ie:
if ie.ipmicode != 193:
raise
if (not components or components - set((
'core', 'uefi', 'bios', 'xcc', 'bmc', 'imm', 'fpga',
'lxpm'))):
for firm in self.fetch_agentless_firmware():
yield firm
def detach_remote_media(self):
if self.webkeepalive: