Deploy state sync on swact
This commit adds a new USM REST API endpoint that provides the controllers deployment sync status during the upgrade. Depends-on: https://review.opendev.org/c/starlingx/update/+/904367 Test Plan: PASS: sent request to get the response of the sync status Task: 49426 Story: 2010676 Change-Id: Ib661f707686f13cbb52a5dbb67f636a9504ce8c9 Signed-off-by: junfeng-li <junfeng.li@windriver.com>
This commit is contained in:
parent
6c96e5d766
commit
deae981e5f
|
@ -23,6 +23,10 @@ LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
class SoftwareAPIController(object):
|
class SoftwareAPIController(object):
|
||||||
|
|
||||||
|
@expose(generic=True, template='json')
|
||||||
|
def index(self):
|
||||||
|
pass
|
||||||
|
|
||||||
@expose('json')
|
@expose('json')
|
||||||
def commit_patch(self, *args):
|
def commit_patch(self, *args):
|
||||||
try:
|
try:
|
||||||
|
@ -239,3 +243,7 @@ class SoftwareAPIController(object):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return dict(error=str(e))
|
return dict(error=str(e))
|
||||||
return dict(data=query_hosts)
|
return dict(data=query_hosts)
|
||||||
|
|
||||||
|
@index.when(method='GET', template='json')
|
||||||
|
def in_sync_controller(self):
|
||||||
|
return sc.in_sync_controller_api()
|
||||||
|
|
|
@ -1384,6 +1384,35 @@ class PatchController(PatchService):
|
||||||
|
|
||||||
return dict(info=msg_info, warning=msg_warning, error=msg_error)
|
return dict(info=msg_info, warning=msg_warning, error=msg_error)
|
||||||
|
|
||||||
|
def in_sync_controller_api(self):
|
||||||
|
"""
|
||||||
|
Check if both controllers are in sync
|
||||||
|
by checking the database JSON file
|
||||||
|
"""
|
||||||
|
is_in_sync = False
|
||||||
|
|
||||||
|
does_synced_software_exist = os.path.isfile(constants.SYNCED_SOFTWARE_JSON_FILE)
|
||||||
|
does_software_exist = os.path.isfile(constants.SOFTWARE_JSON_FILE)
|
||||||
|
|
||||||
|
if does_synced_software_exist and does_software_exist:
|
||||||
|
# both files exist, compare them
|
||||||
|
with open(constants.SYNCED_SOFTWARE_JSON_FILE, 'r') as f:
|
||||||
|
synced_software = json.load(f)
|
||||||
|
with open(constants.SOFTWARE_JSON_FILE, 'r') as f:
|
||||||
|
software = json.load(f)
|
||||||
|
LOG.debug("Synced software: %s", synced_software)
|
||||||
|
LOG.debug("Software: %s", software)
|
||||||
|
|
||||||
|
is_in_sync = synced_software == software
|
||||||
|
elif not does_synced_software_exist and not does_software_exist:
|
||||||
|
# neither file exists, it is not in deploying state
|
||||||
|
is_in_sync = True
|
||||||
|
else:
|
||||||
|
# either file does not exist, it is in deploying state
|
||||||
|
is_in_sync = False
|
||||||
|
|
||||||
|
return {"in_sync": is_in_sync}
|
||||||
|
|
||||||
def patch_init_release_api(self, release):
|
def patch_init_release_api(self, release):
|
||||||
"""
|
"""
|
||||||
Create an empty repo for a new release
|
Create an empty repo for a new release
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
# Copyright (c) 2023 Wind River Systems, Inc.
|
# Copyright (c) 2023-2024 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
from software.software_controller import PatchController
|
from software.software_controller import PatchController
|
||||||
from software.software_controller import ReleaseValidationFailure
|
from software.software_controller import ReleaseValidationFailure
|
||||||
import unittest
|
import unittest
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
from unittest.mock import mock_open
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
from software import constants
|
from software import constants
|
||||||
|
|
||||||
|
@ -127,3 +128,64 @@ class TestSoftwareController(unittest.TestCase):
|
||||||
self.assertEqual(info, '')
|
self.assertEqual(info, '')
|
||||||
self.assertEqual(warning, '')
|
self.assertEqual(warning, '')
|
||||||
self.assertEqual(error, 'Upgrade file signature verification failed\n')
|
self.assertEqual(error, 'Upgrade file signature verification failed\n')
|
||||||
|
|
||||||
|
@patch('software.software_controller.os.path.isfile')
|
||||||
|
@patch('software.software_controller.json.load')
|
||||||
|
@patch('software.software_controller.open', new_callable=mock_open)
|
||||||
|
def test_in_sync_controller_api_files_identical(self,
|
||||||
|
mock_dummy, # pylint: disable=unused-argument
|
||||||
|
mock_json_load,
|
||||||
|
mock_isfile):
|
||||||
|
controller = PatchController()
|
||||||
|
|
||||||
|
# Test when both files exist and are identical
|
||||||
|
mock_isfile.side_effect = [True, True]
|
||||||
|
mock_json_load.side_effect = [{'key': 'value'}, {'key': 'value'}]
|
||||||
|
result = controller.in_sync_controller_api()
|
||||||
|
self.assertEqual(result, {"in_sync": True})
|
||||||
|
|
||||||
|
@patch('software.software_controller.os.path.isfile')
|
||||||
|
@patch('software.software_controller.json.load')
|
||||||
|
@patch('software.software_controller.open', new_callable=mock_open)
|
||||||
|
def test_in_sync_controller_api_files_not_identical(self,
|
||||||
|
mock_dummy, # pylint: disable=unused-argument
|
||||||
|
mock_json_load,
|
||||||
|
mock_isfile):
|
||||||
|
controller = PatchController()
|
||||||
|
|
||||||
|
# Test when both files exist and are not identical
|
||||||
|
mock_isfile.side_effect = [True, True]
|
||||||
|
mock_json_load.side_effect = [{'key': 'value1'}, {'key': 'value2'}]
|
||||||
|
result = controller.in_sync_controller_api()
|
||||||
|
self.assertEqual(result, {"in_sync": False})
|
||||||
|
|
||||||
|
@patch('software.software_controller.os.path.isfile')
|
||||||
|
@patch('software.software_controller.json.load')
|
||||||
|
@patch('software.software_controller.open', new_callable=mock_open)
|
||||||
|
def test_in_sync_controller_api_files_not_exist(self,
|
||||||
|
mock_dummy, # pylint: disable=unused-argument
|
||||||
|
mock_json_load, # pylint: disable=unused-argument
|
||||||
|
mock_isfile):
|
||||||
|
controller = PatchController()
|
||||||
|
|
||||||
|
# Test when neither file exists
|
||||||
|
mock_isfile.side_effect = [False, False]
|
||||||
|
result = controller.in_sync_controller_api()
|
||||||
|
self.assertEqual(result, {"in_sync": True})
|
||||||
|
|
||||||
|
@patch('software.software_controller.os.path.isfile')
|
||||||
|
@patch('software.software_controller.json.load')
|
||||||
|
@patch('software.software_controller.open', new_callable=mock_open)
|
||||||
|
def test_in_sync_controller_api_one_file_exist(self,
|
||||||
|
mock_dummy, # pylint: disable=unused-argument
|
||||||
|
mock_json_load, # pylint: disable=unused-argument
|
||||||
|
mock_isfile):
|
||||||
|
controller = PatchController()
|
||||||
|
|
||||||
|
# Test when only one file exists
|
||||||
|
mock_isfile.side_effect = [True, False]
|
||||||
|
result = controller.in_sync_controller_api()
|
||||||
|
self.assertEqual(result, {"in_sync": False})
|
||||||
|
mock_isfile.side_effect = [False, True]
|
||||||
|
result = controller.in_sync_controller_api()
|
||||||
|
self.assertEqual(result, {"in_sync": False})
|
||||||
|
|
Loading…
Reference in New Issue