From 151e57183e1e7056f2b40898273ccbd42353cfe5 Mon Sep 17 00:00:00 2001 From: badrogger Date: Mon, 30 Dec 2024 13:54:24 +0000 Subject: [PATCH] Update lvmpy. Fix is update safe --- lvmpy | 2 +- node_cli/core/node.py | 7 ++++++- node_cli/utils/docker_utils.py | 21 +++++++++++++++++++++ tests/cli/node_test.py | 29 ++++++++++++++--------------- tests/core/core_node_test.py | 28 +++++++++++++++++++++++----- 5 files changed, 65 insertions(+), 22 deletions(-) diff --git a/lvmpy b/lvmpy index 0d796233..694e2533 160000 --- a/lvmpy +++ b/lvmpy @@ -1 +1 @@ -Subproject commit 0d7962335f1e60797fdd89d3c9d1e750e0355275 +Subproject commit 694e25337b51fe97aaadd3ea45e88759e838184e diff --git a/node_cli/core/node.py b/node_cli/core/node.py index e360d7dc..7330cfd9 100644 --- a/node_cli/core/node.py +++ b/node_cli/core/node.py @@ -74,6 +74,7 @@ from node_cli.utils.texts import Texts from node_cli.utils.exit_codes import CLIExitCodes from node_cli.utils.decorators import check_not_inited, check_inited, check_user +from node_cli.utils.docker_utils import is_admin_running, is_api_running, is_sync_admin_running from node_cli.migrations.focal_to_jammy import migrate as migrate_2_6 @@ -96,7 +97,11 @@ class NodeStatuses(Enum): NOT_CREATED = 5 -def is_update_safe() -> bool: +def is_update_safe(sync_node: bool = False) -> bool: + if not sync_node and (not is_admin_running() or not is_api_running()): + return True + if sync_node and not is_sync_admin_running(): + return True status, payload = get_request(BLUEPRINT_NAME, 'update-safe') if status == 'error': return False diff --git a/node_cli/utils/docker_utils.py b/node_cli/utils/docker_utils.py index 7a4957db..fe271d79 100644 --- a/node_cli/utils/docker_utils.py +++ b/node_cli/utils/docker_utils.py @@ -335,6 +335,27 @@ def cleanup_unused_images(dclient=None, ignore=None): ) +def is_container_running(name: str, dclient: Optional[DockerClient] = None) -> bool: + dc = dclient or docker_client() + try: + container = dc.containers.get(name) + return container.status == 'running' + except docker.errors.NotFound: + return False + + +def is_admin_running(dclient: Optional[DockerClient] = None) -> bool: + return is_container_running(name='skale_admin', dclient=dclient) + + +def is_api_running(dclient: Optional[DockerClient] = None) -> bool: + return is_container_running(name='skale_api', dclient=dclient) + + +def is_sync_admin_running(dclient: Optional[DockerClient] = None) -> bool: + return is_container_running(name='skale_sync_admin', dclient=dclient) + + def system_prune(): logger.info('Removing dangling docker artifacts') cmd = ['docker', 'system', 'prune', '-f'] diff --git a/tests/cli/node_test.py b/tests/cli/node_test.py index e12b4329..7e206db1 100644 --- a/tests/cli/node_test.py +++ b/tests/cli/node_test.py @@ -46,7 +46,6 @@ response_mock, run_command, run_command_mock, - safe_update_api_response, subprocess_run_mock, ) from tests.resources_test import BIG_DISK_SIZE @@ -368,8 +367,19 @@ def test_turn_off_maintenance_on(mocked_g_config): with mock.patch('subprocess.run', new=subprocess_run_mock), mock.patch( 'node_cli.core.node.turn_off_op' ), mock.patch('node_cli.utils.decorators.is_node_inited', return_value=True): + result = run_command_mock( + 'node_cli.utils.helper.requests.post', + resp_mock, + _turn_off, + ['--maintenance-on', '--yes'], + ) + assert ( + result.output + == 'Setting maintenance mode on...\nNode is successfully set in maintenance mode\n' + ) # noqa + assert result.exit_code == 0 with mock.patch( - 'node_cli.utils.helper.requests.get', return_value=safe_update_api_response() + 'node_cli.utils.docker_utils.is_container_running', return_value=True ): result = run_command_mock( 'node_cli.utils.helper.requests.post', @@ -377,19 +387,8 @@ def test_turn_off_maintenance_on(mocked_g_config): _turn_off, ['--maintenance-on', '--yes'], ) - assert ( - result.output - == 'Setting maintenance mode on...\nNode is successfully set in maintenance mode\n' - ) # noqa - assert result.exit_code == 0 - result = run_command_mock( - 'node_cli.utils.helper.requests.post', - resp_mock, - _turn_off, - ['--maintenance-on', '--yes'], - ) - assert 'Cannot turn off safely' in result.output - assert result.exit_code == CLIExitCodes.UNSAFE_UPDATE + assert 'Cannot turn off safely' in result.output + assert result.exit_code == CLIExitCodes.UNSAFE_UPDATE def test_turn_on_maintenance_off(mocked_g_config): diff --git a/tests/core/core_node_test.py b/tests/core/core_node_test.py index d418ad15..f79c6fa3 100644 --- a/tests/core/core_node_test.py +++ b/tests/core/core_node_test.py @@ -181,14 +181,32 @@ def test_update_node(mocked_g_config, resource_file): def test_is_update_safe(): - assert not is_update_safe() + assert is_update_safe() + assert is_update_safe(sync_node=True) + + with mock.patch('node_cli.core.node.is_admin_running', return_value=True): + with mock.patch('node_cli.core.node.is_api_running', return_value=True): + assert not is_update_safe() + assert is_update_safe(sync_node=True) + + with mock.patch('node_cli.core.node.is_sync_admin_running', return_value=True): + assert is_update_safe() + assert not is_update_safe(sync_node=True) + + with mock.patch('node_cli.utils.docker_utils.is_container_running', return_value=True): + with mock.patch( + 'node_cli.utils.helper.requests.get', return_value=safe_update_api_response() + ): + assert is_update_safe() + with mock.patch('node_cli.utils.helper.requests.get', return_value=safe_update_api_response()): assert is_update_safe() - with mock.patch( - 'node_cli.utils.helper.requests.get', return_value=safe_update_api_response(safe=False) - ): - assert not is_update_safe() + with mock.patch('node_cli.utils.docker_utils.is_container_running', return_value=True): + with mock.patch( + 'node_cli.utils.helper.requests.get', return_value=safe_update_api_response(safe=False) + ): + assert not is_update_safe() def test_repair_sync(tmp_sync_datadir, mocked_g_config, resource_file):