diff --git a/bmc/redfishtool/debian/deb_folder/redfishtool.install b/bmc/redfishtool/debian/deb_folder/redfishtool.install index 9bc926013..c433f8ea2 100644 --- a/bmc/redfishtool/debian/deb_folder/redfishtool.install +++ b/bmc/redfishtool/debian/deb_folder/redfishtool.install @@ -1,3 +1,4 @@ usr/bin/redfishtool usr/bin/redfishtool.py usr/lib/python3/dist-packages/redfishtoollib/* +etc/redfishtool/redfishtool.ini diff --git a/bmc/redfishtool/debian/deb_folder/rules b/bmc/redfishtool/debian/deb_folder/rules index 59a65e845..127588927 100755 --- a/bmc/redfishtool/debian/deb_folder/rules +++ b/bmc/redfishtool/debian/deb_folder/rules @@ -9,4 +9,5 @@ export PBR_VERSION=1.0.0 dh $@ --with python3 --buildsystem=pybuild override_dh_install: - # nothing to do here + mkdir -p $(CURDIR)/debian/redfishtool/etc/redfishtool + cp $(CURDIR)/redfishtool.ini $(CURDIR)/debian/redfishtool/etc/redfishtool diff --git a/bmc/redfishtool/debian/files/redfishtool.ini b/bmc/redfishtool/debian/files/redfishtool.ini new file mode 100644 index 000000000..314099803 --- /dev/null +++ b/bmc/redfishtool/debian/files/redfishtool.ini @@ -0,0 +1,15 @@ +[setBootOverride_overrides] + +# The following list of server models should not receive a +# BootSourceOverrideMode key:value pair in the +# 'setBootOverride Once' PATCH request. When present: +# - HP Proliant servers fail the request. +# - Dell PowerEdge R7xxx servers initiate a BIOS reconfig update/reboot + +# For specific servers - first filter +exclude_BootSourceOverrideMode_Models = "R740XD vSAN Ready Node", "PowerEdge R750" + +# For entire manufacturers - second filter +exclude_BootSourceOverrideMode_Manufacturers = "HPE", "Dell Inc." + +[Settings] diff --git a/bmc/redfishtool/debian/patches/0002-Add-config-file-based-BootSourceOverrideMode-handlin.patch b/bmc/redfishtool/debian/patches/0002-Add-config-file-based-BootSourceOverrideMode-handlin.patch new file mode 100644 index 000000000..a4953a690 --- /dev/null +++ b/bmc/redfishtool/debian/patches/0002-Add-config-file-based-BootSourceOverrideMode-handlin.patch @@ -0,0 +1,131 @@ +From: Eric Macdonald +Date: Sun, 15 Dec 2024 22:41:27 +0000 +Subject: Add config file based BootSourceOverrideMode handling to + setBootOveride + +This patch reads /etc/redfishtool/redfishtool.ini config file in +search for the setBootOverride_overrides section that has a +list of manufacturers and models that should not receive the +BootSourceOverrideMode key:value pair as part of the payload +to the 'setBootOverride Once ' patch request. + +[setBootOverride_overrides] + exclude_BootSourceOverrideMode_Models = "", "" + exclude_BootSourceOverrideMode_Manufacturers = "" + +If current server is found in either the models or manufacturers lists +then it is excluded from getting the BootSourceOverrideMode key:value +pair added to the 'setBootOverride Once ' patch request. + +Signed-off-by: Eric Macdonald +--- + redfishtoollib/Systems.py | 78 ++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 73 insertions(+), 5 deletions(-) + +diff --git a/redfishtoollib/Systems.py b/redfishtoollib/Systems.py +index a0be4ad..6abee66 100644 +--- a/redfishtoollib/Systems.py ++++ b/redfishtoollib/Systems.py +@@ -503,6 +503,65 @@ class RfSystemsOperations(): + return op.iterate_op(op.setIndicatorLed_single, sc, op, rft, cmdTop=cmdTop, prop=prop) + + ++ def get_exclude_BootSourceOverrideMode(self, rft, d): ++ """ ++ Query redfishtool.ini for models or manufacturers that should not ++ not have the BootSourceOverrideMode key:value pair added to the ++ setBootOverride patch request. ++ """ ++ ++ # include the config file parser ++ import configparser ++ ++ manufacturer=d["Manufacturer"] ++ model=d["Model"] ++ rft.printVerbose(4, "Manufacturer: {}".format(d["Manufacturer"])) ++ rft.printVerbose(4, "Model : {}".format(d["Model"])) ++ ++ # the config file path ++ config_file="/etc/redfishtool/redfishtool.ini" ++ config = configparser.ConfigParser() ++ # read the configuration file ++ files_read = config.read(config_file) ++ if not files_read: ++ rft.printVerbose(0, "Configuration file '{}' not found or could not be read.".format(config_file)) ++ return(False) ++ ++ section="setBootOverride_overrides" ++ exclude_BootSourceOverrideMode_Models="exclude_BootSourceOverrideMode_Models" ++ exclude_BootSourceOverrideMode_Manufacturers="exclude_BootSourceOverrideMode_Manufacturers" ++ ++ # get the model and manufacturers exclude lists ++ exclude_models_list=[] ++ exclude_manufacturers_list=[] ++ exclude_BootSourceOverrideMode=False ++ ++ # don't fail based on missing file. Just run with default behavior. ++ if section in config: ++ if exclude_BootSourceOverrideMode_Models not in config[section]: ++ rft.printVerbose(4, "Option '{}' not found in section '{}' of the configuration file {}."\ ++ .format(exclude_BootSourceOverrideMode_Models, section, config_file)) ++ else: ++ exclude_models_list = config[section][exclude_BootSourceOverrideMode_Models] ++ rft.printVerbose(4, "Models Exclude List: {}".format(exclude_models_list)) ++ ++ if exclude_BootSourceOverrideMode_Manufacturers not in config[section]: ++ rft.printVerbose(4, "Option '{}' not found in section '{}' of the configuration file {}."\ ++ .format(exclude_BootSourceOverrideMode_Manufacturers, section, config_file)) ++ else: ++ exclude_manufacturers_list = config[section][exclude_BootSourceOverrideMode_Manufacturers] ++ rft.printVerbose(4, "Manufacturer Exclude List: {}".format(exclude_manufacturers_list)) ++ ++ exclude_BootSourceOverrideMode=False ++ if model in exclude_models_list: ++ rft.printVerbose(0, "Excluding BootSourceOverrideMode for server model: '{}'".format(model)) ++ exclude_BootSourceOverrideMode = True ++ elif manufacturer in exclude_manufacturers_list: ++ rft.printVerbose(0, "Excluding BootSourceOverrideMode for server manufacturer: '{}'".format(manufacturer)) ++ exclude_BootSourceOverrideMode = True ++ return (exclude_BootSourceOverrideMode) ++ ++ + def setBootOverride_single(self,sc,op,rft,cmdTop=False, prop=None): + # this operation has argument syntaxes below: + # ...setBootOverride [] +@@ -533,11 +592,17 @@ class RfSystemsOperations(): + #now read target, + # we will need to check that the properties we are patching are there, and chk for etag hdr + # and to see if the value specified is one of the allowable values for this rhost +- rc,r,j,d=op.get(sc,op,rft,prop="Boot") ++ rc,r,j,d=op.get(sc,op,rft) + if(rc != 0): + print("Error, can't read boot properties from remote service") + return(8,None,False,None) +- ++ ++ # this call will open the redfishtool.ini file and search for server models or ++ # manufacturers that don't support or behave well when the 'setBootOverride Once ' ++ # key:value pair is part of the payload of the PATCH method. ++ # If found then a True (to exclude) is returned. ++ exclude_BootSourceOverrideMode = op.get_exclude_BootSourceOverrideMode(rft, d) ++ + # verify that they have a BootSourceOverrideEnabled prop + bootRes=d["Boot"] + if( not "BootSourceOverrideEnabled" in bootRes ): +@@ -587,10 +652,13 @@ class RfSystemsOperations(): + + # Get the value of "BootSourceOverrideTarget" property and pass it in the patch request. + # Some HW vendors need this property to be passed explicitly. +- if "BootSourceOverrideMode" in d["Boot"]: +- patchData={"Boot": {"BootSourceOverrideEnabled": enabledVal, "BootSourceOverrideTarget": targetVal, "BootSourceOverrideMode": d["Boot"]["BootSourceOverrideMode"] } } ++ if exclude_BootSourceOverrideMode is True: ++ patchData={"Boot": {"BootSourceOverrideEnabled": enabledVal,\ ++ "BootSourceOverrideTarget": targetVal } } + else: +- patchData={"Boot": {"BootSourceOverrideEnabled": enabledVal, "BootSourceOverrideTarget": targetVal } } ++ patchData={"Boot": {"BootSourceOverrideEnabled": enabledVal,\ ++ "BootSourceOverrideTarget": targetVal,\ ++ "BootSourceOverrideMode": d["Boot"]["BootSourceOverrideMode"] } } + + #call the generic patch command to send the patch. This takes care of etag support + rc,r,j,d=rft.patchResource(rft, r, patchData) diff --git a/bmc/redfishtool/debian/patches/0002-Add-retry-to-BootSourceOverrideMode-handling.patch b/bmc/redfishtool/debian/patches/0002-Add-retry-to-BootSourceOverrideMode-handling.patch deleted file mode 100644 index 627a033b1..000000000 --- a/bmc/redfishtool/debian/patches/0002-Add-retry-to-BootSourceOverrideMode-handling.patch +++ /dev/null @@ -1,83 +0,0 @@ -From: Eric Macdonald -Date: Tue, 10 Dec 2024 17:05:13 +0000 -Subject: Add retry to BootSourceOverrideMode handling - -Redfishtool version 1.1.8 added a condition where if -'BootSourceOverrideMode' exists in the boot query response -then it adds the following to the Boot Source Override command -json string for the setBootOverride_single command. - -"BootSourceOverrideMode": d["Boot"]["BootSourceOverrideMode"] - -This change is leading to this Bad Request error for some servers. - -redfishtool: Transport: Response Error: status_code: 400 -- Bad Request - -Servers known to fail in this way are HP Proliant e910t, e920t as well -as DL360 and DL380 server models with HP iLO versions 3.01, 3.04 and -3.6. - -This update introduces a legacy mode retry to the setBootOverride -operation if the new method fails in a 400 - Bad Request. - -Signed-off-by: Eric Macdonald ---- - redfishtoollib/Systems.py | 30 ++++++++++++++++++++++-------- - 1 file changed, 22 insertions(+), 8 deletions(-) - -diff --git a/redfishtoollib/Systems.py b/redfishtoollib/Systems.py -index a0be4ad..e2cbe01 100644 ---- a/redfishtoollib/Systems.py -+++ b/redfishtoollib/Systems.py -@@ -182,7 +182,7 @@ class RfSystemsOperations(): - def __init__(self): - self.systemsPath=None - self.systemsCollectionDict=None -- -+ self.setBootOverride_legacy_mode=False - - def hello(self,sc,op,rft,cmdTop=False): - rft.printVerbose(4,"in hello") -@@ -584,13 +584,19 @@ class RfSystemsOperations(): - return(8,None,False,None) - - #form the patch data -- -- # Get the value of "BootSourceOverrideTarget" property and pass it in the patch request. -- # Some HW vendors need this property to be passed explicitly. -- if "BootSourceOverrideMode" in d["Boot"]: -- patchData={"Boot": {"BootSourceOverrideEnabled": enabledVal, "BootSourceOverrideTarget": targetVal, "BootSourceOverrideMode": d["Boot"]["BootSourceOverrideMode"] } } -- else: -+ if self.setBootOverride_legacy_mode: -+ # Some servers don't like the BootSourceOverrideMode added to the payload -+ # even when BootSourceOverrideMode is set in d["Boot"]. -+ # The caller has the option to set self.setBootOverride_legacy_mode True -+ # and call this function to use the 'legacy' mode patchData. - patchData={"Boot": {"BootSourceOverrideEnabled": enabledVal, "BootSourceOverrideTarget": targetVal } } -+ else: -+ # Get the value of "BootSourceOverrideTarget" property and pass it in the patch request. -+ # Some HW vendors need this property to be passed explicitly. -+ if "BootSourceOverrideMode" in d["Boot"]: -+ patchData={"Boot": {"BootSourceOverrideEnabled": enabledVal, "BootSourceOverrideTarget": targetVal, "BootSourceOverrideMode": d["Boot"]["BootSourceOverrideMode"] } } -+ else: -+ patchData={"Boot": {"BootSourceOverrideEnabled": enabledVal, "BootSourceOverrideTarget": targetVal } } - - #call the generic patch command to send the patch. This takes care of etag support - rc,r,j,d=rft.patchResource(rft, r, patchData) -@@ -605,7 +611,15 @@ class RfSystemsOperations(): - - - def setBootOverride(self, sc, op, rft, cmdTop=False, prop=None): -- return op.iterate_op(op.setBootOverride_single, sc, op, rft, cmdTop=cmdTop, prop=prop) -+ rc,r,j,d=op.iterate_op(op.setBootOverride_single, sc, op, rft, cmdTop=cmdTop, prop=prop) -+ if ( rc == 5 and r is not None ): -+ # added a retry in legacyMode if the http response -+ # in 'r' is - Bad Request -+ if r.status_code == 400: -+ rft.printVerbose(0," redfishtool: setBootOverride operation failed, retrying in legacy mode") -+ self.setBootOverride_legacy_mode = True -+ rc,r,j,d=op.iterate_op(op.setBootOverride_single, sc, op, rft, cmdTop=cmdTop, prop=prop) -+ return(rc,r,j,d) - - - def getProcessors(self,sc,op, rft, cmdTop=False, prop=None): diff --git a/bmc/redfishtool/debian/patches/series b/bmc/redfishtool/debian/patches/series index dad33d41f..4a700bd38 100644 --- a/bmc/redfishtool/debian/patches/series +++ b/bmc/redfishtool/debian/patches/series @@ -1,2 +1,2 @@ 0001-1.1.8-versioning.patch -0002-Add-retry-to-BootSourceOverrideMode-handling.patch +0002-Add-config-file-based-BootSourceOverrideMode-handlin.patch