diff --git a/crmsh/migration.py b/crmsh/migration.py index 4afab479a..f71c87e89 100644 --- a/crmsh/migration.py +++ b/crmsh/migration.py @@ -255,14 +255,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 76f212871..4fd96881f 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 @@ -13,3 +14,29 @@ def test_load_supported_resource_agents(self): self.assertIn(cibquery.ResourceAgent('ocf', 'heartbeat', 'IPaddr2'), s) self.assertIn(cibquery.ResourceAgent('stonith', None, 'fence_sbd'), s) self.assertNotIn(cibquery.ResourceAgent('foo', None, 'bar'), s) + + def test_check_version_range(self): + def check_fn(x): + migration._check_version_range( + self._handler, + 'foo', + (0, 2,), + re.compile(r'^foo\s+(\d+(?:.\d+)*)'), + x, + ) + check_fn('foo 0.2') + self._handler.handle_problem.assert_not_called() + check_fn('foo 0.2.1') + self._handler.handle_problem.assert_not_called() + check_fn('foo 0.9') + self._handler.handle_problem.assert_not_called() + check_fn('foo 0.9.99') + self._handler.handle_problem.assert_not_called() + check_fn('foo 1') + self._handler.handle_problem.assert_called() + self._handler.handle_problem.reset_mock() + check_fn('foo 1.0') + self._handler.handle_problem.assert_called() + self._handler.handle_problem.reset_mock() + check_fn('foo 1.0.0') + self._handler.handle_problem.assert_called()