Skip to content

Commit 98c8e09

Browse files
authored
Merge pull request #193 from DMTF/Fix191-Auto-Task-Handling
Added new global config to automatically internalize task monitoring for select operations
2 parents 2811e17 + a5e4cd6 commit 98c8e09

File tree

4 files changed

+49
-30
lines changed

4 files changed

+49
-30
lines changed

redfish_utilities/accounts.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,25 @@
99
File : accounts.py
1010
1111
Brief : This file contains the definitions and functionalities for managing
12-
accounts on a Redfish Service
12+
accounts on a Redfish service
1313
"""
1414

1515
from .messages import verify_response
16+
from .tasks import poll_task_monitor
17+
from . import config
1618

1719

1820
class RedfishAccountCollectionNotFoundError(Exception):
1921
"""
20-
Raised when the Account Service or Account Collection cannot be found
22+
Raised when the account service or account collection cannot be found
2123
"""
2224

2325
pass
2426

2527

2628
class RedfishAccountNotFoundError(Exception):
2729
"""
28-
Raised when the Account Service or Account Collection cannot be found
30+
Raised when the account service or account collection cannot be found
2931
"""
3032

3133
pass
@@ -52,7 +54,7 @@ def get_users(context):
5254

5355
user_list = []
5456

55-
# Go through each Account in the Account Collection
57+
# Go through each account in the account collection
5658
account_col = context.get(get_account_collection(context), None)
5759
for account_member in account_col.dict["Members"]:
5860
account = context.get(account_member["@odata.id"], None)
@@ -128,6 +130,8 @@ def add_user(context, user_name, password, role):
128130
user_name
129131
)
130132
)
133+
if config.__auto_task_handling__:
134+
response = poll_task_monitor(context, response, silent=True)
131135
verify_response(response)
132136
return response
133137

@@ -154,6 +158,8 @@ def delete_user(context, user_name):
154158
# Some also do not allow for both Enabled and UserName to be modified simultaneously
155159
modify_user(context, user_name, new_enabled=False)
156160
return modify_user(context, user_name, new_name="")
161+
if config.__auto_task_handling__:
162+
response = poll_task_monitor(context, response, silent=True)
157163
verify_response(response)
158164
return response
159165

@@ -203,6 +209,8 @@ def modify_user(
203209

204210
# Update the user
205211
response = context.patch(user_uri, body=new_info, headers={"If-Match": user_info.getheader("ETag")})
212+
if config.__auto_task_handling__:
213+
response = poll_task_monitor(context, response, silent=True)
206214
verify_response(response)
207215
return response
208216

@@ -218,17 +226,17 @@ def get_account_collection(context):
218226
The URI for the account collection
219227
"""
220228

221-
# Get the Service Root to find the Account Service
229+
# Get the service root to find the account service
222230
service_root = context.get("/redfish/v1")
223231
if "AccountService" not in service_root.dict:
224-
# No Account Service
225-
raise RedfishAccountCollectionNotFoundError("Service does not contain an Account Service")
232+
# No account service
233+
raise RedfishAccountCollectionNotFoundError("Service does not contain an account service")
226234

227-
# Get the Account Service to find the Account Collection
235+
# Get the account service to find the account collection
228236
account_service = context.get(service_root.dict["AccountService"]["@odata.id"])
229237
if "Accounts" not in account_service.dict:
230238
# No Account Collection
231-
raise RedfishAccountCollectionNotFoundError("Service does not contain an Account Collection")
239+
raise RedfishAccountCollectionNotFoundError("Service does not contain an account collection")
232240

233241
return account_service.dict["Accounts"]["@odata.id"]
234242

redfish_utilities/config.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@
99
File : config.py
1010
1111
Brief : This file contains configuration settings for the module; useful for
12-
debugging issues encountered on live systems
12+
debugging issues encountered on live systems or configuring global
13+
options.
1314
"""
1415

1516
# Leverage known workarounds for non-conformant services, such as bypassing
1617
# unexpected 4XX responses, missing properties, and malformed URIs
1718
__workarounds__ = False
19+
20+
# Automate task handling for POST/PATCH/PUT/DELETE operations that should
21+
# always be "fast"
22+
__auto_task_handling__ = False

redfish_utilities/tasks.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@
1616
import time
1717

1818

19-
def poll_task_monitor(context, response):
19+
def poll_task_monitor(context, response, silent=False):
2020
"""
2121
Monitors a task monitor until it's complete and prints out progress
2222
NOTE: This call will block until the task is complete
2323
2424
Args:
2525
context: The Redfish client object with an open session
2626
response: The initial response from the operation that produced the task
27+
silent: Indicates if the task progress is to be hidden
2728
2829
Returns:
2930
The final response of the request
@@ -37,23 +38,24 @@ def poll_task_monitor(context, response):
3738
task_monitor = response
3839
while task_monitor.is_processing:
3940
# Print the progress
40-
task_state = None
41-
task_percent = None
42-
try:
43-
task_state = task_monitor.dict.get("TaskState", None)
44-
task_percent = task_monitor.dict.get("PercentComplete", None)
45-
except Exception:
46-
# 202 responses are allowed to not have a response body
47-
pass
48-
if task_state is None:
49-
task_state = "Running"
50-
if task_percent is None:
51-
progress_str = "Task is {}\r".format(task_state)
52-
else:
53-
progress_str = "Task is {}: {}% complete\r".format(task_state, task_percent)
54-
sys.stdout.write("\x1b[2K")
55-
sys.stdout.write(progress_str)
56-
sys.stdout.flush()
41+
if silent is False:
42+
task_state = None
43+
task_percent = None
44+
try:
45+
task_state = task_monitor.dict.get("TaskState", None)
46+
task_percent = task_monitor.dict.get("PercentComplete", None)
47+
except Exception:
48+
# 202 responses are allowed to not have a response body
49+
pass
50+
if task_state is None:
51+
task_state = "Running"
52+
if task_percent is None:
53+
progress_str = "Task is {}\r".format(task_state)
54+
else:
55+
progress_str = "Task is {}: {}% complete\r".format(task_state, task_percent)
56+
sys.stdout.write("\x1b[2K")
57+
sys.stdout.write(progress_str)
58+
sys.stdout.flush()
5759

5860
# Sleep for the requested time
5961
retry_time = response.retry_after
@@ -63,7 +65,8 @@ def poll_task_monitor(context, response):
6365

6466
# Check the monitor for an update
6567
task_monitor = response.monitor(context)
66-
sys.stdout.write("\x1b[2K")
67-
print("Task is Done!")
68+
if silent is False:
69+
sys.stdout.write("\x1b[2K")
70+
print("Task is Done!")
6871

6972
return task_monitor

scripts/rf_accounts.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
argget.add_argument("--debug", action="store_true", help="Creates debug file showing HTTP traces and exceptions")
5555
args = argget.parse_args()
5656

57+
# Always let the calls for account management block until the underlying task is complete
58+
redfish_utilities.config.__auto_task_handling__ = True
59+
5760
if args.debug:
5861
log_file = "rf_accounts-{}.log".format(datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S"))
5962
log_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"

0 commit comments

Comments
 (0)