Execute software deploy delete in Software DC orchestration
This commit implements the execution of `software deploy delete` within the finish_strategy state. Additionally, it removes outdated committed release code and introduces custom exceptions to handle state errors effectively. Test Plan (patch only): PASS - Apply a sw-deploy-strategy - Release in deploying state after apply_vim_strategy state - Release changed to deployed state in finish_strategy state - software deploy delete executed Story: 2010676 Task: 50543 Change-Id: If40f0ec7298270fe4a2a7306c3132eba3050e62c Signed-off-by: Hugo Brito <hugo.brito@windriver.com>
This commit is contained in:

committed by
Hugo Nicodemos

parent
82db04c240
commit
8fbdbec0d4
@@ -18,6 +18,7 @@ ABORTING = "aborting"
|
|||||||
AVAILABLE = "available"
|
AVAILABLE = "available"
|
||||||
COMMITTED = "committed"
|
COMMITTED = "committed"
|
||||||
DEPLOYED = "deployed"
|
DEPLOYED = "deployed"
|
||||||
|
DEPLOYING = "deploying"
|
||||||
REMOVING = "removing"
|
REMOVING = "removing"
|
||||||
UNAVAILABLE = "unavailable"
|
UNAVAILABLE = "unavailable"
|
||||||
|
|
||||||
@@ -70,6 +71,12 @@ class SoftwareClient(base.DriverBase):
|
|||||||
response = requests.post(url, headers=self.headers, timeout=timeout)
|
response = requests.post(url, headers=self.headers, timeout=timeout)
|
||||||
return self._handle_response(response, operation="Deploy precheck")
|
return self._handle_response(response, operation="Deploy precheck")
|
||||||
|
|
||||||
|
def deploy_delete(self, timeout=REST_DEFAULT_TIMEOUT):
|
||||||
|
"""Deploy delete"""
|
||||||
|
url = self.endpoint + "/deploy"
|
||||||
|
response = requests.delete(url, headers=self.headers, timeout=timeout)
|
||||||
|
return self._handle_response(response, operation="Deploy delete")
|
||||||
|
|
||||||
def commit_patch(self, releases, timeout=REST_DEFAULT_TIMEOUT):
|
def commit_patch(self, releases, timeout=REST_DEFAULT_TIMEOUT):
|
||||||
"""Commit patch"""
|
"""Commit patch"""
|
||||||
release_str = "/".join(releases)
|
release_str = "/".join(releases)
|
||||||
@@ -86,5 +93,5 @@ class SoftwareClient(base.DriverBase):
|
|||||||
if isinstance(data, dict) and data.get("error"):
|
if isinstance(data, dict) and data.get("error"):
|
||||||
message = f"{operation} failed with error: {data.get('error')}"
|
message = f"{operation} failed with error: {data.get('error')}"
|
||||||
LOG.error(message)
|
LOG.error(message)
|
||||||
raise Exception(message)
|
raise exceptions.SoftwareDataException(endpoint=response.url, error=message)
|
||||||
return data
|
return data
|
||||||
|
@@ -121,6 +121,10 @@ class ApiException(DCCommonException):
|
|||||||
message = _("%(endpoint)s failed with status code: %(rc)d")
|
message = _("%(endpoint)s failed with status code: %(rc)d")
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareDataException(DCCommonException):
|
||||||
|
message = _("%(endpoint)s failed with data error: %(error)s")
|
||||||
|
|
||||||
|
|
||||||
class SystemPeerNotFound(NotFound):
|
class SystemPeerNotFound(NotFound):
|
||||||
message = _("System Peer %(system_peer)s not found")
|
message = _("System Peer %(system_peer)s not found")
|
||||||
|
|
||||||
|
@@ -250,6 +250,26 @@ class PreCheckFailedException(DCManagerException):
|
|||||||
message = _("Subcloud %(subcloud)s upgrade precheck failed: %(details)s")
|
message = _("Subcloud %(subcloud)s upgrade precheck failed: %(details)s")
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwarePreCheckFailedException(DCManagerException):
|
||||||
|
message = _("Subcloud %(subcloud)s software deploy precheck failed: %(details)s")
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareListFailedException(DCManagerException):
|
||||||
|
message = _("Subcloud %(subcloud)s software list failed: %(details)s")
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareDeleteFailedException(DCManagerException):
|
||||||
|
message = _("Subcloud %(subcloud)s sofware delete failed: %(details)s")
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareDeployCommitFailedException(DCManagerException):
|
||||||
|
message = _("Subcloud %(subcloud)s sofware deploy commit failed: %(details)s")
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareDeployDeleteFailedException(DCManagerException):
|
||||||
|
message = _("Subcloud %(subcloud)s sofware deploy delete failed: %(details)s")
|
||||||
|
|
||||||
|
|
||||||
class PrestagePreCheckFailedException(DCManagerException):
|
class PrestagePreCheckFailedException(DCManagerException):
|
||||||
"""PrestagePreCheckFailedException
|
"""PrestagePreCheckFailedException
|
||||||
|
|
||||||
|
@@ -44,9 +44,11 @@ class CreatingVIMStrategyState(BaseState):
|
|||||||
extra_args = utils.get_sw_update_strategy_extra_args(self.context)
|
extra_args = utils.get_sw_update_strategy_extra_args(self.context)
|
||||||
release_id = extra_args.get(consts.EXTRA_ARGS_RELEASE_ID)
|
release_id = extra_args.get(consts.EXTRA_ARGS_RELEASE_ID)
|
||||||
opts_dict["release_id"] = release_id
|
opts_dict["release_id"] = release_id
|
||||||
|
# Create rollback = False since DC orchestration do not support rollback
|
||||||
|
opts_dict["rollback"] = False
|
||||||
|
|
||||||
# Call the API to build the VIM strategy
|
# Call the API to build the VIM strategy
|
||||||
# release will be sent as a **kwargs value for sw-deploy strategy
|
# release and rollback will be sent as a **kwargs value for sw-deploy strategy
|
||||||
subcloud_strategy = self.get_vim_client(region).create_strategy(
|
subcloud_strategy = self.get_vim_client(region).create_strategy(
|
||||||
self.strategy_name,
|
self.strategy_name,
|
||||||
opts_dict['storage-apply-type'],
|
opts_dict['storage-apply-type'],
|
||||||
@@ -54,7 +56,9 @@ class CreatingVIMStrategyState(BaseState):
|
|||||||
opts_dict['max-parallel-workers'],
|
opts_dict['max-parallel-workers'],
|
||||||
opts_dict['default-instance-action'],
|
opts_dict['default-instance-action'],
|
||||||
opts_dict['alarm-restriction-type'],
|
opts_dict['alarm-restriction-type'],
|
||||||
release=opts_dict.get('release_id'),)
|
release=opts_dict.get('release_id'),
|
||||||
|
rollback=opts_dict.get('rollback'),
|
||||||
|
)
|
||||||
|
|
||||||
# a successful API call to create MUST set the state be 'building'
|
# a successful API call to create MUST set the state be 'building'
|
||||||
if subcloud_strategy.state != vim.STATE_BUILDING:
|
if subcloud_strategy.state != vim.STATE_BUILDING:
|
||||||
|
@@ -3,12 +3,15 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
||||||
from dccommon.drivers.openstack import software_v1
|
from dccommon.drivers.openstack import software_v1
|
||||||
from dcmanager.common import consts
|
from dcmanager.common import consts
|
||||||
from dcmanager.common.exceptions import StrategyStoppedException
|
from dcmanager.common import exceptions
|
||||||
|
from dcmanager.db import api as db_api
|
||||||
from dcmanager.orchestrator.states.base import BaseState
|
from dcmanager.orchestrator.states.base import BaseState
|
||||||
from dcmanager.orchestrator.states.software.cache.cache_specifications import \
|
from dcmanager.orchestrator.states.software.cache.cache_specifications import (
|
||||||
REGION_ONE_RELEASE_USM_CACHE_TYPE
|
REGION_ONE_RELEASE_USM_CACHE_TYPE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FinishStrategyState(BaseState):
|
class FinishStrategyState(BaseState):
|
||||||
@@ -25,68 +28,129 @@ class FinishStrategyState(BaseState):
|
|||||||
|
|
||||||
self.info_log(strategy_step, "Finishing software strategy")
|
self.info_log(strategy_step, "Finishing software strategy")
|
||||||
|
|
||||||
regionone_committed_releases = self._read_from_cache(
|
subcloud = db_api.subcloud_get(self.context, strategy_step.subcloud.id)
|
||||||
REGION_ONE_RELEASE_USM_CACHE_TYPE,
|
|
||||||
state=software_v1.COMMITTED
|
regionone_deployed_releases = self._read_from_cache(
|
||||||
|
REGION_ONE_RELEASE_USM_CACHE_TYPE, state=software_v1.DEPLOYED
|
||||||
)
|
)
|
||||||
|
|
||||||
self.debug_log(
|
self.debug_log(
|
||||||
strategy_step,
|
strategy_step,
|
||||||
f"regionone_committed_releases: {regionone_committed_releases}"
|
f"regionone_deployed_releases: {regionone_deployed_releases}",
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
software_client = self.get_software_client(self.region_name)
|
software_client = self.get_software_client(self.region_name)
|
||||||
subcloud_releases = software_client.list()
|
subcloud_releases = software_client.list()
|
||||||
except Exception:
|
except Exception:
|
||||||
message = ("Cannot retrieve subcloud releases. Please see logs for "
|
message = "Cannot retrieve subcloud releases. Please see logs for details."
|
||||||
"details.")
|
|
||||||
self.exception_log(strategy_step, message)
|
self.exception_log(strategy_step, message)
|
||||||
raise Exception(message)
|
raise exceptions.SoftwareListFailedException(
|
||||||
|
subcloud=subcloud.name,
|
||||||
|
details=message,
|
||||||
|
)
|
||||||
|
|
||||||
self.debug_log(strategy_step,
|
self.debug_log(strategy_step, f"Releases for subcloud: {subcloud_releases}")
|
||||||
f"Releases for subcloud: {subcloud_releases}")
|
|
||||||
|
|
||||||
releases_to_commit = list()
|
# For this subcloud, determine which releases should be committed,
|
||||||
releases_to_delete = list()
|
# which should be deleted and which should finish the deploy.
|
||||||
|
|
||||||
# For this subcloud, determine which releases should be committed and
|
|
||||||
# which should be deleted.
|
|
||||||
releases_to_delete = [
|
releases_to_delete = [
|
||||||
release["release_id"] for release in subcloud_releases
|
release["release_id"]
|
||||||
|
for release in subcloud_releases
|
||||||
if release["state"] in (software_v1.AVAILABLE, software_v1.UNAVAILABLE)
|
if release["state"] in (software_v1.AVAILABLE, software_v1.UNAVAILABLE)
|
||||||
]
|
]
|
||||||
releases_to_commit = [
|
|
||||||
release["release_id"] for release in subcloud_releases
|
# TODO(nicodemos): Update releases_to_commit and handle it after
|
||||||
if release["state"] == software_v1.DEPLOYED
|
# `software commit` is implemented
|
||||||
and any(
|
releases_to_commit = []
|
||||||
release["release_id"] == release_regionone["release_id"]
|
|
||||||
for release_regionone in regionone_committed_releases
|
releases_to_deploy_delete = [
|
||||||
)
|
release["release_id"]
|
||||||
|
for release in subcloud_releases
|
||||||
|
if release["state"] == software_v1.DEPLOYING
|
||||||
]
|
]
|
||||||
|
|
||||||
if releases_to_delete:
|
if releases_to_delete:
|
||||||
self.info_log(strategy_step, f"Deleting releases {releases_to_delete}")
|
self._handle_release_delete(
|
||||||
try:
|
strategy_step, software_client, subcloud, releases_to_delete
|
||||||
software_client.delete(releases_to_delete)
|
)
|
||||||
except Exception:
|
|
||||||
message = ("Cannot delete releases from subcloud. Please see "
|
|
||||||
"logs for details.")
|
|
||||||
self.exception_log(strategy_step, message)
|
|
||||||
raise Exception(message)
|
|
||||||
|
|
||||||
if self.stopped():
|
if self.stopped():
|
||||||
raise StrategyStoppedException()
|
raise exceptions.StrategyStoppedException()
|
||||||
|
|
||||||
if releases_to_commit:
|
if releases_to_commit:
|
||||||
self.info_log(strategy_step,
|
self._handle_deploy_commit(
|
||||||
f"Committing releases {releases_to_commit} to subcloud")
|
strategy_step, software_client, subcloud, releases_to_commit
|
||||||
try:
|
)
|
||||||
software_client.commit_patch(releases_to_commit)
|
|
||||||
except Exception:
|
if releases_to_deploy_delete:
|
||||||
message = ("Cannot commit releases to subcloud. Please see logs for "
|
self._handle_deploy_delete(
|
||||||
"details.")
|
strategy_step,
|
||||||
self.exception_log(strategy_step, message)
|
software_client,
|
||||||
raise Exception(message)
|
subcloud,
|
||||||
|
releases_to_deploy_delete,
|
||||||
|
regionone_deployed_releases,
|
||||||
|
)
|
||||||
|
|
||||||
return self.next_state
|
return self.next_state
|
||||||
|
|
||||||
|
def _handle_release_delete(
|
||||||
|
self, strategy_step, software_client, subcloud, releases_to_delete
|
||||||
|
):
|
||||||
|
self.info_log(strategy_step, f"Deleting releases {releases_to_delete}")
|
||||||
|
try:
|
||||||
|
software_client.delete(releases_to_delete)
|
||||||
|
except Exception:
|
||||||
|
message = (
|
||||||
|
"Cannot delete releases from subcloud. Please see logs for details."
|
||||||
|
)
|
||||||
|
self.exception_log(strategy_step, message)
|
||||||
|
raise exceptions.SoftwareDeleteFailedException(
|
||||||
|
subcloud=subcloud.name,
|
||||||
|
details=message,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _handle_deploy_commit(
|
||||||
|
self, strategy_step, software_client, subcloud, releases_to_commit
|
||||||
|
):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
# If there are releases in deploying state and it's deployed in the regionone,
|
||||||
|
# they should be finished executing the deploy delete operation.
|
||||||
|
def _handle_deploy_delete(
|
||||||
|
self,
|
||||||
|
strategy_step,
|
||||||
|
software_client,
|
||||||
|
subcloud,
|
||||||
|
releases_to_deploy_delete,
|
||||||
|
regionone_deployed_releases,
|
||||||
|
):
|
||||||
|
if not any(
|
||||||
|
release_id == release_regionone["release_id"]
|
||||||
|
for release_id in releases_to_deploy_delete
|
||||||
|
for release_regionone in regionone_deployed_releases
|
||||||
|
):
|
||||||
|
message = (
|
||||||
|
f"There is a deploying release on subcloud {subcloud.name} "
|
||||||
|
"that is not deployed in System Controller. Aborting."
|
||||||
|
)
|
||||||
|
self.error_log(strategy_step, message)
|
||||||
|
raise exceptions.SoftwareDeployDeleteFailedException(
|
||||||
|
subcloud=subcloud.name,
|
||||||
|
details=message,
|
||||||
|
)
|
||||||
|
self.info_log(
|
||||||
|
strategy_step,
|
||||||
|
f"Finishing releases {releases_to_deploy_delete} to subcloud",
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
software_client.deploy_delete()
|
||||||
|
except Exception:
|
||||||
|
message = (
|
||||||
|
"Cannot finish deploy delete on subcloud. Please see logs for details."
|
||||||
|
)
|
||||||
|
self.exception_log(strategy_step, message)
|
||||||
|
raise exceptions.SoftwareDeployDeleteFailedException(
|
||||||
|
subcloud=subcloud.name,
|
||||||
|
details=message,
|
||||||
|
)
|
||||||
|
@@ -58,7 +58,7 @@ class PreCheckState(BaseState):
|
|||||||
except Exception:
|
except Exception:
|
||||||
details = f"Get current strategy failed on subcloud: {subcloud.name}"
|
details = f"Get current strategy failed on subcloud: {subcloud.name}"
|
||||||
self.error_log(strategy_step, details)
|
self.error_log(strategy_step, details)
|
||||||
raise exceptions.PreCheckFailedException(
|
raise exceptions.SoftwarePreCheckFailedException(
|
||||||
subcloud=subcloud.name,
|
subcloud=subcloud.name,
|
||||||
details=details,
|
details=details,
|
||||||
)
|
)
|
||||||
@@ -78,7 +78,7 @@ class PreCheckState(BaseState):
|
|||||||
f"subcloud {subcloud.name}. Aborting."
|
f"subcloud {subcloud.name}. Aborting."
|
||||||
)
|
)
|
||||||
self.error_log(strategy_step, details)
|
self.error_log(strategy_step, details)
|
||||||
raise exceptions.PreCheckFailedException(
|
raise exceptions.SoftwarePreCheckFailedException(
|
||||||
subcloud=subcloud.name,
|
subcloud=subcloud.name,
|
||||||
details=details,
|
details=details,
|
||||||
)
|
)
|
||||||
@@ -102,7 +102,10 @@ class PreCheckState(BaseState):
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
message = f"Cannot retrieve release list : {exc}."
|
message = f"Cannot retrieve release list : {exc}."
|
||||||
self.exception_log(strategy_step, message)
|
self.exception_log(strategy_step, message)
|
||||||
raise Exception(message)
|
raise exceptions.SoftwareListFailedException(
|
||||||
|
subcloud=subcloud.name,
|
||||||
|
details=message,
|
||||||
|
)
|
||||||
|
|
||||||
self._check_prestaged_data(
|
self._check_prestaged_data(
|
||||||
strategy_step,
|
strategy_step,
|
||||||
@@ -129,7 +132,7 @@ class PreCheckState(BaseState):
|
|||||||
f"subcloud: {subcloud_name}"
|
f"subcloud: {subcloud_name}"
|
||||||
)
|
)
|
||||||
self.error_log(strategy_step, details)
|
self.error_log(strategy_step, details)
|
||||||
raise exceptions.PreCheckFailedException(
|
raise exceptions.SoftwarePreCheckFailedException(
|
||||||
subcloud=subcloud_name,
|
subcloud=subcloud_name,
|
||||||
details=details,
|
details=details,
|
||||||
)
|
)
|
||||||
@@ -140,7 +143,7 @@ class PreCheckState(BaseState):
|
|||||||
f"{strategy_state}. Aborting."
|
f"{strategy_state}. Aborting."
|
||||||
)
|
)
|
||||||
self.error_log(strategy_step, details)
|
self.error_log(strategy_step, details)
|
||||||
raise exceptions.PreCheckFailedException(
|
raise exceptions.SoftwarePreCheckFailedException(
|
||||||
subcloud=subcloud_name,
|
subcloud=subcloud_name,
|
||||||
details=details,
|
details=details,
|
||||||
)
|
)
|
||||||
@@ -163,7 +166,7 @@ class PreCheckState(BaseState):
|
|||||||
if not (is_available_in_subcloud and regionone_deployed_release):
|
if not (is_available_in_subcloud and regionone_deployed_release):
|
||||||
details = f"Release {release_id} is not prestaged. Aborting."
|
details = f"Release {release_id} is not prestaged. Aborting."
|
||||||
self.error_log(strategy_step, details)
|
self.error_log(strategy_step, details)
|
||||||
raise exceptions.PreCheckFailedException(
|
raise exceptions.SoftwarePreCheckFailedException(
|
||||||
subcloud=subcloud_name,
|
subcloud=subcloud_name,
|
||||||
details=details,
|
details=details,
|
||||||
)
|
)
|
||||||
|
@@ -10,8 +10,9 @@ from dccommon.drivers.openstack import vim
|
|||||||
from dcmanager.common import consts
|
from dcmanager.common import consts
|
||||||
from dcmanager.tests.unit.common import fake_strategy
|
from dcmanager.tests.unit.common import fake_strategy
|
||||||
from dcmanager.tests.unit.fakes import FakeVimStrategy
|
from dcmanager.tests.unit.fakes import FakeVimStrategy
|
||||||
from dcmanager.tests.unit.orchestrator.states.software.test_base import \
|
from dcmanager.tests.unit.orchestrator.states.software.test_base import (
|
||||||
TestSoftwareOrchestrator
|
TestSoftwareOrchestrator,
|
||||||
|
)
|
||||||
|
|
||||||
STRATEGY_BUILDING = FakeVimStrategy(state=vim.STATE_BUILDING)
|
STRATEGY_BUILDING = FakeVimStrategy(state=vim.STATE_BUILDING)
|
||||||
STRATEGY_DONE_BUILDING = FakeVimStrategy(state=vim.STATE_READY_TO_APPLY)
|
STRATEGY_DONE_BUILDING = FakeVimStrategy(state=vim.STATE_READY_TO_APPLY)
|
||||||
@@ -66,6 +67,7 @@ class TestCreateVIMSoftwareStrategyState(TestSoftwareOrchestrator):
|
|||||||
"migrate",
|
"migrate",
|
||||||
"relaxed",
|
"relaxed",
|
||||||
release=RELEASE_ID,
|
release=RELEASE_ID,
|
||||||
|
rollback=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# On success, the state should transition to the next state
|
# On success, the state should transition to the next state
|
||||||
|
@@ -17,22 +17,22 @@ from dcmanager.tests.unit.orchestrator.states.software.test_base import \
|
|||||||
REGION_ONE_RELEASES = [
|
REGION_ONE_RELEASES = [
|
||||||
{
|
{
|
||||||
"release_id": "starlingx-9.0.0",
|
"release_id": "starlingx-9.0.0",
|
||||||
"state": "committed",
|
"state": "deployed",
|
||||||
"sw_version": "9.0.0",
|
"sw_version": "9.0.0",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"release_id": "starlingx-9.0.1",
|
"release_id": "starlingx-9.0.1",
|
||||||
"state": "committed",
|
"state": "deployed",
|
||||||
"sw_version": "9.0.1",
|
"sw_version": "9.0.1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"release_id": "starlingx-9.0.2",
|
"release_id": "starlingx-9.0.2",
|
||||||
"state": "committed",
|
"state": "deployed",
|
||||||
"sw_version": "9.0.2",
|
"sw_version": "9.0.2",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"release_id": "starlingx-9.0.3",
|
"release_id": "starlingx-9.0.3",
|
||||||
"state": "committed",
|
"state": "deployed",
|
||||||
"sw_version": "9.0.3",
|
"sw_version": "9.0.3",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -40,12 +40,12 @@ REGION_ONE_RELEASES = [
|
|||||||
SUBCLOUD_RELEASES = [
|
SUBCLOUD_RELEASES = [
|
||||||
{
|
{
|
||||||
"release_id": "starlingx-9.0.0",
|
"release_id": "starlingx-9.0.0",
|
||||||
"state": "committed",
|
"state": "deployed",
|
||||||
"sw_version": "9.0.0",
|
"sw_version": "9.0.0",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"release_id": "starlingx-9.0.1",
|
"release_id": "starlingx-9.0.1",
|
||||||
"state": "committed",
|
"state": "deployed",
|
||||||
"sw_version": "9.0.1",
|
"sw_version": "9.0.1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -53,16 +53,16 @@ SUBCLOUD_RELEASES = [
|
|||||||
"state": "deployed",
|
"state": "deployed",
|
||||||
"sw_version": "9.0.2",
|
"sw_version": "9.0.2",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"release_id": "starlingx-9.0.2",
|
||||||
|
"state": "deploying",
|
||||||
|
"sw_version": "9.0.3",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"release_id": "starlingx-9.0.4",
|
"release_id": "starlingx-9.0.4",
|
||||||
"state": "available",
|
"state": "available",
|
||||||
"sw_version": "9.0.4",
|
"sw_version": "9.0.4",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"release_id": "starlingx-9.0.5",
|
|
||||||
"state": "deployed",
|
|
||||||
"sw_version": "9.0.5",
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -86,6 +86,7 @@ class TestFinishStrategyState(TestSoftwareOrchestrator):
|
|||||||
self.software_client.list = mock.MagicMock()
|
self.software_client.list = mock.MagicMock()
|
||||||
self.software_client.delete = mock.MagicMock()
|
self.software_client.delete = mock.MagicMock()
|
||||||
self.software_client.commit_patch = mock.MagicMock()
|
self.software_client.commit_patch = mock.MagicMock()
|
||||||
|
self.software_client.deploy_delete = mock.MagicMock()
|
||||||
self._read_from_cache = mock.MagicMock()
|
self._read_from_cache = mock.MagicMock()
|
||||||
|
|
||||||
def test_finish_strategy_success(self):
|
def test_finish_strategy_success(self):
|
||||||
@@ -101,9 +102,8 @@ class TestFinishStrategyState(TestSoftwareOrchestrator):
|
|||||||
call_args, _ = self.software_client.delete.call_args_list[0]
|
call_args, _ = self.software_client.delete.call_args_list[0]
|
||||||
self.assertItemsEqual(["starlingx-9.0.4"], call_args[0])
|
self.assertItemsEqual(["starlingx-9.0.4"], call_args[0])
|
||||||
|
|
||||||
self.software_client.commit_patch.assert_called_once_with(
|
self.software_client.commit_patch.assert_not_called()
|
||||||
["starlingx-9.0.2"]
|
self.software_client.deploy_delete.assert_called_once()
|
||||||
)
|
|
||||||
|
|
||||||
# On success, the state should transition to the next state
|
# On success, the state should transition to the next state
|
||||||
self.assert_step_updated(self.strategy_step.subcloud_id,
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
||||||
@@ -169,8 +169,8 @@ class TestFinishStrategyState(TestSoftwareOrchestrator):
|
|||||||
self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED
|
self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_finish_strategy_fails_when_commit_patch_exception(self):
|
def test_finish_strategy_fails_when_deploy_delete_exception(self):
|
||||||
"""Test finish strategy fails when software client commit_patch
|
"""Test finish strategy fails when software client deploy_delete
|
||||||
|
|
||||||
raises exception
|
raises exception
|
||||||
"""
|
"""
|
||||||
@@ -178,7 +178,7 @@ class TestFinishStrategyState(TestSoftwareOrchestrator):
|
|||||||
self.mock_read_from_cache.return_value = REGION_ONE_RELEASES
|
self.mock_read_from_cache.return_value = REGION_ONE_RELEASES
|
||||||
|
|
||||||
self.software_client.list.side_effect = [SUBCLOUD_RELEASES]
|
self.software_client.list.side_effect = [SUBCLOUD_RELEASES]
|
||||||
self.software_client.commit_patch.side_effect = Exception()
|
self.software_client.deploy_delete.side_effect = Exception()
|
||||||
|
|
||||||
self.worker.perform_state_action(self.strategy_step)
|
self.worker.perform_state_action(self.strategy_step)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user