diff --git a/distributedcloud/dcmanager/common/prestage.py b/distributedcloud/dcmanager/common/prestage.py index 5ae31a32d..208fe5875 100644 --- a/distributedcloud/dcmanager/common/prestage.py +++ b/distributedcloud/dcmanager/common/prestage.py @@ -131,6 +131,13 @@ def initial_subcloud_validate(subcloud, installed_loads, software_version): orch_skip=True, details="Subcloud is not managed.") + if subcloud.backup_status in consts.STATES_FOR_ONGOING_BACKUP: + raise exceptions.PrestagePreCheckFailedException( + subcloud=subcloud.name, + orch_skip=True, + details="Prestage operation is not allowed while" + " backup is in progress.") + allowed_deploy_states = [consts.DEPLOY_STATE_DONE, consts.PRESTAGE_STATE_FAILED, consts.PRESTAGE_STATE_COMPLETE] @@ -164,6 +171,7 @@ def validate_prestage(subcloud, payload): - Subcloud is an AIO-SX - Subcloud is online - Subcloud is managed + - Subcloud backup operation is not in progress - Subcloud has no management-affecting alarms (unless force=true) Raises a PrestageCheckFailedException on failure. diff --git a/distributedcloud/dcmanager/tests/unit/api/v1/controllers/test_subclouds.py b/distributedcloud/dcmanager/tests/unit/api/v1/controllers/test_subclouds.py index f56805e17..5df81b84e 100644 --- a/distributedcloud/dcmanager/tests/unit/api/v1/controllers/test_subclouds.py +++ b/distributedcloud/dcmanager/tests/unit/api/v1/controllers/test_subclouds.py @@ -31,6 +31,7 @@ import webtest from dccommon import consts as dccommon_consts from dcmanager.api.controllers.v1 import subclouds from dcmanager.common import consts +from dcmanager.common import exceptions from dcmanager.common import phased_subcloud_deploy as psd_common from dcmanager.common import prestage from dcmanager.common import utils as cutils @@ -2242,6 +2243,22 @@ class TestSubcloudAPIOther(testroot.DCManagerApiTest): str(subcloud.id) + '/prestage', headers=FAKE_HEADERS, params=data) + def test_prestage_subcloud_backup_in_progress(self): + subcloud = fake_subcloud.create_fake_subcloud(self.ctx) + subcloud = db_api.subcloud_update( + self.ctx, + subcloud.id, + availability_status=dccommon_consts.AVAILABILITY_ONLINE, + deploy_status=consts.DEPLOY_STATE_DONE, + management_state=dccommon_consts.MANAGEMENT_MANAGED, + backup_status=consts.BACKUP_STATE_IN_PROGRESS) + + self.assertRaises(exceptions.PrestagePreCheckFailedException, + prestage.initial_subcloud_validate, + subcloud, + [fake_subcloud.FAKE_SOFTWARE_VERSION], + fake_subcloud.FAKE_SOFTWARE_VERSION) + @mock.patch.object(cutils, 'get_systemcontroller_installed_loads') @mock.patch.object(prestage, '_get_system_controller_upgrades') @mock.patch.object(prestage, '_get_prestage_subcloud_info') diff --git a/distributedcloud/dcmanager/tests/unit/orchestrator/test_sw_update_manager.py b/distributedcloud/dcmanager/tests/unit/orchestrator/test_sw_update_manager.py index 0f93fe458..6d71ea06d 100644 --- a/distributedcloud/dcmanager/tests/unit/orchestrator/test_sw_update_manager.py +++ b/distributedcloud/dcmanager/tests/unit/orchestrator/test_sw_update_manager.py @@ -489,6 +489,34 @@ class TestSwUpdateManager(base.DCManagerTestCase): um.create_sw_update_strategy, self.ctxt, payload=data) + @mock.patch.object(prestage, '_get_system_controller_upgrades') + @mock.patch.object(sw_update_manager, 'PatchOrchThread') + def test_create_sw_prestage_strategy_backup_in_progress(self, + mock_patch_orch_thread, + mock_controller_upgrade): + mock_controller_upgrade.return_value = list() + + # Create fake subcloud and respective status (managed & online) + fake_subcloud1 = self.create_subcloud(self.ctxt, 'subcloud1', + self.fake_group3.id, + is_managed=True, is_online=True) + self.update_subcloud_status(self.ctxt, fake_subcloud1.id) + db_api.subcloud_update(self.ctx, + fake_subcloud1.id, + backup_status=consts.BACKUP_STATE_IN_PROGRESS) + + data = copy.copy(FAKE_SW_PRESTAGE_DATA) + fake_password = (base64.b64encode('testpass'.encode("utf-8"))).decode( + 'ascii') + data['sysadmin_password'] = fake_password + data['cloud_name'] = 'subcloud1' + + um = sw_update_manager.SwUpdateManager() + + self.assertRaises(exceptions.BadRequest, + um.create_sw_update_strategy, + self.ctxt, payload=data) + @mock.patch.object(sw_update_manager, 'PatchOrchThread') def test_create_sw_update_strategy_cloud_name_not_exists(self, mock_patch_orch_thread):