175 lines
6.7 KiB
Python
175 lines
6.7 KiB
Python
#
|
|
# Copyright (c) 2022 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
import abc
|
|
|
|
from oslo_log import log as logging
|
|
|
|
from dcmanager.common import consts
|
|
from dcmanager.common import exceptions
|
|
from dcmanager.common import prestage
|
|
from dcmanager.common import utils
|
|
from dcmanager.db import api as db_api
|
|
from dcmanager.orchestrator.states.base import BaseState
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class PrestageState(BaseState):
|
|
"""Perform prepare operation"""
|
|
|
|
def __init__(self, next_state, region_name):
|
|
super(PrestageState, self).__init__(
|
|
next_state=next_state, region_name=region_name)
|
|
|
|
@abc.abstractmethod
|
|
def _do_state_action(self, strategy_step):
|
|
pass
|
|
|
|
def perform_state_action(self, strategy_step):
|
|
"""Wrapper to ensure proper error handling"""
|
|
try:
|
|
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:
|
|
prestage.prestage_fail(self.context, strategy_step.subcloud.id)
|
|
raise
|
|
|
|
# state machine can proceed to the next state
|
|
return self.next_state
|
|
|
|
|
|
class PrestagePreCheckState(PrestageState):
|
|
"""Perform pre check operations"""
|
|
|
|
def __init__(self, region_name):
|
|
super(PrestagePreCheckState, self).__init__(
|
|
next_state=consts.STRATEGY_STATE_PRESTAGE_PREPARE,
|
|
region_name=region_name)
|
|
|
|
@utils.synchronized('prestage-update-extra-args', external=True)
|
|
def _update_oam_floating_ip(self, strategy_step, oam_floating_ip):
|
|
# refresh the extra_args
|
|
extra_args = utils.get_sw_update_strategy_extra_args(self.context)
|
|
if 'oam_floating_ip_dict' in extra_args:
|
|
LOG.debug("Updating oam_floating_ip_dict: %s: %s",
|
|
strategy_step.subcloud.name, oam_floating_ip)
|
|
oam_floating_ip_dict = extra_args['oam_floating_ip_dict']
|
|
oam_floating_ip_dict[strategy_step.subcloud.name] \
|
|
= oam_floating_ip
|
|
else:
|
|
LOG.debug("Creating oam_floating_ip_dict: %s: %s",
|
|
strategy_step.subcloud.name, oam_floating_ip)
|
|
oam_floating_ip_dict = {
|
|
strategy_step.subcloud.name: oam_floating_ip
|
|
}
|
|
db_api.sw_update_strategy_update(
|
|
self.context, state=None, update_type=None,
|
|
additional_args={'oam_floating_ip_dict': oam_floating_ip_dict})
|
|
|
|
def _do_state_action(self, strategy_step):
|
|
extra_args = utils.get_sw_update_strategy_extra_args(self.context)
|
|
if extra_args is None:
|
|
message = "Prestage pre-check: missing all mandatory arguments"
|
|
self.error_log(strategy_step, message)
|
|
raise Exception(message)
|
|
|
|
payload = {
|
|
'sysadmin_password': extra_args['sysadmin_password'],
|
|
'force': extra_args['force']
|
|
}
|
|
try:
|
|
oam_floating_ip = prestage.validate_prestage(
|
|
strategy_step.subcloud, payload)
|
|
|
|
self._update_oam_floating_ip(strategy_step, oam_floating_ip)
|
|
if strategy_step.stage == 1:
|
|
# Note: this cleanup happens for every subcloud, but they are all
|
|
# processed before moving on to the next strategy step
|
|
# TODO(kmacleod) although this is a quick check, it is
|
|
# synchronized, so we may want to figure out a better
|
|
# way to only run this once
|
|
prestage.cleanup_failed_preparation()
|
|
prestage.prestage_start(self.context, strategy_step.subcloud.id)
|
|
|
|
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:
|
|
raise exceptions.StrategySkippedException(details=str(ex))
|
|
|
|
self.error_log(strategy_step, "Pre-check failed: %s" % ex)
|
|
raise
|
|
else:
|
|
self.info_log(strategy_step, "Pre-check pass")
|
|
|
|
|
|
class PrestagePrepareState(PrestageState):
|
|
"""Perform prepare operation"""
|
|
|
|
def __init__(self, region_name):
|
|
super(PrestagePrepareState, self).__init__(
|
|
next_state=consts.STRATEGY_STATE_PRESTAGE_PACKAGES,
|
|
region_name=region_name)
|
|
|
|
def _do_state_action(self, strategy_step):
|
|
extra_args = utils.get_sw_update_strategy_extra_args(self.context)
|
|
payload = {
|
|
'sysadmin_password': extra_args['sysadmin_password'],
|
|
'oam_floating_ip':
|
|
extra_args['oam_floating_ip_dict'][strategy_step.subcloud.name],
|
|
'force': extra_args['force']
|
|
}
|
|
prestage.prestage_prepare(self.context, strategy_step.subcloud, payload)
|
|
self.info_log(strategy_step, "Prepare finished")
|
|
|
|
|
|
class PrestagePackagesState(PrestageState):
|
|
"""Perform prestage packages operation"""
|
|
|
|
def __init__(self, region_name):
|
|
super(PrestagePackagesState, self).__init__(
|
|
next_state=consts.STRATEGY_STATE_PRESTAGE_IMAGES,
|
|
region_name=region_name)
|
|
|
|
def _do_state_action(self, strategy_step):
|
|
extra_args = utils.get_sw_update_strategy_extra_args(self.context)
|
|
payload = {
|
|
'sysadmin_password': extra_args['sysadmin_password'],
|
|
'oam_floating_ip':
|
|
extra_args['oam_floating_ip_dict'][strategy_step.subcloud.name],
|
|
'force': extra_args['force']
|
|
}
|
|
prestage.prestage_packages(self.context,
|
|
strategy_step.subcloud, payload)
|
|
self.info_log(strategy_step, "Packages finished")
|
|
|
|
|
|
class PrestageImagesState(PrestageState):
|
|
"""Perform prestage images operation"""
|
|
|
|
def __init__(self, region_name):
|
|
super(PrestageImagesState, self).__init__(
|
|
next_state=consts.STRATEGY_STATE_COMPLETE,
|
|
region_name=region_name)
|
|
|
|
def _do_state_action(self, strategy_step):
|
|
extra_args = utils.get_sw_update_strategy_extra_args(self.context)
|
|
payload = {
|
|
'sysadmin_password': extra_args['sysadmin_password'],
|
|
'oam_floating_ip':
|
|
extra_args['oam_floating_ip_dict'][strategy_step.subcloud.name],
|
|
'force': extra_args['force']
|
|
}
|
|
prestage.prestage_images(self.context, strategy_step.subcloud, payload)
|
|
self.info_log(strategy_step, "Images finished")
|
|
prestage.prestage_complete(self.context, strategy_step.subcloud.id)
|