From 389d007da2cf99ec5436d6012fb813245d076ffc Mon Sep 17 00:00:00 2001 From: nicholasyang Date: Thu, 2 Jan 2025 08:52:06 +0800 Subject: [PATCH] Dev: add pre-migration checks for pacemaker version (jsc#PED-11808) (cherry picked from commit 3264f0d7ae716a596e588ded295954fb554cf18c) --- crmsh/migration.py | 42 ++++++++++++++++++++++++++++---- test/unittests/test_migration.py | 35 ++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/crmsh/migration.py b/crmsh/migration.py index 3bde4f602..549e13ecc 100644 --- a/crmsh/migration.py +++ b/crmsh/migration.py @@ -258,14 +258,46 @@ def check_dependency_version(handler: CheckResultHandler): handler.log_info('Checking dependency version...') shell = sh.LocalShell() out = shell.get_stdout_or_raise_error(None, 'corosync -v') - match = re.search(r"version\s+'((\d+)(?:\.\d+)*)'", out) - if not match or match.group(2) != '3': + _check_version_range( + handler, + 'Corosync', (3,), + re.compile(r"version\s+'(\d+(?:\.\d+)*)'"), + shell.get_stdout_or_raise_error(None, 'corosync -v'), + ) + _check_version_range( + handler, + 'Pacemaker', (3,), + re.compile(r"^Pacemaker\s+(\d+(?:\.\d+)*)"), + shell.get_stdout_or_raise_error(None, 'pacemakerd --version'), + ) + + +def _check_version_range( + handler: CheckResultHandler, component_name: str, + minimum: tuple, + pattern, + text: str, +): + match = pattern.search(text) + if not match: handler.handle_problem( - False, 'Corosync version not supported', [ - 'Supported version: corosync >= 3', - f'Actual version: corosync == {match.group(1)}', + False, f'{component_name} version not supported', [ + 'Unknown version:', + text, ], ) + else: + version = tuple(int(x) for x in match.group(1).split('.')) + if not minimum <= version: + handler.handle_problem( + False, f'{component_name} version not supported', [ + 'Supported version: {} <= {}'.format( + '.'.join(str(x) for x in minimum), + component_name, + ), + f'Actual version: {component_name} == {match.group(1)}', + ], + ) def check_service_status(handler: CheckResultHandler): diff --git a/test/unittests/test_migration.py b/test/unittests/test_migration.py index 381a91dcd..fdceedb88 100644 --- a/test/unittests/test_migration.py +++ b/test/unittests/test_migration.py @@ -1,3 +1,4 @@ +import re import unittest from unittest import mock @@ -21,3 +22,37 @@ def test_check_removed_resource_agents(self): [cibquery.ResourceAgent('foo', 'bar', 'qux')] ) self._handler.handle_problem.assert_called() + + def test_check_version_range(self): + def check_fn(x): + migration._check_version_range( + self._handler, + 'foo', + (1, 1,), + re.compile(r'^foo\s+(\d+(?:.\d+)*)'), + x, + ) + check_fn('foo 0') + self._handler.handle_problem.assert_called() + self._handler.handle_problem.reset_mock() + check_fn('foo 0.9') + self._handler.handle_problem.assert_called() + self._handler.handle_problem.reset_mock() + check_fn('foo 0.9.99') + self._handler.handle_problem.assert_called() + self._handler.handle_problem.reset_mock() + check_fn('foo 1') + self._handler.handle_problem.assert_called() + self._handler.handle_problem.reset_mock() + check_fn('foo 1.1') + self._handler.handle_problem.assert_not_called() + check_fn('foo 1.1.0') + self._handler.handle_problem.assert_not_called() + check_fn('foo 1.1.1') + self._handler.handle_problem.assert_not_called() + check_fn('foo 1.2') + self._handler.handle_problem.assert_not_called() + check_fn('foo 2') + self._handler.handle_problem.assert_not_called() + check_fn('foo 2.0') + self._handler.handle_problem.assert_not_called()