Fix prestage orchestration details for skipped subclouds
Ensure that the 'details' field reflects the reason a subcloud is skipped during prestage orchestration. We use a new exception, StrategySkippedException, to signal the OrchThread that a subcloud is being skipped. This immediately transitions the subcloud strategy to complete, while preserving the reason for skipping in the strategy_step details. NOTE: this update also includes a minor update to the API parameters file, which was missed in the original feature commit (api-ref/source/parameters.yaml) Test Plan: PASS: - normal prestage orchestration - prestage orchestration with non-AIO-SX subcloud - subcloud is skipped - details populated and reported in details column of 'dcmanager strategy-step list' - subcloud deploy_status is returned to 'complete' - verify feature logging Closes-Bug: 1963967 Signed-off-by: Kyle MacLeod <kyle.macleod@windriver.com> Change-Id: I3408f274e3e04410872716b718130a3a27006c36
This commit is contained in:
parent
66e5517513
commit
9c4d1e9965
|
@ -22,7 +22,8 @@ subcloud_uri:
|
||||||
sw_update_strategy_type:
|
sw_update_strategy_type:
|
||||||
description: |
|
description: |
|
||||||
Filter to query a particular type of update strategy if it exists.
|
Filter to query a particular type of update strategy if it exists.
|
||||||
One of: `firmware`, `kube-rootca-update`, `kubernetes`, `patch`, `upgrade`
|
One of: `firmware`, `kube-rootca-update`, `kubernetes`, `patch`,
|
||||||
|
`prestage`, or `upgrade`.
|
||||||
in: path
|
in: path
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
|
|
@ -229,5 +229,12 @@ class StrategyStepNameNotFound(NotFound):
|
||||||
message = _("StrategyStep with name %(name)s doesn't exist.")
|
message = _("StrategyStep with name %(name)s doesn't exist.")
|
||||||
|
|
||||||
|
|
||||||
|
class StrategySkippedException(DCManagerException):
|
||||||
|
def __init__(self, details):
|
||||||
|
self.details = details
|
||||||
|
self.message = _(details)
|
||||||
|
super(StrategySkippedException, self).__init__()
|
||||||
|
|
||||||
|
|
||||||
class StrategyStoppedException(DCManagerException):
|
class StrategyStoppedException(DCManagerException):
|
||||||
message = _("Strategy has been stopped")
|
message = _("Strategy has been stopped")
|
||||||
|
|
|
@ -122,8 +122,12 @@ class OrchThread(threading.Thread):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def format_update_details(last_state, info):
|
def format_update_details(last_state, info):
|
||||||
# include the last state, since the current state is likely 'failed'
|
# Optionally include the last state, since the current state
|
||||||
details = "%s: %s" % (last_state, info)
|
# is likely 'failed'
|
||||||
|
if last_state:
|
||||||
|
details = "%s: %s" % (last_state, info)
|
||||||
|
else:
|
||||||
|
details = str(info)
|
||||||
# details cannot exceed 255 chars. truncate and add '..'
|
# details cannot exceed 255 chars. truncate and add '..'
|
||||||
if len(details) > 255:
|
if len(details) > 255:
|
||||||
details = details[:253] + '..'
|
details = details[:253] + '..'
|
||||||
|
@ -535,14 +539,26 @@ class OrchThread(threading.Thread):
|
||||||
self.strategy_step_update(strategy_step.subcloud_id,
|
self.strategy_step_update(strategy_step.subcloud_id,
|
||||||
state=next_state,
|
state=next_state,
|
||||||
details="")
|
details="")
|
||||||
except Exception as e:
|
except exceptions.StrategySkippedException as ex:
|
||||||
|
LOG.info("(%s) Skipping subcloud, Stage: %s, State: %s, Subcloud: %s"
|
||||||
|
% (self.update_type,
|
||||||
|
strategy_step.stage,
|
||||||
|
strategy_step.state,
|
||||||
|
self.get_region_name(strategy_step)))
|
||||||
|
# Transition immediately to complete. Update the details to show
|
||||||
|
# that this subcloud has been skipped
|
||||||
|
details = self.format_update_details(None, str(ex))
|
||||||
|
self.strategy_step_update(strategy_step.subcloud_id,
|
||||||
|
state=consts.STRATEGY_STATE_COMPLETE,
|
||||||
|
details=details)
|
||||||
|
except Exception as ex:
|
||||||
# Catch ALL exceptions and set the strategy to failed
|
# Catch ALL exceptions and set the strategy to failed
|
||||||
LOG.exception("(%s) Failed! Stage: %s, State: %s, Subcloud: %s"
|
LOG.exception("(%s) Failed! Stage: %s, State: %s, Subcloud: %s"
|
||||||
% (self.update_type,
|
% (self.update_type,
|
||||||
strategy_step.stage,
|
strategy_step.stage,
|
||||||
strategy_step.state,
|
strategy_step.state,
|
||||||
self.get_region_name(strategy_step)))
|
self.get_region_name(strategy_step)))
|
||||||
details = self.format_update_details(strategy_step.state, str(e))
|
details = self.format_update_details(strategy_step.state, str(ex))
|
||||||
self.strategy_step_update(strategy_step.subcloud_id,
|
self.strategy_step_update(strategy_step.subcloud_id,
|
||||||
state=consts.STRATEGY_STATE_FAILED,
|
state=consts.STRATEGY_STATE_FAILED,
|
||||||
details=details)
|
details=details)
|
||||||
|
|
|
@ -32,7 +32,12 @@ class PrestageState(BaseState):
|
||||||
"""Wrapper to ensure proper error handling"""
|
"""Wrapper to ensure proper error handling"""
|
||||||
try:
|
try:
|
||||||
self._do_state_action(strategy_step)
|
self._do_state_action(strategy_step)
|
||||||
|
except exceptions.StrategySkippedException:
|
||||||
|
# Move deploy_status back to complete (nothing has changed)
|
||||||
|
db_api.subcloud_update(
|
||||||
|
self.context, strategy_step.subcloud.id,
|
||||||
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
||||||
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
prestage.prestage_fail(self.context, strategy_step.subcloud.id)
|
prestage.prestage_fail(self.context, strategy_step.subcloud.id)
|
||||||
raise
|
raise
|
||||||
|
@ -95,19 +100,14 @@ class PrestagePreCheckState(PrestageState):
|
||||||
prestage.prestage_start(self.context, strategy_step.subcloud.id)
|
prestage.prestage_start(self.context, strategy_step.subcloud.id)
|
||||||
|
|
||||||
except exceptions.PrestagePreCheckFailedException as ex:
|
except exceptions.PrestagePreCheckFailedException as ex:
|
||||||
|
# We've either failed precheck or we want to skip this subcloud.
|
||||||
|
# Either way, we'll re-raise up to the base class for status
|
||||||
|
# update, and then let OrchThread take it from here
|
||||||
if ex.orch_skip:
|
if ex.orch_skip:
|
||||||
self.info_log(strategy_step,
|
raise exceptions.StrategySkippedException(details=str(ex))
|
||||||
"Pre-check: skipping subcloud: %s" % ex)
|
|
||||||
|
|
||||||
# Update the details to show that this subcloud has been skipped
|
self.error_log(strategy_step, "Pre-check failed: %s" % ex)
|
||||||
db_api.strategy_step_update(self.context,
|
raise
|
||||||
strategy_step.subcloud.id,
|
|
||||||
details=str(ex))
|
|
||||||
|
|
||||||
self.override_next_state(consts.STRATEGY_STATE_COMPLETE)
|
|
||||||
else:
|
|
||||||
self.info_log(strategy_step, "Pre-check failed: %s" % ex)
|
|
||||||
raise
|
|
||||||
else:
|
else:
|
||||||
self.info_log(strategy_step, "Pre-check pass")
|
self.info_log(strategy_step, "Pre-check pass")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue