From 234dde5fc1394d4ac6f855426e7794c97cc53f91 Mon Sep 17 00:00:00 2001 From: Steven Robertson Date: Sun, 7 Feb 2021 13:09:17 -0800 Subject: [PATCH] check Ansible version before loaders are loaded --- ansible_mitogen/loaders.py | 67 +++++++++++++++++++++++++++++-------- ansible_mitogen/planner.py | 10 ------ ansible_mitogen/strategy.py | 48 +------------------------- docs/changelog.rst | 1 + 4 files changed, 55 insertions(+), 71 deletions(-) diff --git a/ansible_mitogen/loaders.py b/ansible_mitogen/loaders.py index 00a89b74..c00915d5 100644 --- a/ansible_mitogen/loaders.py +++ b/ansible_mitogen/loaders.py @@ -31,6 +31,7 @@ Stable names for PluginLoader instances across Ansible versions. """ from __future__ import absolute_import +import distutils.version __all__ = [ 'action_loader', @@ -41,21 +42,59 @@ __all__ = [ 'strategy_loader', ] -try: - from ansible.plugins.loader import action_loader - from ansible.plugins.loader import connection_loader - from ansible.plugins.loader import module_loader - from ansible.plugins.loader import module_utils_loader - from ansible.plugins.loader import shell_loader - from ansible.plugins.loader import strategy_loader -except ImportError: # Ansible <2.4 - from ansible.plugins import action_loader - from ansible.plugins import connection_loader - from ansible.plugins import module_loader - from ansible.plugins import module_utils_loader - from ansible.plugins import shell_loader - from ansible.plugins import strategy_loader +import ansible +ANSIBLE_VERSION_MIN = (2, 10) +ANSIBLE_VERSION_MAX = (2, 10) + +NEW_VERSION_MSG = ( + "Your Ansible version (%s) is too recent. The most recent version\n" + "supported by Mitogen for Ansible is %s.x. Please check the Mitogen\n" + "release notes to see if a new version is available, otherwise\n" + "subscribe to the corresponding GitHub issue to be notified when\n" + "support becomes available.\n" + "\n" + " https://mitogen.rtfd.io/en/latest/changelog.html\n" + " https://github.com/mitogen-hq/mitogen/issues/\n" +) +OLD_VERSION_MSG = ( + "Your version of Ansible (%s) is too old. The oldest version supported by " + "Mitogen for Ansible is %s." +) + + +def assert_supported_release(): + """ + Throw AnsibleError with a descriptive message in case of being loaded into + an unsupported Ansible release. + """ + v = ansible.__version__ + if not isinstance(v, tuple): + v = tuple(distutils.version.LooseVersion(v).version) + + if v[:2] < ANSIBLE_VERSION_MIN: + raise ansible.errors.AnsibleError( + OLD_VERSION_MSG % (v, ANSIBLE_VERSION_MIN) + ) + + if v[:2] > ANSIBLE_VERSION_MAX: + raise ansible.errors.AnsibleError( + NEW_VERSION_MSG % (ansible.__version__, ANSIBLE_VERSION_MAX) + ) + + +# this is the first file our strategy plugins import, so we need to check this here +# in prior Ansible versions, connection_loader.get_with_context didn't exist, so if a user +# is trying to load an old Ansible version, we'll fail and error gracefully +assert_supported_release() + + +from ansible.plugins.loader import action_loader +from ansible.plugins.loader import connection_loader +from ansible.plugins.loader import module_loader +from ansible.plugins.loader import module_utils_loader +from ansible.plugins.loader import shell_loader +from ansible.plugins.loader import strategy_loader # These are original, unwrapped implementations action_loader__get = action_loader.get diff --git a/ansible_mitogen/planner.py b/ansible_mitogen/planner.py index faf8d197..c0913a3e 100644 --- a/ansible_mitogen/planner.py +++ b/ansible_mitogen/planner.py @@ -436,26 +436,16 @@ def py_modname_from_path(name, path): Fetch the logical name of a new-style module as it might appear in :data:`sys.modules` of the target's Python interpreter. - * For Ansible <2.7, this is an unpackaged module named like - "ansible_module_%s". - - * For Ansible <2.9, this is an unpackaged module named like - "ansible.modules.%s" - * Since Ansible 2.9, modules appearing within a package have the original package hierarchy approximated on the target, enabling relative imports to function correctly. For example, "ansible.modules.system.setup". """ - # 2.9+ if _get_ansible_module_fqn: try: return _get_ansible_module_fqn(path) except ValueError: pass - if ansible.__version__ < '2.7': - return 'ansible_module_' + name - return 'ansible.modules.' + name diff --git a/ansible_mitogen/strategy.py b/ansible_mitogen/strategy.py index ddc0a5b6..792cfada 100644 --- a/ansible_mitogen/strategy.py +++ b/ansible_mitogen/strategy.py @@ -27,7 +27,6 @@ # POSSIBILITY OF SUCH DAMAGE. from __future__ import absolute_import -import distutils.version import os import signal import threading @@ -43,52 +42,8 @@ import ansible_mitogen.loaders import ansible_mitogen.mixins import ansible_mitogen.process -import ansible import ansible.executor.process.worker - -try: - # 2.8+ has a standardized "unset" object. - from ansible.utils.sentinel import Sentinel -except ImportError: - Sentinel = None - -ANSIBLE_VERSION_MIN = (2, 10) -ANSIBLE_VERSION_MAX = (2, 10) - -NEW_VERSION_MSG = ( - "Your Ansible version (%s) is too recent. The most recent version\n" - "supported by Mitogen for Ansible is %s.x. Please check the Mitogen\n" - "release notes to see if a new version is available, otherwise\n" - "subscribe to the corresponding GitHub issue to be notified when\n" - "support becomes available.\n" - "\n" - " https://mitogen.rtfd.io/en/latest/changelog.html\n" - " https://github.com/dw/mitogen/issues/\n" -) -OLD_VERSION_MSG = ( - "Your version of Ansible (%s) is too old. The oldest version supported by " - "Mitogen for Ansible is %s." -) - - -def _assert_supported_release(): - """ - Throw AnsibleError with a descriptive message in case of being loaded into - an unsupported Ansible release. - """ - v = ansible.__version__ - if not isinstance(v, tuple): - v = tuple(distutils.version.LooseVersion(v).version) - - if v[:2] < ANSIBLE_VERSION_MIN: - raise ansible.errors.AnsibleError( - OLD_VERSION_MSG % (v, ANSIBLE_VERSION_MIN) - ) - - if v[:2] > ANSIBLE_VERSION_MAX: - raise ansible.errors.AnsibleError( - NEW_VERSION_MSG % (ansible.__version__, ANSIBLE_VERSION_MAX) - ) +from ansible.utils.sentinel import Sentinel def _patch_awx_callback(): @@ -351,7 +306,6 @@ class StrategyMixin(object): Wrap :meth:`run` to ensure requisite infrastructure and modifications are configured for the duration of the call. """ - _assert_supported_release() wrappers = AnsibleWrappers() self._worker_model = self._get_worker_model() ansible_mitogen.process.set_worker_model(self._worker_model) diff --git a/docs/changelog.rst b/docs/changelog.rst index 99c30798..21d5d1a3 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -23,6 +23,7 @@ v0.3.0 (unreleased) This release separates itself from the v0.2.X releases. Ansible's API changed too much to support backwards compatibility so from now on, v0.2.X releases will be for Ansible < 2.10 and v0.3.X will be for Ansible 2.10+. `See here for details `_. +* :gh:issue:`770` better check for supported Ansible version * :gh:issue:`731` ansible 2.10 support * :gh:issue:`652` support for ansible collections import hook