diff --git a/pyghmi/ipmi/command.py b/pyghmi/ipmi/command.py index 7d46e197..746c7227 100644 --- a/pyghmi/ipmi/command.py +++ b/pyghmi/ipmi/command.py @@ -776,9 +776,9 @@ class Command(object): else: raise Exception("Unrecognized data format " + repr(fetchdata)) - def get_bmc_configuration(self): + def get_bmc_configuration(self, extended=False): self.oem_init() - return self._oem.get_bmc_configuration() + return self._oem.get_bmc_configuration(extended) def set_bmc_configuration(self, changeset): self.oem_init() diff --git a/pyghmi/ipmi/oem/generic.py b/pyghmi/ipmi/oem/generic.py index a5bd96a1..fa5df146 100644 --- a/pyghmi/ipmi/oem/generic.py +++ b/pyghmi/ipmi/oem/generic.py @@ -331,7 +331,16 @@ class OEMHandler(object): """ return False - def get_bmc_configuration(self): + def get_bmc_configuration(self, extended): + """Get additional BMC parameters + + This allows a bmc to return arbitrary key-value pairs. + + :param extended: In the case of potentially redundant/slow + attributes, this allows the caller to opt + into retrieving unpopular options that may be + redundant or confusing. + """ return {} def set_bmc_configuration(self, changeset): diff --git a/pyghmi/ipmi/oem/lenovo/config.py b/pyghmi/ipmi/oem/lenovo/config.py index 40ed5670..79b84ebb 100644 --- a/pyghmi/ipmi/oem/lenovo/config.py +++ b/pyghmi/ipmi/oem/lenovo/config.py @@ -247,12 +247,16 @@ class LenovoFirmwareConfig(object): options[option]['new_value'] = options[option]['default'] self.set_fw_options(options) - def get_fw_options(self): + def get_fw_options(self, fetchimm=True): + if fetchimm: + cfgfilename = "config.efi" + else: + cfgfilename = "config" options = {} data = None for _ in range(0, 30): - filehandle = self.imm_open("config.efi") - size = self.imm_size("config.efi") + filehandle = self.imm_open(cfgfilename) + size = self.imm_size(cfgfilename) data = self.imm_read(filehandle, size) self.imm_close(filehandle) data = EfiDecompressor.decompress(data) diff --git a/pyghmi/ipmi/oem/lenovo/handler.py b/pyghmi/ipmi/oem/lenovo/handler.py index 6b2f0a5d..5fed6197 100755 --- a/pyghmi/ipmi/oem/lenovo/handler.py +++ b/pyghmi/ipmi/oem/lenovo/handler.py @@ -969,12 +969,12 @@ class OEMHandler(generic.OEMHandler): return {'height': self._fpc_variant, 'slot': 0} return super(OEMHandler, self).get_description() - def get_bmc_configuration(self): + def get_bmc_configuration(self, extended): if self.has_xcc: - return self.immhandler.get_bmc_configuration() + return self.immhandler.get_bmc_configuration(extended) if self.is_fpc: return self.smmhandler.get_bmc_configuration() - return super(OEMHandler, self).get_bmc_configuration() + return super(OEMHandler, self).get_bmc_configuration(extended) def set_bmc_configuration(self, changeset): if self.has_xcc: diff --git a/pyghmi/ipmi/oem/lenovo/imm.py b/pyghmi/ipmi/oem/lenovo/imm.py index 25bd8859..438291b3 100644 --- a/pyghmi/ipmi/oem/lenovo/imm.py +++ b/pyghmi/ipmi/oem/lenovo/imm.py @@ -181,11 +181,11 @@ class IMMClient(object): return None return cls._parse_builddate(propstr) - def get_system_configuration(self, hideadvanced=True): + def get_system_configuration(self, hideadvanced=True, fetchimm=False): if not self.fwc: self.fwc = config.LenovoFirmwareConfig(self.ipmicmd) try: - self.fwo = self.fwc.get_fw_options() + self.fwo = self.fwc.get_fw_options(fetchimm=fetchimm) except Exception: raise Exception(self.bmcname + ' failed to retrieve UEFI configuration') @@ -211,8 +211,9 @@ class IMMClient(object): def set_system_configuration(self, changeset): if not self.fwc: self.fwc = config.LenovoFirmwareConfig(self.ipmicmd) + fetchimm = False if not self.fwo or util._monotonic_time() - self.fwovintage > 30: - self.fwo = self.fwc.get_fw_options() + self.fwo = self.fwc.get_fw_options(fetchimm=fetchimm) self.fwovintage = util._monotonic_time() for key in list(changeset): if key not in self.fwo: @@ -226,6 +227,23 @@ class IMMClient(object): if fnmatch.fnmatch(calias.lower(), key.lower()): changeset[rkey] = changeset[key] found = True + if not found and not fetchimm: + fetchimm = True + self.fwo = self.fwc.get_fw_options(fetchimm=fetchimm) + if key in self.fwo: + continue + else: + found = False + for rkey in self.fwo: + if fnmatch.fnmatch(rkey.lower(), key.lower()): + changeset[rkey] = changeset[key] + found = True + elif self.fwo[rkey].get('alias', None) != rkey: + calias = self.fwo[rkey]['alias'] + if fnmatch.fnmatch( + calias.lower(), key.lower()): + changeset[rkey] = changeset[key] + found = True if found: del changeset[key] else: @@ -824,7 +842,7 @@ class XCCClient(IMMClient): return {} return {'height': int(dsc['u-height']), 'slot': int(dsc['slot'])} - def get_bmc_configuration(self): + def get_bmc_configuration(self, extended): settings = {} passrules = self.wc.grab_json_response('/api/dataset/imm_users_global') passrules = passrules.get('items', [{}])[0] @@ -858,6 +876,11 @@ class XCCClient(IMMClient): settings['smm']['value'] = 'Enable' else: settings['smm']['value'] = None + if extended: + immsettings = self.get_system_configuration(fetchimm=True) + for setting in immsettings: + if setting.startswith('IMM.'): + settings[setting] = immsettings[setting] return settings rulemap = {