2
0
mirror of https://opendev.org/x/pyghmi synced 2026-01-11 18:52:33 +00:00

Provide update for backup XCC3 bank

Similar to XCC2, we must get at the underlying uxz file
if we want to steer it.

We also must use the multipart form data to pass json with right
Content-Type, add a mechanism to auto-json a dict to acheive this.

Change-Id: If204d7a05399e39cd43ffd7622559ab10d906b47
This commit is contained in:
Jarrod Johnson
2025-01-07 15:45:42 -05:00
parent 8f94185418
commit a1e29baf8b
3 changed files with 42 additions and 9 deletions

View File

@@ -931,7 +931,7 @@ class OEMHandler(object):
raise exc.UnsupportedFunctionality(
'Remote media upload not supported on this platform')
def update_firmware(self, filename, data=None, progress=None, bank=None):
def update_firmware(self, filename, data=None, progress=None, bank=None, otherfields=()):
# disable cache to make sure we trigger the token renewal logic if needed
usd = self._do_web_request('/redfish/v1/UpdateService', cache=False)
upurl = usd.get('MultipartHttpPushUri', None)
@@ -952,7 +952,7 @@ class OEMHandler(object):
try:
uploadthread = webclient.FileUploader(
self.webclient, upurl, filename, data, formwrap=ismultipart,
excepterror=False)
excepterror=False, otherfields=otherfields)
uploadthread.start()
wc = self.webclient
while uploadthread.isAlive():

View File

@@ -3,7 +3,8 @@ import json
import pyghmi.redfish.oem.generic as generic
import pyghmi.exceptions as pygexc
import pyghmi.util.webclient as webclient
import zipfile
import os.path
class OEMHandler(generic.OEMHandler):
@@ -82,6 +83,32 @@ class OEMHandler(generic.OEMHandler):
'password_lockout_period': 'AccountLockoutDuration',
}
def update_firmware(self, filename, data=None, progress=None, bank=None, otherfields=()):
if not otherfields and bank == 'backup':
uxzcount = 0
otherfields = {'UpdateParameters': {"Targets": ["/redfish/v1/UpdateService/FirmwareInventory/BMC-Backup"]}}
needseek = False
if data and hasattr(data, 'read'):
if zipfile.is_zipfile(data):
needseek = True
z = zipfile.ZipFile(data)
else:
data.seek(0)
elif data is None and zipfile.is_zipfile(filename):
z = zipfile.ZipFile(filename)
if z:
for tmpname in z.namelist():
if tmpname.startswith('payloads/'):
uxzcount += 1
if tmpname.endswith('.uxz'):
wrappedfilename = tmpname
if uxzcount == 1 and wrappedfilename:
filename = os.path.basename(wrappedfilename)
data = z.open(wrappedfilename)
elif needseek:
data.seek(0)
super().update_firmware(filename, data=data, progress=progress, bank=bank, otherfields=otherfields)
def get_bmc_configuration(self):
settings = {}
acctsrv = self._do_web_request('/redfish/v1/AccountService')

View File

@@ -107,16 +107,22 @@ def get_upload_form(filename, data, formname, otherfields):
data = data.read()
except AttributeError:
pass
form = (b'--' + BND
form = b''
for ofield in otherfields:
tfield = otherfields[ofield]
xtra=''
if isinstance(tfield, dict):
tfield = json.dumps(tfield)
xtra = '\r\nContent-Type: application/json'
form += (b'--' + BND
+ '\r\nContent-Disposition: form-data; '
'name="{0}"{1}\r\n\r\n{2}\r\n'.format(
ofield, xtra, tfield).encode('utf-8'))
form += (b'--' + BND
+ '\r\nContent-Disposition: form-data; '
'name="{0}"; filename="{1}"\r\n'.format(
formname, ffilename).encode('utf-8'))
form += b'Content-Type: application/octet-stream\r\n\r\n' + data
for ofield in otherfields:
form += (b'\r\n--' + BND
+ '\r\nContent-Disposition: form-data; '
'name="{0}"\r\n\r\n{1}'.format(
ofield, otherfields[ofield]).encode('utf-8'))
form += b'\r\n--' + BND + b'--\r\n'
uploadforms[filename] = form
return form