Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config: add the hidden warnings.rabbitmq_version option #5415

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions aiida/cmdline/commands/cmd_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def verdi_status(print_traceback, no_rmq):
from aiida.cmdline.utils.daemon import delete_stale_pid_file, get_daemon_status
from aiida.common.utils import Capturing
from aiida.manage.configuration.settings import AIIDA_CONFIG_FOLDER
from aiida.manage.manager import check_rabbitmq_version, get_manager
from aiida.manage.manager import get_manager

exit_code = ExitCode.SUCCESS

Expand Down Expand Up @@ -125,7 +125,7 @@ def verdi_status(print_traceback, no_rmq):
print_status(ServiceStatus.ERROR, 'rabbitmq', message, exception=exc, print_traceback=print_traceback)
exit_code = ExitCode.CRITICAL
else:
version, supported = check_rabbitmq_version(comm)
version, supported = manager.check_rabbitmq_version(comm)
connection = f'Connected to RabbitMQ v{version} as {profile.get_rmq_url()}'
if supported:
print_status(ServiceStatus.UP, 'rabbitmq', connection)
Expand Down
5 changes: 5 additions & 0 deletions aiida/manage/configuration/schema/config-v8.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@
"description": "Whether to print a warning when a profile is loaded while a development version is installed",
"global_only": true
},
"warnings.rabbitmq_version": {
"type": "boolean",
"default": true,
"description": "Whether to print a warning when an incompatible version of RabbitMQ is configured"
},
"transport.task_retry_initial_interval": {
"type": "integer",
"default": 20,
Expand Down
93 changes: 49 additions & 44 deletions aiida/manage/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def load_profile(self, profile: Union[None, str, 'Profile'] = None, allow_switch

# Check whether a development version is being run. Note that needs to be called after ``configure_logging``
# because this function relies on the logging being properly configured for the warning to show.
check_version()
self.check_version()

return self._profile

Expand Down Expand Up @@ -309,8 +309,10 @@ def create_communicator(self, task_prefetch_count: Optional[int] = None) -> 'Rmq
# testing_mode cannot be set.
testing_mode=profile.is_test_profile,
)

# Check whether a compatible version of RabbitMQ is being used.
check_rabbitmq_version(communicator)
self.check_rabbitmq_version(communicator)

return communicator

def get_daemon_client(self) -> 'DaemonClient':
Expand Down Expand Up @@ -423,62 +425,65 @@ def create_daemon_runner(self, loop: Optional[asyncio.AbstractEventLoop] = None)

return runner

def check_rabbitmq_version(self, communicator: 'RmqThreadCommunicator'):
"""Check the version of RabbitMQ that is being connected to and emit warning if the version is not compatible.

def is_rabbitmq_version_supported(communicator: 'RmqThreadCommunicator') -> bool:
"""Return whether the version of RabbitMQ configured for the current profile is supported.
Versions 3.8.15 and above are not compatible with AiiDA with default configuration.
"""
from packaging.version import parse

Versions 3.8 and above are not compatible with AiiDA with default configuration.
from aiida.cmdline.utils import echo

:return: boolean whether the current RabbitMQ version is supported.
"""
from packaging.version import parse
return get_rabbitmq_version(communicator) < parse('3.8')
show_warning = self.get_option('warnings.rabbitmq_version')
version = get_rabbitmq_version(communicator)

if show_warning and version >= parse('3.8.15'):
echo.echo_warning(f'RabbitMQ v{version} is not supported and will cause unexpected problems!')
echo.echo_warning('It can cause long-running workflows to crash and jobs to be submitted multiple times.')
echo.echo_warning('See https://github.com/aiidateam/aiida-core/wiki/RabbitMQ-version-to-use for details.')
return version, False

def get_rabbitmq_version(communicator: 'RmqThreadCommunicator'):
"""Return the version of the RabbitMQ server that the current profile connects to.
return version, True

:return: :class:`packaging.version.Version`
"""
from packaging.version import parse
return parse(communicator.server_properties['version'].decode('utf-8'))
def check_version(self):
"""Check the currently installed version of ``aiida-core`` and warn if it is a post release development version.

The ``aiida-core`` package maintains the protocol that the ``develop`` branch will use a post release version
number. This means it will always append `.post0` to the version of the latest release. This should mean that if
this protocol is maintained properly, this method will print a warning if the currently installed version is a
post release development branch and not an actual release.
"""
from packaging.version import parse

def check_rabbitmq_version(communicator: 'RmqThreadCommunicator'):
"""Check the version of RabbitMQ that is being connected to and emit warning if the version is not compatible."""
from packaging.version import parse
from aiida import __version__
from aiida.cmdline.utils import echo

from aiida.cmdline.utils import echo
version = get_rabbitmq_version(communicator)
if version >= parse('3.8.15'):
echo.echo_warning(f'RabbitMQ v{version} is not supported and will cause unexpected problems!')
echo.echo_warning('It can cause long-running workflows to crash and jobs to be submitted multiple times.')
echo.echo_warning('See https://github.com/aiidateam/aiida-core/wiki/RabbitMQ-version-to-use for details.')
return version, False
return version, True
# Showing of the warning can be turned off by setting the following option to false.
show_warning = self.get_option('warnings.development_version')
version = parse(__version__)

if version.is_postrelease and show_warning:
echo.echo_warning(f'You are currently using a post release development version of AiiDA: {version}')
echo.echo_warning('Be aware that this is not recommended for production and is not officially supported.')
echo.echo_warning('Databases used with this version may not be compatible with future releases of AiiDA')
echo.echo_warning('as you might not be able to automatically migrate your data.\n')

def check_version():
"""Check the currently installed version of ``aiida-core`` and warn if it is a post release development version.

The ``aiida-core`` package maintains the protocol that the ``develop`` branch will use a post release version
number. This means it will always append `.post0` to the version of the latest release. This should mean that if
this protocol is maintained properly, this method will print a warning if the currently installed version is a
post release development branch and not an actual release.
def is_rabbitmq_version_supported(communicator: 'RmqThreadCommunicator') -> bool:
"""Return whether the version of RabbitMQ configured for the current profile is supported.

Versions 3.8.15 and above are not compatible with AiiDA with default configuration.

:return: boolean whether the current RabbitMQ version is supported.
"""
from packaging.version import parse
return get_rabbitmq_version(communicator) < parse('3.8.15')

from aiida import __version__
from aiida.cmdline.utils import echo
from aiida.manage.configuration import get_config_option

version = parse(__version__)

# Showing of the warning can be turned off by setting the following option to false.
show_warning = get_config_option('warnings.development_version')
def get_rabbitmq_version(communicator: 'RmqThreadCommunicator'):
"""Return the version of the RabbitMQ server that the current profile connects to.

if version.is_postrelease and show_warning:
echo.echo_warning(f'You are currently using a post release development version of AiiDA: {version}')
echo.echo_warning('Be aware that this is not recommended for production and is not officially supported.')
echo.echo_warning('Databases used with this version may not be compatible with future releases of AiiDA')
echo.echo_warning('as you might not be able to automatically migrate your data.\n')
:return: :class:`packaging.version.Version`
"""
from packaging.version import parse
return parse(communicator.server_properties['version'].decode('utf-8'))
10 changes: 5 additions & 5 deletions tests/manage/configuration/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import pytest

import aiida
from aiida.manage.manager import check_version
from aiida.manage.manager import get_manager


def test_check_version_release(monkeypatch, capsys, isolated_config):
"""Test that ``check_version`` prints nothing for a release version.
"""Test that ``Manager.check_version`` prints nothing for a release version.

If a warning is emitted, it should be printed to stdout. So even though it will go through the logging system, the
logging configuration of AiiDA will interfere with that of pytest and the ultimately the output will simply be
Expand All @@ -19,15 +19,15 @@ def test_check_version_release(monkeypatch, capsys, isolated_config):
# Explicitly setting the default in case the test profile has it changed.
isolated_config.set_option('warnings.development_version', True)

check_version()
get_manager().check_version()
captured = capsys.readouterr()
assert not captured.err
assert not captured.out


@pytest.mark.parametrize('suppress_warning', (True, False))
def test_check_version_development(monkeypatch, capsys, isolated_config, suppress_warning):
"""Test that ``check_version`` prints a warning for a post release development version.
"""Test that ``Manager.check_version`` prints a warning for a post release development version.

The warning can be suppressed by setting the option ``warnings.development_version`` to ``False``.

Expand All @@ -40,7 +40,7 @@ def test_check_version_development(monkeypatch, capsys, isolated_config, suppres

isolated_config.set_option('warnings.development_version', not suppress_warning)

check_version()
get_manager().check_version()
captured = capsys.readouterr()
assert not captured.err

Expand Down
2 changes: 1 addition & 1 deletion tests/manage/configuration/test_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class TestConfigurationOptions:
def test_get_option_names(self):
"""Test `get_option_names` function."""
assert isinstance(get_option_names(), list)
assert len(get_option_names()) == 27
assert len(get_option_names()) == 28

def test_get_option(self):
"""Test `get_option` function."""
Expand Down