Add robustness to capturing task info from Drydock

In the case of being able to gather informational task info, if there is
any exception, report the exception and move on, rather than failing
hard.

Change-Id: I677f9c375549f0ff421aa322c561a8bc7cb848d0
This commit is contained in:
Bryan Strassner 2018-06-27 13:14:46 -05:00
parent c7a9c65c88
commit 90944fc768
1 changed files with 50 additions and 40 deletions

View File

@ -245,47 +245,57 @@ class DrydockNodesOperator(DrydockBaseOperator):
task. Drydock is assumed to roll up overall success to the top level. task. Drydock is assumed to roll up overall success to the top level.
""" """
success_nodes = [] success_nodes = []
task_dict = self.get_task_dict(task_id) try:
task_status = task_dict.get('status', "Not Specified") task_dict = self.get_task_dict(task_id)
task_result = task_dict.get('result') task_status = task_dict.get('status', "Not Specified")
if task_result is None: task_result = task_dict.get('result')
LOG.warn("Task result is missing for task %s, with status %s." if task_result is None:
" Neither successes nor further details can be extracted" LOG.warn("Task result is missing for task %s, with status %s."
" from this result", " Neither successes nor further details can be"
task_id, task_status) " extracted from this result",
else: task_id, task_status)
if extend_success: else:
try: if extend_success:
# successes and failures on the task result drive the try:
# interpretation of success or failure for this workflow. # successes and failures on the task result drive the
# - Any node that is _only_ success for a task is a # interpretation of success or failure for this
# success to us. # workflow.
# - Any node that is listed as a failure is a failure. # - Any node that is _only_ success for a task is a
# This implies that a node listed as a success and a # success to us.
# failure is a failure. E.g. some subtasks succeeded and # - Any node that is listed as a failure is a failure.
# some failed # This implies that a node listed as a success and a
t_successes = task_result.get('successes', []) # failure is a failure. E.g. some subtasks succeeded
t_failures = task_result.get('failures', []) # and some failed
actual_successes = set(t_successes) - set(t_failures) t_successes = task_result.get('successes', [])
# acquire the successes from success nodes t_failures = task_result.get('failures', [])
success_nodes.extend(actual_successes) actual_successes = set(t_successes) - set(t_failures)
LOG.info("Nodes <%s> added as successes for task %s", # acquire the successes from success nodes
", ".join(success_nodes), task_id) success_nodes.extend(actual_successes)
except KeyError: LOG.info("Nodes <%s> added as successes for task %s",
# missing key on the path to getting nodes - don't add any ", ".join(success_nodes), task_id)
LOG.warn("Missing successes field on result of task %s, " except KeyError:
"but a success field was expected. No successes" # missing key on the path to getting nodes - don't add
" can be extracted from this result", LOG.warn(
task_id) "Missing successes field on result of task %s, "
pass "but a success field was expected. No successes"
_report_task_info(task_id, task_result, task_status) " can be extracted from this result", task_id
)
pass
_report_task_info(task_id, task_result, task_status)
# for each child, report only the step info, do not add to overall
# success list.
for ch_task_id in task_dict.get('subtask_id_list', []):
success_nodes.extend(
self._get_successes_for_task(ch_task_id,
extend_success=False)
)
except Exception:
# since we are reporting task results, if we can't get the
# results, do not block the processing.
LOG.warn("Failed to retrieve a result for task %s. Exception "
"follows:", task_id, exc_info=True)
# for each child, report only the step info, do not add to overall
# success list.
for ch_task_id in task_dict.get('subtask_id_list', []):
success_nodes.extend(
self._get_successes_for_task(ch_task_id, extend_success=False)
)
# deduplicate and return # deduplicate and return
return set(success_nodes) return set(success_nodes)