Skip to content

Commit 29dcf22

Browse files
committed
Version 5.1.0.0
1 parent 7094f3a commit 29dcf22

File tree

5 files changed

+88
-37
lines changed

5 files changed

+88
-37
lines changed

src/redfish/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
""" Redfish restful library """
22

33
__all__ = ["rest", "ris", "hpilo"]
4-
__version__ = "5.0.0.0"
4+
__version__ = "5.1.0.0"
55

66
import logging
77

src/redfish/hpilo/risblobstore2.py

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import string
2626
import struct
2727
import sys
28+
import time
29+
import os
2830
from ctypes import (
2931
POINTER,
3032
c_char_p,
@@ -176,7 +178,9 @@ def __init__(self, log_dir=None):
176178
lib = self.gethprestchifhandle()
177179
self.log_dir = log_dir
178180
self.channel = HpIlo(dll=lib, log_dir=log_dir)
179-
self.max_retries = 3
181+
self.max_retries = 40
182+
self.max_read_retries = 3
183+
self.delay = 0.25
180184

181185
def __del__(self):
182186
"""Blob store 2 close channel function"""
@@ -233,19 +237,31 @@ def get_info(self, key, namespace, retries=0):
233237
data = ptr[: lib.size_of_infoRequest()]
234238
data = bytearray(data)
235239

236-
resp = self._send_receive_raw(data)
240+
while(retries <= self.max_retries):
241+
"""The Redfish request is submitted to iLO successfully in rest_immediate() function.
242+
Here we are checking if iLO has processed the Redfish request and the response is
243+
written in the key in the volatile namespace in blob.
244+
If iLO has not processed the request and response is not written, we get BADPARAMETER error.
245+
Hence retry after 0.25 seconds."""
246+
resp = self._send_receive_raw(data)
237247

238-
errorcode = struct.unpack("<I", bytes(resp[8:12]))[0]
239-
if errorcode == BlobReturnCodes.BADPARAMETER:
240-
if retries < self.max_retries:
241-
self.get_info(key=key, namespace=namespace, retries=retries + 1)
242-
else:
243-
raise Blob2OverrideError(errorcode)
244-
elif errorcode == BlobReturnCodes.NOTFOUND:
245-
raise BlobNotFoundError(key, namespace)
248+
#checking for errors in the received response
249+
errorcode = struct.unpack("<I", bytes(resp[8:12]))[0]
246250

247-
if not (errorcode == BlobReturnCodes.SUCCESS or errorcode == BlobReturnCodes.NOTMODIFIED):
248-
raise HpIloError(errorcode)
251+
if errorcode == BlobReturnCodes.BADPARAMETER:
252+
#if BADPARAMETER, delaying the execution by 0.25 seconds and retrying "send_receive_raw"
253+
if retries < self.max_retries:
254+
time.sleep(self.delay)
255+
retries += 1
256+
else:
257+
#if all retries are exhausted and an error is still received, raise Blob2override error.
258+
raise Blob2OverrideError(errorcode)
259+
elif errorcode == BlobReturnCodes.NOTFOUND:
260+
raise BlobNotFoundError(key, namespace)
261+
elif not (errorcode == BlobReturnCodes.SUCCESS or errorcode == BlobReturnCodes.NOTMODIFIED):
262+
raise HpIloError(errorcode)
263+
else:
264+
break
249265

250266
response = resp[lib.size_of_responseHeaderBlob() :]
251267

@@ -288,7 +304,7 @@ def read(self, key, namespace, retries=0):
288304
bytesread = struct.unpack("<I", bytes(recvpkt[readhead:(newreadsize)]))[0]
289305

290306
if bytesread == 0:
291-
if retries < self.max_retries:
307+
if retries < self.max_read_retries:
292308
data = self.read(key=key, namespace=namespace, retries=retries + 1)
293309
return data
294310
else:
@@ -431,16 +447,29 @@ def delete(self, key, namespace, retries=0):
431447
data = ptr[: lib.size_of_deleteRequest()]
432448
data = bytearray(data)
433449

434-
resp = self._send_receive_raw(data)
450+
while(retries <= self.max_retries):
451+
"""The Redfish request is submitted to iLO successfully in rest_immediate() function.
452+
Here we are checking if iLO has processed the Redfish request and the response is
453+
written in the key in the volatile namespace in blob.
454+
If iLO has not processed the request and response is not written, we get BADPARAMETER error.
455+
Hence retry after 0.25 seconds."""
456+
resp = self._send_receive_raw(data)
435457

436-
errorcode = struct.unpack("<I", bytes(resp[8:12]))[0]
437-
if errorcode == BlobReturnCodes.BADPARAMETER:
438-
if retries < self.max_retries:
439-
self.delete(key=key, namespace=namespace, retries=retries + 1)
458+
#checking for errors in the received response
459+
errorcode = struct.unpack("<I", bytes(resp[8:12]))[0]
460+
461+
if errorcode == BlobReturnCodes.BADPARAMETER:
462+
#if error is BADPARAMETER, delaying the execution by 0.25 seconds and retrying "send_receive_raw"
463+
if retries < self.max_retries:
464+
time.sleep(self.delay)
465+
retries += 1
466+
else:
467+
#if all retries are exhausted and an error is still received, raise Blob2override error.
468+
raise Blob2OverrideError(errorcode)
469+
elif not (errorcode == BlobReturnCodes.SUCCESS or errorcode == BlobReturnCodes.NOTMODIFIED):
470+
raise HpIloError(errorcode)
440471
else:
441-
raise Blob2OverrideError(errorcode)
442-
elif not (errorcode == BlobReturnCodes.SUCCESS or errorcode == BlobReturnCodes.NOTMODIFIED):
443-
raise HpIloError(errorcode)
472+
break
444473

445474
self.unloadchifhandle(lib)
446475

@@ -889,6 +918,21 @@ def gethprestchifhandle():
889918
if libhandle:
890919
BlobStore2.setglobalhprestchifrandnumber(libhandle)
891920
return libhandle
921+
else:
922+
import site
923+
site_packages = site.getsitepackages()
924+
for package in site_packages:
925+
try:
926+
if os.name != "nt":
927+
libpath = os.path.join(package, "ilorest", "chiflibrary", "ilorest_chif.so")
928+
else:
929+
libpath = os.path.join(package, "ilorest", "chiflibrary", "ilorest_chif.dll")
930+
libhandle = cdll.LoadLibrary(libpath)
931+
except Exception as exp:
932+
excp = exp
933+
if libhandle:
934+
BlobStore2.setglobalhprestchifrandnumber(libhandle)
935+
return libhandle
892936
raise ChifDllMissingError(excp)
893937

894938
@staticmethod

src/redfish/ris/resp_handler.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ def output_resp(self, response, dl_reg=False, verbosity=1):
8181

8282
if response.status < 300 and (response._rest_request.method == "GET" or not response.read):
8383
# for rawget
84-
if verbosity == 0:
85-
verbosity = 1
8684
print_handler(
8785
self.verbosity_levels(
8886
message=message_text, response_status=response.status, verbosity=verbosity, dl_reg=dl_reg
@@ -285,7 +283,7 @@ def verbosity_levels(
285283
+ "\n"
286284
)
287285
else:
288-
return "" + message + "\n"
286+
return ""
289287

290288
# unused? (removal pending)
291289
@staticmethod

src/redfish/ris/ris.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import jsonpointer
4141
from jsonpointer import set_pointer
4242
from six.moves.urllib.parse import urlparse, urlunparse
43+
from six.moves.urllib.parse import ParseResult
44+
from six.moves.urllib.parse import quote
4345

4446
from redfish.rest.containers import RestRequest, StaticRestResponse
4547
from redfish.ris.ris_threaded import LoadWorker
@@ -575,21 +577,20 @@ def _load(
575577
:type path_refresh: bool
576578
"""
577579

578-
if path.endswith("?page=1") and not loadcomplete:
580+
if (path.endswith("?page=1") or path.endswith(".json")) and not loadcomplete:
579581
# Don't download schemas in crawl unless we are loading absolutely everything
580582
return
581583
elif not includelogs and crawl:
582584
# Only include logs when asked as there can be an extreme amount of entries
583585
if "/log" in path.lower():
584586
return
585587

586-
# TODO: need to find a better way to support non ascii characters
587-
path = path.replace("|", "%7C")
588-
# remove fragments
589-
newpath = urlparse(path)
590-
newpath = list(newpath[:])
591-
newpath[-1] = ""
592-
path = urlunparse(tuple(newpath))
588+
# remove fragments and quote characters in path
589+
p = urlparse(path)
590+
p = ParseResult(
591+
scheme=p.scheme, netloc=p.netloc, path=quote(p.path), params=p.params, query=p.query, fragment=""
592+
)
593+
path = urlunparse(p)
593594

594595
if prevpath and prevpath != path:
595596
self.ctree[prevpath].update([path])
@@ -617,10 +618,8 @@ def _load(
617618

618619
self.update_member(resp=resp, path=path, init=init)
619620

620-
fpath = (
621-
lambda pa, path: path
622-
if pa.endswith(self.typepath.defs.hrefstring) and pa.startswith((self.collstr, "Entries"))
623-
else None
621+
fpath = lambda pa, path: (
622+
path if pa.endswith(self.typepath.defs.hrefstring) and pa.startswith((self.collstr, "Entries")) else None
624623
)
625624

626625
if loadtype == "href":

src/redfish/ris/utils.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ def merge_dict(currdict, newdict):
115115

116116
if isinstance(itemv1, Mapping) and isinstance(itemv2, Mapping):
117117
merge_dict(itemv1, itemv2)
118+
elif isinstance(itemv1, list) and isinstance(itemv2, list):
119+
j = 0
120+
for i in itemv2:
121+
if isinstance(i, dict):
122+
for k, v in i.items():
123+
if k not in [d.keys() for d in itemv1]:
124+
itemv1[j][k] = v
125+
j = j + 1
126+
else:
127+
itemv1.append(i)
118128
else:
119129
currdict[k] = itemv2
120130

0 commit comments

Comments
 (0)