Create finish software strategy
Create finish software strategy for the upgrade orchestrator, this state will commit the patches from the subcloud that are committed in systemcontroller and it will delete releases from the subcloud that are available or unavailable and not present in the systemcontroller. Story: 2010676 Task: 48825 Test Case (Patching only): PASS: Apply and commit a patch to the systemcontroller and apply the same patch to the subcloud and run the upgrade orchestration and verify that the patch from the subcloud is committed. PASS: Upload a patch to the subcloud and run the upgrade orchestration and verify that the patch is deleted from the subcloud. PASS: Upload a patch to subcloud, protect the patch metadata file with chattr +i, create and apply a upgrade strategy and verify that the orchestrator failed to delete that patch and the correct error message is presented. Signed-off-by: Christopher Souza <Christopher.DeOliveiraSouza@windriver.com> Change-Id: I2dae16800235891fc863151b307313732e8d49cd
This commit is contained in:

committed by
Christopher de Oliveira Souza

parent
2438807fc8
commit
e741c5d131
@@ -3,13 +3,16 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from dccommon.drivers.openstack import software_v1
|
||||
from dcmanager.common import consts
|
||||
from dcmanager.common.exceptions import StrategyStoppedException
|
||||
from dcmanager.orchestrator.states.base import BaseState
|
||||
from dcmanager.orchestrator.states.software.cache.cache_specifications import \
|
||||
REGION_ONE_RELEASE_USM_CACHE_TYPE
|
||||
|
||||
|
||||
class FinishStrategyState(BaseState):
|
||||
"""Finish Strategy software orchestration state"""
|
||||
"""Finish Software Strategy software orchestration state"""
|
||||
|
||||
def __init__(self, region_name):
|
||||
super(FinishStrategyState, self).__init__(
|
||||
@@ -18,5 +21,68 @@ class FinishStrategyState(BaseState):
|
||||
)
|
||||
|
||||
def perform_state_action(self, strategy_step):
|
||||
"""Finish Strategy region status"""
|
||||
"""Finish Software Strategy"""
|
||||
|
||||
self.info_log(strategy_step, "Finishing software strategy")
|
||||
|
||||
regionone_committed_releases = self._read_from_cache(
|
||||
REGION_ONE_RELEASE_USM_CACHE_TYPE,
|
||||
state=software_v1.COMMITTED
|
||||
)
|
||||
|
||||
self.debug_log(strategy_step,
|
||||
"regionone_committed_releases: %s" % regionone_committed_releases)
|
||||
|
||||
try:
|
||||
software_client = self.get_software_client(self.region_name)
|
||||
subcloud_releases = software_client.query()
|
||||
except Exception:
|
||||
message = ("Cannot retrieve subcloud releases. Please see logs for"
|
||||
" details.")
|
||||
self.exception_log(strategy_step, message)
|
||||
raise Exception(message)
|
||||
|
||||
self.debug_log(strategy_step,
|
||||
"Releases for subcloud: %s" % subcloud_releases)
|
||||
|
||||
releases_to_commit = list()
|
||||
releases_to_delete = list()
|
||||
|
||||
# For this subcloud, determine which releases should be committed and
|
||||
# which should be deleted.
|
||||
for release_id in subcloud_releases:
|
||||
if (subcloud_releases[release_id]['state'] ==
|
||||
software_v1.AVAILABLE or
|
||||
subcloud_releases[release_id]['state'] ==
|
||||
software_v1.UNAVAILABLE):
|
||||
releases_to_delete.append(release_id)
|
||||
elif subcloud_releases[release_id]['state'] == \
|
||||
software_v1.DEPLOYED:
|
||||
if release_id in regionone_committed_releases:
|
||||
releases_to_commit.append(release_id)
|
||||
|
||||
if releases_to_delete:
|
||||
self.info_log(strategy_step, "Deleting releases %s" % 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 Exception(message)
|
||||
|
||||
if self.stopped():
|
||||
raise StrategyStoppedException()
|
||||
|
||||
if releases_to_commit:
|
||||
self.info_log(strategy_step,
|
||||
"Committing releases %s to subcloud" % releases_to_commit)
|
||||
try:
|
||||
software_client.commit_patch(releases_to_commit)
|
||||
except Exception:
|
||||
message = ("Cannot commit releases to subcloud. Please see logs for"
|
||||
" details.")
|
||||
self.exception_log(strategy_step, message)
|
||||
raise Exception(message)
|
||||
|
||||
return self.next_state
|
||||
|
@@ -3,14 +3,41 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
|
||||
from dcmanager.common import consts
|
||||
from dcmanager.orchestrator.states.software.finish_strategy import \
|
||||
FinishStrategyState
|
||||
from dcmanager.tests.unit.orchestrator.states.software.test_base import \
|
||||
TestSoftwareOrchestrator
|
||||
|
||||
|
||||
REGION_ONE_RELEASES = {"DC.1": {"sw_version": "20.12",
|
||||
"state": "committed"},
|
||||
"DC.2": {"sw_version": "20.12",
|
||||
"state": "committed"},
|
||||
"DC.3": {"sw_version": "20.12",
|
||||
"state": "committed"},
|
||||
"DC.8": {"sw_version": "20.12",
|
||||
"state": "committed"}}
|
||||
|
||||
SUBCLOUD_RELEASES = {"DC.1": {"sw_version": "20.12",
|
||||
"state": "committed"},
|
||||
"DC.2": {"sw_version": "20.12",
|
||||
"state": "committed"},
|
||||
"DC.3": {"sw_version": "20.12",
|
||||
"state": "deployed"},
|
||||
"DC.9": {"sw_version": "20.12",
|
||||
"state": "available"}}
|
||||
|
||||
|
||||
class TestFinishStrategyState(TestSoftwareOrchestrator):
|
||||
def setUp(self):
|
||||
p = mock.patch.object(cfg.CONF, 'use_usm')
|
||||
self.mock_use_usm = p.start()
|
||||
self.mock_use_usm.return_value = True
|
||||
self.addCleanup(p.stop)
|
||||
super(TestFinishStrategyState, self).setUp()
|
||||
|
||||
self.on_success_state = consts.STRATEGY_STATE_COMPLETE
|
||||
@@ -22,11 +49,47 @@ class TestFinishStrategyState(TestSoftwareOrchestrator):
|
||||
self.strategy_step = self.setup_strategy_step(
|
||||
self.subcloud.id, consts.STRATEGY_STATE_SW_FINISH_STRATEGY)
|
||||
|
||||
def test_finish_strategy_success(self):
|
||||
"""Test finish strategy when the API call succeeds."""
|
||||
# Add mock API endpoints for software client calls
|
||||
# invoked by this state
|
||||
self.software_client.query = mock.MagicMock()
|
||||
self.software_client.delete = mock.MagicMock()
|
||||
self.software_client.commit_patch = mock.MagicMock()
|
||||
self._read_from_cache = mock.MagicMock()
|
||||
|
||||
@mock.patch.object(FinishStrategyState, '_read_from_cache')
|
||||
def test_finish_strategy_success(self, mock_read_from_cache):
|
||||
"""Test software finish strategy when the API call succeeds."""
|
||||
mock_read_from_cache.return_value = REGION_ONE_RELEASES
|
||||
|
||||
self.software_client.query.side_effect = [SUBCLOUD_RELEASES]
|
||||
|
||||
# invoke the strategy state operation on the orch thread
|
||||
self.worker.perform_state_action(self.strategy_step)
|
||||
|
||||
call_args, _ = self.software_client.delete.call_args_list[0]
|
||||
self.assertItemsEqual(['DC.9'], call_args[0])
|
||||
|
||||
call_args, _ = self.software_client.commit_patch.call_args_list[0]
|
||||
self.assertItemsEqual(['DC.3'], call_args[0])
|
||||
|
||||
# On success, the state should transition to the next state
|
||||
self.assert_step_updated(self.strategy_step.subcloud_id,
|
||||
self.on_success_state)
|
||||
|
||||
@mock.patch.object(FinishStrategyState, '_read_from_cache')
|
||||
def test_finish_strategy_no_operation_required(self, mock_read_from_cache):
|
||||
"""Test software finish strategy when no operation is required."""
|
||||
mock_read_from_cache.return_value = REGION_ONE_RELEASES
|
||||
|
||||
self.software_client.query.side_effect = [REGION_ONE_RELEASES]
|
||||
|
||||
# invoke the strategy state operation on the orch thread
|
||||
self.worker.perform_state_action(self.strategy_step)
|
||||
|
||||
self.software_client.delete.assert_not_called()
|
||||
|
||||
self.software_client.commit_patch.assert_not_called()
|
||||
|
||||
# On success, the state should transition to the next state
|
||||
self.assert_step_updated(self.strategy_step.subcloud_id,
|
||||
self.on_success_state)
|
||||
|
Reference in New Issue
Block a user