diff --git a/pyghmi/redfish/command.py b/pyghmi/redfish/command.py index 9a1c1538..6afe2190 100644 --- a/pyghmi/redfish/command.py +++ b/pyghmi/redfish/command.py @@ -1486,7 +1486,7 @@ class Command(object): def get_update_status(self): return self.oem.get_update_status() - def update_firmware(self, file, data=None, progress=None, bank=None): + def update_firmware(self, file, data=None, progress=None, bank=None, otherfields=()): """Send file to BMC to perform firmware update :param filename: The filename to upload to the target BMC @@ -1498,7 +1498,7 @@ class Command(object): """ if progress is None: progress = lambda x: True - return self.oem.update_firmware(file, data, progress, bank) + return self.oem.update_firmware(file, data, progress, bank, otherfields) def get_diagnostic_data(self, savefile, progress=None, autosuffix=False): if os.path.exists(savefile) and not os.path.isdir(savefile): diff --git a/pyghmi/redfish/oem/ami/megarac.py b/pyghmi/redfish/oem/ami/megarac.py index 28791baf..3f4c2b12 100644 --- a/pyghmi/redfish/oem/ami/megarac.py +++ b/pyghmi/redfish/oem/ami/megarac.py @@ -15,7 +15,7 @@ import pyghmi.redfish.oem.generic as generic import pyghmi.util.webclient as webclient from urllib.parse import urlencode - +import pyghmi.exceptions as pygexc class OEMHandler(generic.OEMHandler): @@ -35,6 +35,47 @@ class OEMHandler(generic.OEMHandler): self.bmc = webclient.thehost self._certverify = webclient._certverify + def reseat_bay(self, bay): + if bay != -1: + raise pygexc.UnsupportedFunctionality( + 'This is not an enclosure manager') + + self._do_web_request('/redfish/v1/Chassis/Chassis_0/Actions/Oem/NvidiaChassis.AuxPowerReset', { + "ResetType": "AuxPowerCycle" + }) + + def format_messages(self, response): + msgs = response.get('Messages', []) + msgents = [] + for msg in msgs: + msgents.append(self.format_message(msg)) + for msg in response.get('Oem', {}).get('Ami', {}).get('HMCMessages', []): + msgents.append(self.format_messages(msg)) + return ';'.join(msgents) + + def update_firmware(self, filename, data=None, progress=None, bank=None, otherfields=()): + self._do_web_request('/redfish/v1/UpdateService', { + "Oem": { + "AMIUpdateService": { + "@odata.type": "#AMIUpdateService.v1_0_0.AMIUpdateService", + "PreserveConfiguration": { + "Syslog": True, + "NTP": True, + "Network": True, + "Authentication": True, + "EXTLOG": True, + "FRU": True, + "IPMI": True, + "KVM": True, + "REDFISH": True, + "SDR": False, + "SEL": True, + "SNMP": True, + "SSH": True, + "WEB": True + } + }}}, method='PATCH', etag='*') + return super(OEMHandler, self).update_firmware(filename, data=data, progress=progress, bank=bank, otherfields=otherfields) @property def wc(self): diff --git a/pyghmi/redfish/oem/generic.py b/pyghmi/redfish/oem/generic.py index a0df51d5..3512db44 100644 --- a/pyghmi/redfish/oem/generic.py +++ b/pyghmi/redfish/oem/generic.py @@ -753,6 +753,8 @@ class OEMHandler(object): return {'bootdev': reqbootdev} except Exception: del payload['Boot']['BootSourceOverrideMode'] + else: + payload['Boot']['BootSourceOverrideMode'] = 'UEFI' #thetag = fishclient.sysinfo.get('@odata.etag', None) fishclient._do_web_request(fishclient.sysurl, payload, method='PATCH', etag='*') # thetag) @@ -1393,7 +1395,7 @@ class OEMHandler(object): usd, upurl, ismultipart = self.retrieve_firmware_upload_url() try: uploadthread = webclient.FileUploader( - self.webclient, upurl, filename, data, formwrap=ismultipart, + self.webclient, upurl, filename, data, formname='UpdateFile', formwrap=ismultipart, excepterror=False, otherfields=otherfields) uploadthread.start() wc = self.webclient @@ -1427,7 +1429,17 @@ class OEMHandler(object): rsp = json.loads(uploadthread.rsp) monitorurl = rsp['@odata.id'] return self.monitor_update_progress(monitorurl, progress) - + + def format_message(self, msg): + try: + return '{}: {}'.format(msg.get('MessageSeverity', msg['Severity']), msg['Message']) + except Exception: + return repr(msg) + + def format_messages(self, response): + msgs = response.get('Messages', []) + return ';'.join(self.format_message(x) for x in msgs) + def monitor_update_progress(self, monitorurl, progress): complete = False phase = "apply" @@ -1452,12 +1464,10 @@ class OEMHandler(object): state = pgress[statetype] if state in ('Cancelled', 'Exception', 'Interrupted', 'Suspended'): - raise Exception( - json.dumps(json.dumps(pgress['Messages']))) + + raise Exception(self.format_messages(pgress)) if 'PercentComplete' in pgress: pct = float(pgress['PercentComplete']) - else: - print(repr(pgress)) complete = state == 'Completed' progress({'phase': phase, 'progress': pct}) if complete: