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:
@@ -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():
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user