Skip to content

Commit

Permalink
Merge pull request #173 from DMTF/Fix171-Reset-BIOS
Browse files Browse the repository at this point in the history
Added option to 'rf_bios_settings.py' to reset BIOS to the default settings
  • Loading branch information
mraineri authored Jan 17, 2025
2 parents de97229 + 774d382 commit ad1d84c
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 30 deletions.
13 changes: 11 additions & 2 deletions docs/rf_bios_settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A tool to manager BIOS settings for a system.
```
usage: rf_bios_settings.py [-h] --user USER --password PASSWORD --rhost RHOST
[--system SYSTEM] [--attribute name value]
[--workaround] [--debug]
[--reset] [--workaround] [--debug]
A tool to manager BIOS settings for a system
Expand All @@ -29,6 +29,7 @@ optional arguments:
--attribute name value, -a name value
Sets a BIOS attribute to a new value; can be supplied
multiple times to set multiple attributes
--reset, -reset Resets BIOS to the default settings
--workaround, -workaround
Indicates if workarounds should be attempted for non-
conformant services
Expand All @@ -42,8 +43,9 @@ It then traverses the system collection for the service to find the matching sys

The tool will then get the BIOS resource for the matching system.

* If *reset* is specified, it will perform a request to set BIOS to the default settings.
* If *attribute* is specified, it will update the BIOS resource with the new attribute value.
* If *attribute* is not specified, it will display the BIOS settings.
* Otherwise, it will display the BIOS settings.

Example; display attributes:

Expand Down Expand Up @@ -71,3 +73,10 @@ Example; set an attribute:
$ rf_bios_settings.py -u root -p root -r https://192.168.1.100 -a BiosMode Legacy
Setting BiosMode to Legacy...
```

Example; reset BIOS to the default settings:

```
$ rf_bios_settings.py -u root -p root -r https://192.168.1.100 -reset
Resetting the BIOS settings...
```
2 changes: 2 additions & 0 deletions redfish_utilities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
from .systems import get_system_bios
from .systems import set_system_bios
from .systems import print_system_bios
from .systems import reset_system_bios
from .tasks import poll_task_monitor
from .thermal_equipment import thermal_equipment_types
from .thermal_equipment import thermal_equipment_component_types
Expand Down Expand Up @@ -185,6 +186,7 @@
"get_system_bios",
"set_system_bios",
"print_system_bios",
"reset_system_bios",
"poll_task_monitor",
"thermal_equipment_types",
"thermal_equipment_component_types",
Expand Down
42 changes: 42 additions & 0 deletions redfish_utilities/systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ class RedfishSystemBiosInvalidSettingsError(Exception):
pass


class RedfishSystemResetBiosNotFoundError(Exception):
"""
Raised when the BIOS resource does not support the reset BIOS action
"""

pass


class RedfishVirtualMediaNotFoundError(Exception):
"""
Raised when a system does not have any virtual media available
Expand Down Expand Up @@ -788,3 +796,37 @@ def print_system_bios(current_settings, future_settings):
)

print("")


def reset_system_bios(context, system_id=None):
"""
Finds a system matching the given ID and resets the BIOS settings
Args:
context: The Redfish client object with an open session
system_id: The system to locate; if None, perform on the only system
Returns:
The response of the reset operation
"""

# Locate the system
system = get_system(context, system_id)

# Get the Bios resource
if "Bios" not in system.dict:
raise RedfishSystemBiosNotFoundError("System '{}' does not support representing BIOS".format(system.dict["Id"]))
bios = context.get(system.dict["Bios"]["@odata.id"])

# Locate the ResetBios action and invoke it
if "Actions" not in bios.dict:
raise RedfishSystemResetBiosNotFoundError(
"System '{}' does not support the reset BIOS action".format(system.dict["Id"])
)
if "#Bios.ResetBios" not in bios.dict["Actions"]:
raise RedfishSystemResetBiosNotFoundError(
"System '{}' does not support the reset BIOS action".format(system.dict["Id"])
)
response = context.post(bios.dict["Actions"]["#Bios.ResetBios"]["target"], body={})
verify_response(response)
return response
60 changes: 33 additions & 27 deletions scripts/rf_bios_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
action="append",
help="Sets a BIOS attribute to a new value; can be supplied multiple times to set multiple attributes",
)
argget.add_argument("--reset", "-reset", action="store_true", help="Resets BIOS to the default settings")
argget.add_argument(
"--workaround",
"-workaround",
Expand Down Expand Up @@ -69,35 +70,40 @@

exit_code = 0
try:
# Get the BIOS settings
current_settings, future_settings = redfish_utilities.get_system_bios(redfish_obj, args.system)
if args.reset:
# Reset BIOS to the default settings
print("Resetting the BIOS settings...")
redfish_utilities.reset_system_bios(redfish_obj, args.system)
else:
# Get the BIOS settings
current_settings, future_settings = redfish_utilities.get_system_bios(redfish_obj, args.system)

if args.attribute is not None:
new_settings = {}
for attribute in args.attribute:
# Based on the current settings, determine the appropriate data type for the new setting
new_value = attribute[1]
if attribute[0] in current_settings:
if isinstance(current_settings[attribute[0]], bool):
# Boolean; convert from a string
if new_value.lower() == "true":
new_value = True
else:
new_value = False
elif isinstance(current_settings[attribute[0]], (int, float)):
# Integer or float; go by the user input to determine how to convert since the current value may be truncated
try:
new_value = int(new_value)
except Exception:
new_value = float(new_value)
if args.attribute is not None:
new_settings = {}
for attribute in args.attribute:
# Based on the current settings, determine the appropriate data type for the new setting
new_value = attribute[1]
if attribute[0] in current_settings:
if isinstance(current_settings[attribute[0]], bool):
# Boolean; convert from a string
if new_value.lower() == "true":
new_value = True
else:
new_value = False
elif isinstance(current_settings[attribute[0]], (int, float)):
# Integer or float; go by the user input to determine how to convert since the current value may be truncated
try:
new_value = int(new_value)
except Exception:
new_value = float(new_value)

# Set the specified attribute to the new value
new_settings[attribute[0]] = new_value
print("Setting {} to {}...".format(attribute[0], attribute[1]))
redfish_utilities.set_system_bios(redfish_obj, new_settings, args.system)
else:
# Print the BIOS settings
redfish_utilities.print_system_bios(current_settings, future_settings)
# Set the specified attribute to the new value
new_settings[attribute[0]] = new_value
print("Setting {} to {}...".format(attribute[0], attribute[1]))
redfish_utilities.set_system_bios(redfish_obj, new_settings, args.system)
else:
# Print the BIOS settings
redfish_utilities.print_system_bios(current_settings, future_settings)
except Exception as e:
if args.debug:
logger.error("Caught exception:\n\n{}\n".format(traceback.format_exc()))
Expand Down
7 changes: 6 additions & 1 deletion scripts/rf_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,12 @@ def print_error_payload(response):
help="The apply time for the update",
choices=redfish_utilities.operation_apply_times,
)
argget.add_argument("--timeout", "-timeout", type=int, help="The timeout, in seconds, to transfer the image; by default this is 2 seconds per MB")
argget.add_argument(
"--timeout",
"-timeout",
type=int,
help="The timeout, in seconds, to transfer the image; by default this is 2 seconds per MB",
)
argget.add_argument("--debug", action="store_true", help="Creates debug file showing HTTP traces and exceptions")
args = argget.parse_args()

Expand Down

0 comments on commit ad1d84c

Please sign in to comment.