diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg index c40f729df3d713064ad31d62b6e3ba0619246d53..827f17f5576bde9fb2df95819785946c04c872f0 100644 --- a/ansible/ansible.cfg +++ b/ansible/ansible.cfg @@ -3,5 +3,5 @@ callback_whitelist = profile_tasks, timer inventory = inventory.yml nocows = 1 stdout_callback = yaml -strategy_plugins = plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy +strategy_plugins = plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy strategy = mitogen_linear diff --git a/ansible/bootstrap.yml b/ansible/bootstrap.yml index 134b6b79c395d1a015ad675983a820c0f0b9a130..44809af9d59394fdbac24065072ae467b09e5e88 100644 --- a/ansible/bootstrap.yml +++ b/ansible/bootstrap.yml @@ -6,10 +6,9 @@ - name: Require minimal ansible version assert: that: - - "ansible_version.full is version_compare('2.7', '>=')" - - "ansible_version.full is version_compare('2.8', '<')" + - "ansible_version.full is version_compare('2.8', '>=')" msg: > - "Please use Ansible 2.7.x to bootstrap your OAS cluster." + "Please use Ansible 2.8.x to bootstrap your OAS cluster." - name: Release name must start with lower case assert: diff --git a/ansible/plugins/mitogen-0.2.7/LICENSE b/ansible/plugins/mitogen-0.2.8-pre/LICENSE similarity index 100% rename from ansible/plugins/mitogen-0.2.7/LICENSE rename to ansible/plugins/mitogen-0.2.8-pre/LICENSE diff --git a/ansible/plugins/mitogen-0.2.7/README.md b/ansible/plugins/mitogen-0.2.8-pre/README.md similarity index 88% rename from ansible/plugins/mitogen-0.2.7/README.md rename to ansible/plugins/mitogen-0.2.8-pre/README.md index 5ef2447f5308e242f4a7bb013f852cf79f8f9b96..da93a80b5b00f537fe36dd2eecd33ef79ef62862 100644 --- a/ansible/plugins/mitogen-0.2.7/README.md +++ b/ansible/plugins/mitogen-0.2.8-pre/README.md @@ -2,7 +2,7 @@ # Mitogen <!-- [](https://travis-ci.org/dw/mitogen}) --> -<a href="https://mitogen.readthedocs.io/">Please see the documentation</a>. +<a href="https://mitogen.networkgenomics.com/">Please see the documentation</a>.  diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/__init__.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/__init__.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/__init__.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/__init__.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/affinity.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/affinity.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/affinity.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/affinity.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/__init__.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/__init__.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/__init__.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/__init__.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/simplejson/__init__.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/simplejson/__init__.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/simplejson/__init__.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/simplejson/__init__.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/simplejson/decoder.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/simplejson/decoder.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/simplejson/decoder.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/simplejson/decoder.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/simplejson/encoder.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/simplejson/encoder.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/simplejson/encoder.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/simplejson/encoder.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/simplejson/scanner.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/simplejson/scanner.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/compat/simplejson/scanner.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/compat/simplejson/scanner.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/connection.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/connection.py similarity index 97% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/connection.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/connection.py index b5f28d342e19695f4c20a0a78adb9734a5aecfee..42fa2ef860b275d0735c48e9aced402f97304be8 100644 --- a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/connection.py +++ b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/connection.py @@ -145,9 +145,29 @@ def _connect_ssh(spec): 'ssh_args': spec.ssh_args(), 'ssh_debug_level': spec.mitogen_ssh_debug_level(), 'remote_name': get_remote_name(spec), + 'keepalive_count': ( + spec.mitogen_ssh_keepalive_count() or 10 + ), + 'keepalive_interval': ( + spec.mitogen_ssh_keepalive_interval() or 30 + ), } } +def _connect_buildah(spec): + """ + Return ContextService arguments for a Buildah connection. + """ + return { + 'method': 'buildah', + 'kwargs': { + 'username': spec.remote_user(), + 'container': spec.remote_addr(), + 'python_path': spec.python_path(), + 'connect_timeout': spec.ansible_ssh_timeout() or spec.timeout(), + 'remote_name': get_remote_name(spec), + } + } def _connect_docker(spec): """ @@ -356,7 +376,7 @@ def _connect_mitogen_doas(spec): 'username': spec.remote_user(), 'password': spec.password(), 'python_path': spec.python_path(), - 'doas_path': spec.become_exe(), + 'doas_path': spec.ansible_doas_exe(), 'connect_timeout': spec.timeout(), 'remote_name': get_remote_name(spec), } @@ -367,6 +387,7 @@ def _connect_mitogen_doas(spec): #: generating ContextService keyword arguments matching a connection #: specification. CONNECTION_METHOD = { + 'buildah': _connect_buildah, 'docker': _connect_docker, 'kubectl': _connect_kubectl, 'jail': _connect_jail, diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/loaders.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/loaders.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/loaders.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/loaders.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/logging.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/logging.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/logging.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/logging.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/mixins.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/mixins.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/mixins.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/mixins.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/module_finder.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/module_finder.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/module_finder.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/module_finder.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/parsing.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/parsing.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/parsing.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/parsing.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/planner.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/planner.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/planner.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/planner.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/__init__.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/__init__.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/__init__.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/__init__.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/action/__init__.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/action/__init__.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/action/__init__.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/action/__init__.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/action/mitogen_get_stack.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/action/mitogen_get_stack.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/action/mitogen_get_stack.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/action/mitogen_get_stack.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/__init__.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/__init__.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/__init__.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/__init__.py diff --git a/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_buildah.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_buildah.py new file mode 100644 index 0000000000000000000000000000000000000000..017214b2469c497cf8a1e99016af1dbde41917eb --- /dev/null +++ b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_buildah.py @@ -0,0 +1,44 @@ +# Copyright 2019, David Wilson +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from __future__ import absolute_import +import os.path +import sys + +try: + import ansible_mitogen +except ImportError: + base_dir = os.path.dirname(__file__) + sys.path.insert(0, os.path.abspath(os.path.join(base_dir, '../../..'))) + del base_dir + +import ansible_mitogen.connection + + +class Connection(ansible_mitogen.connection.Connection): + transport = 'buildah' diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_doas.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_doas.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_doas.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_doas.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_docker.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_docker.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_docker.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_docker.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_jail.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_jail.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_jail.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_jail.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_kubectl.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_kubectl.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_kubectl.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_kubectl.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_local.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_local.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_local.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_local.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_lxc.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_lxc.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_lxc.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_lxc.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_lxd.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_lxd.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_lxd.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_lxd.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_machinectl.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_machinectl.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_machinectl.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_machinectl.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_setns.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_setns.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_setns.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_setns.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_ssh.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_ssh.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_ssh.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_ssh.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_su.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_su.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_su.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_su.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_sudo.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_sudo.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/connection/mitogen_sudo.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/connection/mitogen_sudo.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/__init__.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/__init__.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/__init__.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/__init__.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/mitogen.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/mitogen.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/mitogen.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/mitogen.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/mitogen_free.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/mitogen_free.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/mitogen_free.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/mitogen_free.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/mitogen_host_pinned.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/mitogen_host_pinned.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/mitogen_host_pinned.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/mitogen_host_pinned.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/mitogen_linear.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/mitogen_linear.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/plugins/strategy/mitogen_linear.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/plugins/strategy/mitogen_linear.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/process.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/process.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/process.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/process.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/runner.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/runner.py similarity index 92% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/runner.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/runner.py index 30c36be75ed777865a50672a6a6e5a5e1767d105..843ffe19a3c9a82c4bd851d73a20b45a3c45888d 100644 --- a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/runner.py +++ b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/runner.py @@ -112,6 +112,45 @@ else: for token in shlex.split(str(s), comments=comments)] +class TempFileWatcher(object): + """ + Since Ansible 2.7.0, lineinfile leaks file descriptors returned by + :func:`tempfile.mkstemp` (ansible/ansible#57327). Handle this and all + similar cases by recording descriptors produced by mkstemp during module + execution, and cleaning up any leaked descriptors on completion. + """ + def __init__(self): + self._real_mkstemp = tempfile.mkstemp + # (fd, st.st_dev, st.st_ino) + self._fd_dev_inode = [] + tempfile.mkstemp = self._wrap_mkstemp + + def _wrap_mkstemp(self, *args, **kwargs): + fd, path = self._real_mkstemp(*args, **kwargs) + st = os.fstat(fd) + self._fd_dev_inode.append((fd, st.st_dev, st.st_ino)) + return fd, path + + def revert(self): + tempfile.mkstemp = self._real_mkstemp + for tup in self._fd_dev_inode: + self._revert_one(*tup) + + def _revert_one(self, fd, st_dev, st_ino): + try: + st = os.fstat(fd) + except OSError: + # FD no longer exists. + return + + if not (st.st_dev == st_dev and st.st_ino == st_ino): + # FD reused. + return + + LOG.info("a tempfile.mkstemp() FD was leaked during the last task") + os.close(fd) + + class EnvironmentFileWatcher(object): """ Usually Ansible edits to /etc/environment and ~/.pam_environment are @@ -344,11 +383,22 @@ class Runner(object): env.update(self.env) self._env = TemporaryEnvironment(env) + def _revert_cwd(self): + """ + #591: make a best-effort attempt to return to :attr:`good_temp_dir`. + """ + try: + os.chdir(self.good_temp_dir) + except OSError: + LOG.debug('%r: could not restore CWD to %r', + self, self.good_temp_dir) + def revert(self): """ Revert any changes made to the process after running a module. The base implementation simply restores the original environment. """ + self._revert_cwd() self._env.revert() self.revert_temp_dir() @@ -760,7 +810,21 @@ class NewStyleRunner(ScriptRunner): for fullname, _, _ in self.module_map['custom']: mitogen.core.import_module(fullname) for fullname in self.module_map['builtin']: - mitogen.core.import_module(fullname) + try: + mitogen.core.import_module(fullname) + except ImportError: + # #590: Ansible 2.8 module_utils.distro is a package that + # replaces itself in sys.modules with a non-package during + # import. Prior to replacement, it is a real package containing + # a '_distro' submodule which is used on 2.x. Given a 2.x + # controller and 3.x target, the import hook never needs to run + # again before this replacement occurs, and 'distro' is + # replaced with a module from the stdlib. In this case as this + # loop progresses to the next entry and attempts to preload + # 'distro._distro', the import mechanism will fail. So here we + # silently ignore any failure for it. + if fullname != 'ansible.module_utils.distro._distro': + raise def _setup_excepthook(self): """ @@ -778,6 +842,7 @@ class NewStyleRunner(ScriptRunner): # module, but this has never been a bug report. Instead act like an # interpreter that had its script piped on stdin. self._argv = TemporaryArgv(['']) + self._temp_watcher = TempFileWatcher() self._importer = ModuleUtilsImporter( context=self.service_context, module_utils=self.module_map['custom'], @@ -793,6 +858,7 @@ class NewStyleRunner(ScriptRunner): def revert(self): self.atexit_wrapper.revert() + self._temp_watcher.revert() self._argv.revert() self._stdio.revert() self._revert_excepthook() diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/services.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/services.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/services.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/services.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/strategy.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/strategy.py similarity index 93% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/strategy.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/strategy.py index b9211fcc01793d220c8d5981b4e35937130e7241..01dff285401dcbd07c1daffffc8ffec77d4e8556 100644 --- a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/strategy.py +++ b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/strategy.py @@ -40,9 +40,15 @@ 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.3' -ANSIBLE_VERSION_MAX = '2.7' +ANSIBLE_VERSION_MAX = '2.8' 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" @@ -115,7 +121,11 @@ def wrap_action_loader__get(name, *args, **kwargs): This is used instead of static subclassing as it generalizes to third party action modules outside the Ansible tree. """ - klass = action_loader__get(name, class_only=True) + get_kwargs = {'class_only': True} + if ansible.__version__ >= '2.8': + get_kwargs['collection_list'] = kwargs.pop('collection_list', None) + + klass = action_loader__get(name, **get_kwargs) if klass: bases = (ansible_mitogen.mixins.ActionModuleMixin, klass) adorned_klass = type(str(name), bases, {}) @@ -129,8 +139,8 @@ def wrap_connection_loader__get(name, *args, **kwargs): While the strategy is active, rewrite connection_loader.get() calls for some transports into requests for a compatible Mitogen transport. """ - if name in ('docker', 'kubectl', 'jail', 'local', 'lxc', - 'lxd', 'machinectl', 'setns', 'ssh'): + if name in ('buildah', 'docker', 'kubectl', 'jail', 'local', + 'lxc', 'lxd', 'machinectl', 'setns', 'ssh'): name = 'mitogen_' + name return connection_loader__get(name, *args, **kwargs) @@ -261,14 +271,17 @@ class StrategyMixin(object): name=task.action, mod_type='', ) - ansible_mitogen.loaders.connection_loader.get( - name=play_context.connection, - class_only=True, - ) ansible_mitogen.loaders.action_loader.get( name=task.action, class_only=True, ) + if play_context.connection is not Sentinel: + # 2.8 appears to defer computing this until inside the worker. + # TODO: figure out where it has moved. + ansible_mitogen.loaders.connection_loader.get( + name=play_context.connection, + class_only=True, + ) return super(StrategyMixin, self)._queue_task( host=host, diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/target.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/target.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/target.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/target.py diff --git a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/transport_config.py b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/transport_config.py similarity index 90% rename from ansible/plugins/mitogen-0.2.7/ansible_mitogen/transport_config.py rename to ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/transport_config.py index ad1cab3ed65de782f96ffa64eca09ef2f6bd5462..aa4a16d0172848930e006bd4c612a0817cbbba79 100644 --- a/ansible/plugins/mitogen-0.2.7/ansible_mitogen/transport_config.py +++ b/ansible/plugins/mitogen-0.2.8-pre/ansible_mitogen/transport_config.py @@ -240,6 +240,12 @@ class Spec(with_metaclass(abc.ABCMeta, object)): undesirable in some circumstances. """ + @abc.abstractmethod + def mitogen_buildah_path(self): + """ + The path to the "buildah" program for the 'buildah' transport. + """ + @abc.abstractmethod def mitogen_docker_path(self): """ @@ -276,6 +282,18 @@ class Spec(with_metaclass(abc.ABCMeta, object)): The path to the "machinectl" program for the 'setns' transport. """ + @abc.abstractmethod + def mitogen_ssh_keepalive_interval(self): + """ + The SSH ServerAliveInterval. + """ + + @abc.abstractmethod + def mitogen_ssh_keepalive_count(self): + """ + The SSH ServerAliveCount. + """ + @abc.abstractmethod def mitogen_ssh_debug_level(self): """ @@ -294,6 +312,12 @@ class Spec(with_metaclass(abc.ABCMeta, object)): Connection-specific arguments. """ + @abc.abstractmethod + def ansible_doas_exe(self): + """ + Value of "ansible_doas_exe" variable. + """ + class PlayContextSpec(Spec): """ @@ -372,7 +396,15 @@ class PlayContextSpec(Spec): ] def become_exe(self): - return self._play_context.become_exe + # In Ansible 2.8, PlayContext.become_exe always has a default value due + # to the new options mechanism. Previously it was only set if a value + # ("somewhere") had been specified for the task. + # For consistency in the tests, here we make older Ansibles behave like + # newer Ansibles. + exe = self._play_context.become_exe + if exe is None and self._play_context.become_method == 'sudo': + exe = 'sudo' + return exe def sudo_args(self): return [ @@ -380,8 +412,9 @@ class PlayContextSpec(Spec): for term in ansible.utils.shlex.shlex_split( first_true(( self._play_context.become_flags, - self._play_context.sudo_flags, - # Ansible 2.3. + # Ansible <=2.7. + getattr(self._play_context, 'sudo_flags', ''), + # Ansible <=2.3. getattr(C, 'DEFAULT_BECOME_FLAGS', ''), getattr(C, 'DEFAULT_SUDO_FLAGS', '') ), default='') @@ -397,6 +430,9 @@ class PlayContextSpec(Spec): def mitogen_mask_remote_name(self): return self._connection.get_task_var('mitogen_mask_remote_name') + def mitogen_buildah_path(self): + return self._connection.get_task_var('mitogen_buildah_path') + def mitogen_docker_path(self): return self._connection.get_task_var('mitogen_docker_path') @@ -412,6 +448,12 @@ class PlayContextSpec(Spec): def mitogen_lxc_info_path(self): return self._connection.get_task_var('mitogen_lxc_info_path') + def mitogen_ssh_keepalive_interval(self): + return self._connection.get_task_var('mitogen_ssh_keepalive_interval') + + def mitogen_ssh_keepalive_count(self): + return self._connection.get_task_var('mitogen_ssh_keepalive_count') + def mitogen_machinectl_path(self): return self._connection.get_task_var('mitogen_machinectl_path') @@ -424,6 +466,12 @@ class PlayContextSpec(Spec): def extra_args(self): return self._connection.get_extra_args() + def ansible_doas_exe(self): + return ( + self._connection.get_task_var('ansible_doas_exe') or + os.environ.get('ANSIBLE_DOAS_EXE') + ) + class MitogenViaSpec(Spec): """ @@ -608,6 +656,9 @@ class MitogenViaSpec(Spec): def mitogen_mask_remote_name(self): return self._host_vars.get('mitogen_mask_remote_name') + def mitogen_buildah_path(self): + return self._host_vars.get('mitogen_buildah_path') + def mitogen_docker_path(self): return self._host_vars.get('mitogen_docker_path') @@ -623,6 +674,12 @@ class MitogenViaSpec(Spec): def mitogen_lxc_info_path(self): return self._host_vars.get('mitogen_lxc_info_path') + def mitogen_ssh_keepalive_interval(self): + return self._host_vars.get('mitogen_ssh_keepalive_interval') + + def mitogen_ssh_keepalive_count(self): + return self._host_vars.get('mitogen_ssh_keepalive_count') + def mitogen_machinectl_path(self): return self._host_vars.get('mitogen_machinectl_path') @@ -634,3 +691,9 @@ class MitogenViaSpec(Spec): def extra_args(self): return [] # TODO + + def ansible_doas_exe(self): + return ( + self._host_vars.get('ansible_doas_exe') or + os.environ.get('ANSIBLE_DOAS_EXE') + ) diff --git a/ansible/plugins/mitogen-0.2.7/dev_requirements.txt b/ansible/plugins/mitogen-0.2.8-pre/dev_requirements.txt similarity index 100% rename from ansible/plugins/mitogen-0.2.7/dev_requirements.txt rename to ansible/plugins/mitogen-0.2.8-pre/dev_requirements.txt diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/__init__.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/__init__.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/__init__.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/__init__.py diff --git a/ansible/plugins/mitogen-0.2.8-pre/mitogen/buildah.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/buildah.py new file mode 100644 index 0000000000000000000000000000000000000000..eec415f3223dd3eced64dd9d10317522165a6125 --- /dev/null +++ b/ansible/plugins/mitogen-0.2.8-pre/mitogen/buildah.py @@ -0,0 +1,73 @@ +# Copyright 2019, David Wilson +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# !mitogen: minify_safe + +import logging + +import mitogen.core +import mitogen.parent + + +LOG = logging.getLogger(__name__) + + +class Stream(mitogen.parent.Stream): + child_is_immediate_subprocess = False + + container = None + username = None + buildah_path = 'buildah' + + # TODO: better way of capturing errors such as "No such container." + create_child_args = { + 'merge_stdio': True + } + + def construct(self, container=None, + buildah_path=None, username=None, + **kwargs): + assert container or image + super(Stream, self).construct(**kwargs) + if container: + self.container = container + if buildah_path: + self.buildah_path = buildah_path + if username: + self.username = username + + def _get_name(self): + return u'buildah.' + self.container + + def get_boot_command(self): + args = [] + if self.username: + args += ['--user=' + self.username] + bits = [self.buildah_path, 'run'] + args + ['--', self.container] + + return bits + super(Stream, self).get_boot_command() diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/compat/__init__.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/compat/__init__.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/compat/__init__.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/compat/__init__.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/compat/pkgutil.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/compat/pkgutil.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/compat/pkgutil.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/compat/pkgutil.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/compat/tokenize.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/compat/tokenize.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/compat/tokenize.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/compat/tokenize.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/core.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/core.py similarity index 99% rename from ansible/plugins/mitogen-0.2.7/mitogen/core.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/core.py index ff77bba99c7868393b00bcf31e5777f361d322ce..ea83f9618e1a2b411e6ad285f0a9652de0234750 100644 --- a/ansible/plugins/mitogen-0.2.7/mitogen/core.py +++ b/ansible/plugins/mitogen-0.2.8-pre/mitogen/core.py @@ -1089,6 +1089,7 @@ class Importer(object): # The Mitogen package is handled specially, since the child context must # construct it manually during startup. MITOGEN_PKG_CONTENT = [ + 'buildah', 'compat', 'debug', 'doas', @@ -1355,7 +1356,10 @@ class Importer(object): exec(code, vars(mod)) else: exec('exec code in vars(mod)') - return mod + + # #590: if a module replaces itself in sys.modules during import, below + # is necessary. This matches PyImport_ExecCodeModuleEx() + return sys.modules.get(fullname, mod) def get_filename(self, fullname): if fullname in self._cache: diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/debug.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/debug.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/debug.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/debug.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/doas.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/doas.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/doas.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/doas.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/docker.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/docker.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/docker.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/docker.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/fakessh.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/fakessh.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/fakessh.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/fakessh.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/fork.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/fork.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/fork.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/fork.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/jail.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/jail.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/jail.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/jail.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/kubectl.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/kubectl.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/kubectl.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/kubectl.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/lxc.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/lxc.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/lxc.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/lxc.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/lxd.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/lxd.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/lxd.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/lxd.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/master.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/master.py similarity index 87% rename from ansible/plugins/mitogen-0.2.7/mitogen/master.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/master.py index 1396f4e10fb523dee65fc8e62d4a03f774622606..fb4f505b5f413076f250627d0208dcaccc5b5d8d 100644 --- a/ansible/plugins/mitogen-0.2.7/mitogen/master.py +++ b/ansible/plugins/mitogen-0.2.8-pre/mitogen/master.py @@ -36,6 +36,7 @@ contexts. """ import dis +import errno import imp import inspect import itertools @@ -45,11 +46,16 @@ import pkgutil import re import string import sys -import time import threading +import time import types import zlib +try: + import sysconfig +except ImportError: + sysconfig = None + if not hasattr(pkgutil, 'find_loader'): # find_loader() was new in >=2.5, but the modern pkgutil.py syntax has # been kept intentionally 2.3 compatible so we can reuse it. @@ -92,10 +98,16 @@ def _stdlib_paths(): 'real_prefix', # virtualenv: only set inside a virtual environment. 'base_prefix', # venv: always set, equal to prefix if outside. ] - prefixes = (getattr(sys, a) for a in attr_candidates if hasattr(sys, a)) + prefixes = (getattr(sys, a, None) for a in attr_candidates) version = 'python%s.%s' % sys.version_info[0:2] - return set(os.path.abspath(os.path.join(p, 'lib', version)) - for p in prefixes) + s = set(os.path.abspath(os.path.join(p, 'lib', version)) + for p in prefixes if p is not None) + + # When running 'unit2 tests/module_finder_test.py' in a Py2 venv on Ubuntu + # 18.10, above is insufficient to catch the real directory. + if sysconfig is not None: + s.add(sysconfig.get_config_var('DESTLIB')) + return s def is_stdlib_name(modname): @@ -142,6 +154,41 @@ def get_child_modules(path): return [to_text(name) for _, name, _ in it] +def _looks_like_script(path): + """ + Return :data:`True` if the (possibly extensionless) file at `path` + resembles a Python script. For now we simply verify the file contains + ASCII text. + """ + try: + fp = open(path, 'rb') + except IOError: + e = sys.exc_info()[1] + if e.args[0] == errno.EISDIR: + return False + raise + + try: + sample = fp.read(512).decode('latin-1') + return not set(sample).difference(string.printable) + finally: + fp.close() + + +def _py_filename(path): + if not path: + return None + + if path[-4:] in ('.pyc', '.pyo'): + path = path.rstrip('co') + + if path.endswith('.py'): + return path + + if os.path.exists(path) and _looks_like_script(path): + return path + + def _get_core_source(): """ Master version of parent.get_core_source(). @@ -368,56 +415,38 @@ class LogForwarder(object): return 'LogForwarder(%r)' % (self._router,) -class ModuleFinder(object): +class FinderMethod(object): """ - Given the name of a loaded module, make a best-effort attempt at finding - related modules likely needed by a child context requesting the original - module. + Interface to a method for locating a Python module or package given its + name according to the running Python interpreter. You'd think this was a + simple task, right? Naive young fellow, welcome to the real world. """ - def __init__(self): - #: Import machinery is expensive, keep :py:meth`:get_module_source` - #: results around. - self._found_cache = {} - - #: Avoid repeated dependency scanning, which is expensive. - self._related_cache = {} - def __repr__(self): - return 'ModuleFinder()' + return '%s()' % (type(self).__name__,) - def _looks_like_script(self, path): - """ - Return :data:`True` if the (possibly extensionless) file at `path` - resembles a Python script. For now we simply verify the file contains - ASCII text. + def find(self, fullname): """ - fp = open(path, 'rb') - try: - sample = fp.read(512).decode('latin-1') - return not set(sample).difference(string.printable) - finally: - fp.close() + Accept a canonical module name and return `(path, source, is_pkg)` + tuples, where: - def _py_filename(self, path): - if not path: - return None - - if path[-4:] in ('.pyc', '.pyo'): - path = path.rstrip('co') + * `path`: Unicode string containing path to source file. + * `source`: Bytestring containing source file's content. + * `is_pkg`: :data:`True` if `fullname` is a package. - if path.endswith('.py'): - return path + :returns: + :data:`None` if not found, or tuple as described above. + """ + raise NotImplementedError() - if os.path.exists(path) and self._looks_like_script(path): - return path - def _get_main_module_defective_python_3x(self, fullname): - """ - Recent versions of Python 3.x introduced an incomplete notion of - importer specs, and in doing so created permanent asymmetry in the - :mod:`pkgutil` interface handling for the `__main__` module. Therefore - we must handle `__main__` specially. - """ +class DefectivePython3xMainMethod(FinderMethod): + """ + Recent versions of Python 3.x introduced an incomplete notion of + importer specs, and in doing so created permanent asymmetry in the + :mod:`pkgutil` interface handling for the `__main__` module. Therefore + we must handle `__main__` specially. + """ + def find(self, fullname): if fullname != '__main__': return None @@ -426,7 +455,7 @@ class ModuleFinder(object): return None path = getattr(mod, '__file__', None) - if not (os.path.exists(path) and self._looks_like_script(path)): + if not (os.path.exists(path) and _looks_like_script(path)): return None fp = open(path, 'rb') @@ -437,11 +466,13 @@ class ModuleFinder(object): return path, source, False - def _get_module_via_pkgutil(self, fullname): - """ - Attempt to fetch source code via pkgutil. In an ideal world, this would - be the only required implementation of get_module(). - """ + +class PkgutilMethod(FinderMethod): + """ + Attempt to fetch source code via pkgutil. In an ideal world, this would + be the only required implementation of get_module(). + """ + def find(self, fullname): try: # Pre-'import spec' this returned None, in Python3.6 it raises # ImportError. @@ -458,7 +489,7 @@ class ModuleFinder(object): return try: - path = self._py_filename(loader.get_filename(fullname)) + path = _py_filename(loader.get_filename(fullname)) source = loader.get_source(fullname) is_pkg = loader.is_package(fullname) except (AttributeError, ImportError): @@ -484,19 +515,27 @@ class ModuleFinder(object): return path, source, is_pkg - def _get_module_via_sys_modules(self, fullname): - """ - Attempt to fetch source code via sys.modules. This is specifically to - support __main__, but it may catch a few more cases. - """ + +class SysModulesMethod(FinderMethod): + """ + Attempt to fetch source code via sys.modules. This is specifically to + support __main__, but it may catch a few more cases. + """ + def find(self, fullname): module = sys.modules.get(fullname) LOG.debug('_get_module_via_sys_modules(%r) -> %r', fullname, module) + if getattr(module, '__name__', None) != fullname: + LOG.debug('sys.modules[%r].__name__ does not match %r, assuming ' + 'this is a hacky module alias and ignoring it', + fullname, fullname) + return + if not isinstance(module, types.ModuleType): LOG.debug('sys.modules[%r] absent or not a regular module', fullname) return - path = self._py_filename(getattr(module, '__file__', '')) + path = _py_filename(getattr(module, '__file__', '')) if not path: return @@ -517,12 +556,19 @@ class ModuleFinder(object): return path, source, is_pkg - def _get_module_via_parent_enumeration(self, fullname): - """ - Attempt to fetch source code by examining the module's (hopefully less - insane) parent package. Required for older versions of - ansible.compat.six and plumbum.colors. - """ + +class ParentEnumerationMethod(FinderMethod): + """ + Attempt to fetch source code by examining the module's (hopefully less + insane) parent package. Required for older versions of + ansible.compat.six and plumbum.colors, and Ansible 2.8 + ansible.module_utils.distro. + + For cases like module_utils.distro, this must handle cases where a package + transmuted itself into a totally unrelated module during import and vice + versa. + """ + def find(self, fullname): if fullname not in sys.modules: # Don't attempt this unless a module really exists in sys.modules, # else we could return junk. @@ -531,30 +577,68 @@ class ModuleFinder(object): pkgname, _, modname = str_rpartition(to_text(fullname), u'.') pkg = sys.modules.get(pkgname) if pkg is None or not hasattr(pkg, '__file__'): + LOG.debug('%r: %r is not a package or lacks __file__ attribute', + self, pkgname) return - pkg_path = os.path.dirname(pkg.__file__) + pkg_path = [os.path.dirname(pkg.__file__)] try: - fp, path, ext = imp.find_module(modname, [pkg_path]) - try: - path = self._py_filename(path) - if not path: - fp.close() - return - - source = fp.read() - finally: - if fp: - fp.close() - - if isinstance(source, mitogen.core.UnicodeType): - # get_source() returns "string" according to PEP-302, which was - # reinterpreted for Python 3 to mean a Unicode string. - source = source.encode('utf-8') - return path, source, False + fp, path, (suffix, _, kind) = imp.find_module(modname, pkg_path) except ImportError: e = sys.exc_info()[1] - LOG.debug('imp.find_module(%r, %r) -> %s', modname, [pkg_path], e) + LOG.debug('%r: imp.find_module(%r, %r) -> %s', + self, modname, [pkg_path], e) + return None + + if kind == imp.PKG_DIRECTORY: + return self._found_package(fullname, path) + else: + return self._found_module(fullname, path, fp) + + def _found_package(self, fullname, path): + path = os.path.join(path, '__init__.py') + LOG.debug('%r: %r is PKG_DIRECTORY: %r', self, fullname, path) + return self._found_module( + fullname=fullname, + path=path, + fp=open(path, 'rb'), + is_pkg=True, + ) + + def _found_module(self, fullname, path, fp, is_pkg=False): + try: + path = _py_filename(path) + if not path: + return + + source = fp.read() + finally: + if fp: + fp.close() + + if isinstance(source, mitogen.core.UnicodeType): + # get_source() returns "string" according to PEP-302, which was + # reinterpreted for Python 3 to mean a Unicode string. + source = source.encode('utf-8') + return path, source, is_pkg + + +class ModuleFinder(object): + """ + Given the name of a loaded module, make a best-effort attempt at finding + related modules likely needed by a child context requesting the original + module. + """ + def __init__(self): + #: Import machinery is expensive, keep :py:meth`:get_module_source` + #: results around. + self._found_cache = {} + + #: Avoid repeated dependency scanning, which is expensive. + self._related_cache = {} + + def __repr__(self): + return 'ModuleFinder()' def add_source_override(self, fullname, path, source, is_pkg): """ @@ -576,10 +660,10 @@ class ModuleFinder(object): self._found_cache[fullname] = (path, source, is_pkg) get_module_methods = [ - _get_main_module_defective_python_3x, - _get_module_via_pkgutil, - _get_module_via_sys_modules, - _get_module_via_parent_enumeration, + DefectivePython3xMainMethod(), + PkgutilMethod(), + SysModulesMethod(), + ParentEnumerationMethod(), ] def get_module_source(self, fullname): @@ -595,7 +679,7 @@ class ModuleFinder(object): return tup for method in self.get_module_methods: - tup = method(self, fullname) + tup = method.find(fullname) if tup: #LOG.debug('%r returned %r', method, tup) break diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/minify.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/minify.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/minify.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/minify.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/os_fork.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/os_fork.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/os_fork.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/os_fork.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/parent.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/parent.py similarity index 99% rename from ansible/plugins/mitogen-0.2.7/mitogen/parent.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/parent.py index 3d02bc43e99c97acdda345543d09acfaa2686c38..113fdc2e9d7ed6741f28cf606e79e066d051e883 100644 --- a/ansible/plugins/mitogen-0.2.7/mitogen/parent.py +++ b/ansible/plugins/mitogen-0.2.8-pre/mitogen/parent.py @@ -2163,6 +2163,9 @@ class Router(mitogen.core.Router): self._write_lock.release() return context + def buildah(self, **kwargs): + return self.connect(u'buildah', **kwargs) + def doas(self, **kwargs): return self.connect(u'doas', **kwargs) diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/profiler.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/profiler.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/profiler.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/profiler.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/select.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/select.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/select.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/select.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/service.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/service.py similarity index 99% rename from ansible/plugins/mitogen-0.2.7/mitogen/service.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/service.py index 302e81ab8ff3f727e73a2d1788e388093a4429b6..942ed4f7f4ef8885336c36ba6beac696b5378727 100644 --- a/ansible/plugins/mitogen-0.2.7/mitogen/service.py +++ b/ansible/plugins/mitogen-0.2.8-pre/mitogen/service.py @@ -625,7 +625,7 @@ class PushFileService(Service): """ Push-based file service. Files are delivered and cached in RAM, sent recursively from parent to child. A child that requests a file via - :meth:`get` will block until it has ben delivered by a parent. + :meth:`get` will block until it has been delivered by a parent. This service will eventually be merged into FileService. """ diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/setns.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/setns.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/setns.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/setns.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/ssh.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/ssh.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/ssh.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/ssh.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/su.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/su.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/su.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/su.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/sudo.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/sudo.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/sudo.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/sudo.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/unix.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/unix.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/unix.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/unix.py diff --git a/ansible/plugins/mitogen-0.2.7/mitogen/utils.py b/ansible/plugins/mitogen-0.2.8-pre/mitogen/utils.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/mitogen/utils.py rename to ansible/plugins/mitogen-0.2.8-pre/mitogen/utils.py diff --git a/ansible/plugins/mitogen-0.2.7/preamble_size.py b/ansible/plugins/mitogen-0.2.8-pre/preamble_size.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/preamble_size.py rename to ansible/plugins/mitogen-0.2.8-pre/preamble_size.py diff --git a/ansible/plugins/mitogen-0.2.8-pre/scripts/debug-helpers.sh b/ansible/plugins/mitogen-0.2.8-pre/scripts/debug-helpers.sh new file mode 100644 index 0000000000000000000000000000000000000000..7011c18c6757d8b9662d0e59df98c105a26ad997 --- /dev/null +++ b/ansible/plugins/mitogen-0.2.8-pre/scripts/debug-helpers.sh @@ -0,0 +1,39 @@ +# +# Bash helpers for debugging. +# + +# Tell Ansible to write PID files for the mux and top-level process to CWD. +export MITOGEN_SAVE_PIDS=1 + + +# strace -ff -p $(muxpid) +muxpid() { + cat .ansible-mux.pid +} + +# gdb -p $(anspid) +anspid() { + cat .ansible-controller.pid +} + +# perf top -git $(muxtids) +# perf top -git $(muxtids) +muxtids() { + ls /proc/$(muxpid)/task | tr \\n , +} + +# perf top -git $(anstids) +anstids() { + ls /proc/$(anspid)/task | tr \\n , +} + +# ttrace $(muxpid) [.. options ..] +# strace only threads of PID, not children +ttrace() { + local pid=$1; shift; + local s="" + for i in $(ls /proc/$pid/task) ; do + s="-p $i $s" + done + strace $s "$@" +} diff --git a/ansible/plugins/mitogen-0.2.7/scripts/pogrep.py b/ansible/plugins/mitogen-0.2.8-pre/scripts/pogrep.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/scripts/pogrep.py rename to ansible/plugins/mitogen-0.2.8-pre/scripts/pogrep.py diff --git a/ansible/plugins/mitogen-0.2.7/setup.cfg b/ansible/plugins/mitogen-0.2.8-pre/setup.cfg similarity index 100% rename from ansible/plugins/mitogen-0.2.7/setup.cfg rename to ansible/plugins/mitogen-0.2.8-pre/setup.cfg diff --git a/ansible/plugins/mitogen-0.2.7/setup.py b/ansible/plugins/mitogen-0.2.8-pre/setup.py similarity index 100% rename from ansible/plugins/mitogen-0.2.7/setup.py rename to ansible/plugins/mitogen-0.2.8-pre/setup.py diff --git a/ansible/requirements.txt b/ansible/requirements.txt index 75eb868d1989249d67174423a82e8313d10215f2..5b90d017c8db6f4a1489967d0d550722bfb9460b 100644 --- a/ansible/requirements.txt +++ b/ansible/requirements.txt @@ -1,3 +1,2 @@ # ansible>=2.7 is needed for using the `k8s` resource -# [mitogen currently doesn't work with ansible 2.8](https://github.com/dw/mitogen/issues/587) -ansible>=2.7,<2.8 +ansible>=2.7 diff --git a/test/requirements.txt b/test/requirements.txt index aa1bb55727dffacc73b3ecf95df51610dc1f94e2..206c8817228eba30d79527d565aaad0c779d18a2 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,10 +1,11 @@ # ansible>=2.7 is needed for using the `k8s` resource -# [mitogen currently doesn't work with ansible 2.8](https://github.com/dw/mitogen/issues/587) -ansible>=2.7,<2.8 +ansible>=2.7 behave-webdriver>=0.2.2 certifi>=2019.3.9 # Needed for ansible k8s resource openshift>=0.8.6 +# Needed for testinfra using the ansible module +paramiko psutil>=5.5.0 pycurl>=7.43.0.2 pyopenssl>=19.0.0