Hello community,

here is the log from the commit of package python-testinfra for 
openSUSE:Factory checked in at 2019-09-04 09:10:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-testinfra (Old)
 and      /work/SRC/openSUSE:Factory/.python-testinfra.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-testinfra"

Wed Sep  4 09:10:23 2019 rev:10 rq:727101 version:3.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-testinfra/python-testinfra.changes        
2019-08-28 16:04:59.750768808 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-testinfra.new.7948/python-testinfra.changes  
    2019-09-04 09:10:37.726977459 +0200
@@ -1,0 +2,13 @@
+Wed Aug 28 12:26:12 UTC 2019 - Marketa Calabkova <[email protected]>
+
+- update to version 3.1.0
+  * ssh connections uses persistent connections by default.
+  * ansible ssh connections now use ssh backend instead of paramiko.
+  * Add a new ansible connection options “force_ansible”, when set 
+    to True, testinfra will always call ansible for all commands 
+    he need to run.
+  * Handle all ansible connections types by setting force_ansible=True 
+    for connections which doesn’t have a testinfra equivalent connection 
+    (for example “network_cli”).
+
+-------------------------------------------------------------------

Old:
----
  testinfra-3.0.6.tar.gz

New:
----
  testinfra-3.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-testinfra.spec ++++++
--- /var/tmp/diff_new_pack.BNPLI8/_old  2019-09-04 09:10:40.386977090 +0200
+++ /var/tmp/diff_new_pack.BNPLI8/_new  2019-09-04 09:10:40.390977089 +0200
@@ -18,14 +18,13 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-testinfra
-Version:        3.0.6
+Version:        3.1.0
 Release:        0
 Summary:        Python module to test infrastructures
 License:        Apache-2.0
 Group:          Development/Languages/Python
 URL:            http://github.com/philpep/testinfra
 Source:         
https://files.pythonhosted.org/packages/source/t/testinfra/testinfra-%{version}.tar.gz
-BuildRequires:  %{python_module paramiko}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module pywinrm}
 BuildRequires:  %{python_module salt}

++++++ testinfra-3.0.6.tar.gz -> testinfra-3.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/.travis.yml 
new/testinfra-3.1.0/.travis.yml
--- old/testinfra-3.0.6/.travis.yml     2019-07-07 01:41:09.000000000 +0200
+++ new/testinfra-3.1.0/.travis.yml     2019-08-10 11:59:33.000000000 +0200
@@ -1,16 +1,31 @@
 sudo: required
 services:
   - docker
-env:
-  matrix:
-    - TOXENV=py27,py3
-    - TOXENV=flake8
-    - TOXENV=pylint
-    - TOXENV=sphinxdoc
-    - TOXENV=check-manifest
 language: python
 python: 3.5
 install:
   - pip install tox
-script:
-  - tox -e $TOXENV
+jobs:
+  include:
+    - stage: lint
+      script: tox -e pylint
+      name: pylint
+    - script: tox -e flake8
+      name: flake8
+    - script: tox -e check-manifest
+      name: check-manifest
+    - script: tox -e sphinxdoc
+      name: sphinxdoc
+    - stage: test
+      script: tox -e py27,py3
+      name: python tests
+    - stage: deploy
+      name: deploy to pypi
+      script: skip
+      if: repo == "philpep/testinfra" AND tag IS present
+      deploy:
+        provider: pypi
+        user: "__token__"
+        on:
+          tags: true
+        distributions: "sdist bdist_wheel"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/CHANGELOG.rst 
new/testinfra-3.1.0/CHANGELOG.rst
--- old/testinfra-3.0.6/CHANGELOG.rst   2019-08-04 14:05:14.000000000 +0200
+++ new/testinfra-3.1.0/CHANGELOG.rst   2019-08-18 13:34:56.000000000 +0200
@@ -2,6 +2,19 @@
 Changelog
 =========
 
+3.1.0
+=====
+
+* ssh connections uses persistent connections by default. You can disable this
+  by passing controlpersist=0 to the connections options.
+* ansible ssh connections now use ssh backend instead of paramiko.
+  ansible_ssh_common_args and ansible_ssh_extra_args are now taking in account.
+* Add a new ansible connection options "force_ansible", when set to True,
+  testinfra will always call ansible for all commands he need to run.
+* Handle all ansible connections types by setting force_ansible=True for
+  connections which doesn't have a testinfra equivalent connection (for example
+  "network_cli").
+
 3.0.6
 =====
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/PKG-INFO new/testinfra-3.1.0/PKG-INFO
--- old/testinfra-3.0.6/PKG-INFO        2019-08-04 14:06:21.000000000 +0200
+++ new/testinfra-3.1.0/PKG-INFO        2019-08-18 19:03:01.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: testinfra
-Version: 3.0.6
+Version: 3.1.0
 Summary: Test infrastructures
 Home-page: https://github.com/philpep/testinfra
 Author: Philippe Pepiot
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/doc/source/backends.rst 
new/testinfra-3.1.0/doc/source/backends.rst
--- old/testinfra-3.0.6/doc/source/backends.rst 2019-08-04 13:12:17.000000000 
+0200
+++ new/testinfra-3.1.0/doc/source/backends.rst 2019-08-17 12:44:33.000000000 
+0200
@@ -44,11 +44,16 @@
 ssh
 ~~~
 
-This is a pure SSH backend using the ``ssh`` command available in ``$PATH``. 
Example::
+This is a pure SSH backend using the ``ssh`` command. Example::
 
     $ py.test --hosts='ssh://server'
+    $ py.test --ssh-config=/path/to/ssh_config --hosts='ssh://server'
+    $ py.test --ssh-identity-file=/path/to/key --hosts='ssh://server'
+    $ py.test --hosts='ssh://server?timeout=60&controlpersist=120'
 
-The ssh backend also accepts the ``--ssh-config`` option.
+
+By default timeout is set to 10 seconds and ControlPersist is set to 60 
seconds.
+You can disable persistent connection by passing `controlpersist=0` to the 
options.
 
 
 salt
@@ -73,13 +78,20 @@
 ansible
 ~~~~~~~
 
-The ansible backend is able to parse ansible inventories to get host connection
-details, including ``ansible_become`` and ``ansible_become_user``. It only
-works with local, ssh or docker hosts::
+The ansible backend is able to parse ansible inventories to get host 
connection details.
+For local, ssh, paramiko or docker connections it will use the equivalent
+testinfra connection backend, unless `force_ansible=True`.
+
+For other connections types or when `force_ansible=True`, testinfra will run
+all commands through ansible, which is substantially slower than using native
+connections backends.
+
+Examples::
 
     $ py.test --hosts=all # tests all inventory hosts
     $ py.test --hosts='ansible://host1,ansible://host2'
     $ py.test --hosts='ansible://web*'
+    $ py.test --hosts='ansible://host?force_ansible=True'
 
 kubectl
 ~~~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/test/conftest.py 
new/testinfra-3.1.0/test/conftest.py
--- old/testinfra-3.0.6/test/conftest.py        2019-08-04 13:12:17.000000000 
+0200
+++ new/testinfra-3.1.0/test/conftest.py        2019-08-17 12:44:28.000000000 
+0200
@@ -71,6 +71,7 @@
     items = [
         name,
         "ansible_ssh_private_key_file={}".format(key),
+        'ansible_ssh_common_args="-o UserKnownHostsFile=/dev/null -o 
StrictHostKeyChecking=no -o LogLevel=FATAL"',  # noqa
         "myvar=foo",
         "ansible_host={}".format(host),
         "ansible_user={}".format(user),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/test/test_backends.py 
new/testinfra-3.1.0/test/test_backends.py
--- old/testinfra-3.0.6/test/test_backends.py   2019-08-04 13:12:17.000000000 
+0200
+++ new/testinfra-3.1.0/test/test_backends.py   2019-08-18 13:15:06.000000000 
+0200
@@ -23,16 +23,37 @@
 from testinfra.backend.base import HostSpec
 from testinfra.backend.winrm import _quote
 from testinfra.utils.ansible_runner import AnsibleRunner
-BACKENDS = ("ssh", "safe-ssh", "docker", "paramiko", "ansible")
-HOSTS = [backend + "://debian_stretch" for backend in BACKENDS]
-USER_HOSTS = [backend + "://user@debian_stretch" for backend in BACKENDS]
+HOSTS = [
+    "ssh://debian_stretch",
+    "safe-ssh://debian_stretch",
+    "docker://debian_stretch",
+    "paramiko://debian_stretch",
+    "ansible://debian_stretch",
+    "ansible://debian_stretch?force_ansible=True",
+]
+USER_HOSTS = [
+    "ssh://user@debian_stretch",
+    "safe-ssh://user@debian_stretch",
+    "docker://user@debian_stretch",
+    "paramiko://user@debian_stretch",
+    "ansible://user@debian_stretch",
+    "ansible://user@debian_stretch?force_ansible=True",
+]
 SUDO_HOSTS = [
-    backend + "://user@debian_stretch?sudo=True"
-    for backend in BACKENDS
+    "ssh://user@debian_stretch?sudo=True",
+    "safe-ssh://user@debian_stretch?sudo=True",
+    "docker://user@debian_stretch?sudo=True",
+    "paramiko://user@debian_stretch?sudo=True",
+    "ansible://user@debian_stretch?sudo=True",
+    "ansible://user@debian_stretch?force_ansible=True&sudo=True",
 ]
 SUDO_USER_HOSTS = [
-    backend + "://debian_stretch?sudo=True&sudo_user=user"
-    for backend in BACKENDS
+    "ssh://debian_stretch?sudo=True&sudo_user=user",
+    "safe-ssh://debian_stretch?sudo=True&sudo_user=user",
+    "docker://debian_stretch?sudo=True&sudo_user=user",
+    "paramiko://debian_stretch?sudo=True&sudo_user=user",
+    "ansible://debian_stretch?sudo=True&sudo_user=user",
+    "ansible://debian_stretch?force_ansible=True&sudo=True&sudo_user=user",
 ]
 
 
@@ -42,6 +63,19 @@
     assert host.check_output("true") == ""
     # test that quotting is correct
     assert host.run("echo a b | grep -q %s", "a c").rc == 1
+    out = host.run("echo out && echo err >&2 && exit 42")
+    assert out.rc == 42
+    if (
+        host.backend.get_connection_type() == "ansible"
+        and host.backend.force_ansible
+    ):
+        assert out.stdout_bytes == b'out'
+        assert out.stderr_bytes == b'err'
+    else:
+        assert out.stdout_bytes == b'out\n'
+        assert out.stderr_bytes == b'err\n'
+    out = host.run("commandthatdoesnotexists")
+    assert out.rc == 127
 
 
 @pytest.mark.testinfra_hosts(*HOSTS)
@@ -54,6 +88,15 @@
             b"ls: impossible d'acc\xe9der \xe0 '/\xef\xbf\xbd': "
             b"Aucun fichier ou dossier de ce type\n"
         )
+    elif (
+        host.backend.get_connection_type() == "ansible"
+        and host.backend.force_ansible
+    ):
+        # XXX: this encoding issue comes directly from ansible
+        # not sure how to handle this...
+        assert cmd.stderr == (
+            "ls: impossible d'accéder à '/é': "
+            "Aucun fichier ou dossier de ce type")
     else:
         assert cmd.stderr_bytes == (
             b"ls: impossible d'acc\xe9der \xe0 '/\xe9': "
@@ -65,6 +108,19 @@
         )
 
 
[email protected]_hosts(
+    "ansible://debian_stretch?force_ansible=True")
+def test_ansible_any_error_fatal(host):
+    os.environ['ANSIBLE_ANY_ERRORS_FATAL'] = 'True'
+    try:
+        out = host.run("echo out && echo err >&2 && exit 42")
+        assert out.rc == 42
+        assert out.stdout == 'out'
+        assert out.stderr == 'err'
+    finally:
+        del os.environ['ANSIBLE_ANY_ERRORS_FATAL']
+
+
 @pytest.mark.testinfra_hosts(*(USER_HOSTS + SUDO_USER_HOSTS))
 def test_user_connection(host):
     assert host.user().name == "user"
@@ -150,11 +206,15 @@
         'sudo_user': 'u',
     }),
     ('host', {}, b'host', {
-        'NAME': 'paramiko',
+        'NAME': 'ssh',
+        'host.name': 'host',
+    }),
+    ('host', {}, b'host ansible_connection=smart', {
+        'NAME': 'ssh',
         'host.name': 'host',
     }),
     ('host', {}, b'host ansible_host=127.0.1.1 ansible_user=u 
ansible_ssh_private_key_file=key ansible_port=2222 ansible_become=yes 
ansible_become_user=u', {  # noqa
-        'NAME': 'paramiko',
+        'NAME': 'ssh',
         'sudo': True,
         'sudo_user': 'u',
         'host.name': '127.0.1.1',
@@ -162,13 +222,28 @@
         'ssh_identity_file': 'key',
     }),
     ('host', {}, b'host ansible_host=127.0.1.1 ansible_user=u 
ansible_private_key_file=key ansible_port=2222 ansible_become=yes 
ansible_become_user=u', {  # noqa
-        'NAME': 'paramiko',
+        'NAME': 'ssh',
         'sudo': True,
         'sudo_user': 'u',
         'host.name': '127.0.1.1',
         'host.port': '2222',
         'ssh_identity_file': 'key',
     }),
+    ('host', {}, b'host ansible_ssh_common_args="-o LogLevel=FATAL"', {
+        'NAME': 'ssh',
+        'host.name': 'host',
+        'ssh_extra_args': '-o LogLevel=FATAL',
+    }),
+    ('host', {}, b'host ansible_ssh_extra_args="-o LogLevel=FATAL"', {
+        'NAME': 'ssh',
+        'host.name': 'host',
+        'ssh_extra_args': '-o LogLevel=FATAL',
+    }),
+    ('host', {}, b'host ansible_ssh_common_args="-o StrictHostKeyChecking=no" 
ansible_ssh_extra_args="-o LogLevel=FATAL"', {  # noqa
+        'NAME': 'ssh',
+        'host.name': 'host',
+        'ssh_extra_args': '-o StrictHostKeyChecking=no -o LogLevel=FATAL',
+    }),
     ('host', {}, b'host ansible_connection=docker', {
         'NAME': 'docker',
         'name': 'host',
@@ -183,7 +258,7 @@
     }),
     ('host', {'ssh_config': '/ssh_config', 'ssh_identity_file': '/id_ed25519'},
         b'host', {
-        'NAME': 'paramiko',
+        'NAME': 'ssh',
         'host.name': 'host',
         'ssh_config': '/ssh_config',
         'ssh_identity_file': '/id_ed25519',
@@ -214,15 +289,6 @@
         assert AnsibleRunner(f.name).get_hosts('localhost') == ['localhost']
 
 
-def test_ansible_unhandled_connection():
-    with tempfile.NamedTemporaryFile() as f:
-        f.write(b'host ansible_connection=winrm\n')
-        f.flush()
-        with pytest.raises(RuntimeError) as excinfo:
-            AnsibleRunner(f.name).get_host('host')
-        assert str(excinfo.value) == 'unhandled ansible_connection winrm'
-
-
 def test_ansible_config():
     # test testinfra use ANSIBLE_CONFIG
     tmp = tempfile.NamedTemporaryFile
@@ -311,3 +377,32 @@
 ])
 def test_winrm_quote(arg_string, expected):
     assert _quote(arg_string) == expected
+
+
[email protected]('hostspec,expected', [
+    ('ssh://h',
+        'ssh -o ConnectTimeout=10 -o ControlMaster=auto '
+        '-o ControlPersist=60s h true'),
+    ('ssh://h?timeout=1',
+        'ssh -o ConnectTimeout=1 -o ControlMaster=auto '
+        '-o ControlPersist=60s h true'),
+    ('ssh://u@h:2222',
+        'ssh -o User=u -o Port=2222 -o ConnectTimeout=10 '
+        '-o ControlMaster=auto -o ControlPersist=60s h true'),
+    ('ssh://h:2222?ssh_config=/f',
+        'ssh -F /f -o Port=2222 -o ConnectTimeout=10 '
+        '-o ControlMaster=auto -o ControlPersist=60s h true'),
+    ('ssh://u@h?ssh_identity_file=/id',
+        'ssh -o User=u -i /id -o ConnectTimeout=10 '
+        '-o ControlMaster=auto -o ControlPersist=60s h true'),
+    ('ssh://h?controlpersist=1',
+        'ssh -o ConnectTimeout=10 '
+        '-o ControlMaster=auto -o ControlPersist=1s h true'),
+    ('ssh://h?controlpersist=0',
+        'ssh -o ConnectTimeout=10 h true')
+])
+def test_ssh_hostspec(hostspec, expected):
+    backend = testinfra.get_host(hostspec).backend
+    cmd, cmd_args = backend._build_ssh_command('true')
+    command = backend.quote(' '.join(cmd), *cmd_args)
+    assert command == expected
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/test/test_modules.py 
new/testinfra-3.1.0/test/test_modules.py
--- old/testinfra-3.0.6/test/test_modules.py    2019-07-07 01:41:09.000000000 
+0200
+++ new/testinfra-3.1.0/test/test_modules.py    2019-08-17 12:44:33.000000000 
+0200
@@ -117,9 +117,14 @@
     ssh = host.service(name)
     if docker_image == "ubuntu_xenial":
         assert not ssh.is_running
-    # FIXME: is_running test is broken for archlinux for unknown reason
-    elif docker_image != "archlinux":
-        assert ssh.is_running
+    else:
+        # wait at max 10 seconds for ssh is running
+        for _ in range(10):
+            if ssh.is_running:
+                break
+            time.sleep(1)
+        else:
+            raise AssertionError('ssh is not running')
 
     if docker_image == "ubuntu_xenial":
         assert not ssh.is_enabled
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/testinfra/backend/__init__.py 
new/testinfra-3.1.0/testinfra/backend/__init__.py
--- old/testinfra-3.0.6/testinfra/backend/__init__.py   2019-08-04 
13:12:17.000000000 +0200
+++ new/testinfra-3.1.0/testinfra/backend/__init__.py   2019-08-17 
12:44:33.000000000 +0200
@@ -48,11 +48,12 @@
         kw["connection"] = url.scheme
         host = url.netloc
         query = urllib.parse.parse_qs(url.query)
-        for key in ('sudo', 'ssl', 'no_ssl', 'no_verify_ssl'):
+        for key in ('sudo', 'ssl', 'no_ssl', 'no_verify_ssl', 'force_ansible'):
             if query.get(key, ['false'])[0].lower() == 'true':
                 kw[key] = True
         for key in ("sudo_user", 'namespace', 'container', 'read_timeout_sec',
-                    'operation_timeout_sec', 'timeout', 'kubeconfig'):
+                    'operation_timeout_sec', 'timeout', 'controlpersist',
+                    'kubeconfig'):
             if key in query:
                 kw[key] = query.get(key)[0]
         for key in (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/testinfra/backend/ansible.py 
new/testinfra-3.1.0/testinfra/backend/ansible.py
--- old/testinfra-3.0.6/testinfra/backend/ansible.py    2019-07-07 
01:41:09.000000000 +0200
+++ new/testinfra-3.1.0/testinfra/backend/ansible.py    2019-08-17 
12:44:33.000000000 +0200
@@ -28,11 +28,13 @@
     HAS_RUN_ANSIBLE = True
 
     def __init__(self, host, ansible_inventory=None, ssh_config=None,
-                 ssh_identity_file=None, *args, **kwargs):
+                 ssh_identity_file=None, force_ansible=False,
+                 *args, **kwargs):
         self.host = host
         self.ansible_inventory = ansible_inventory
         self.ssh_config = ssh_config
         self.ssh_identity_file = ssh_identity_file
+        self.force_ansible = force_ansible
         super(AnsibleBackend, self).__init__(host, *args, **kwargs)
 
     @property
@@ -41,9 +43,16 @@
 
     def run(self, command, *args, **kwargs):
         command = self.get_command(command, *args)
-        return self.ansible_runner.run(
-            self.host, command, ssh_config=self.ssh_config,
-            ssh_identity_file=self.ssh_identity_file)
+        if not self.force_ansible:
+            host = self.ansible_runner.get_host(
+                self.host, ssh_config=self.ssh_config,
+                ssh_identity_file=self.ssh_identity_file)
+            if host is not None:
+                return host.run(command)
+        out = self.run_ansible('shell', module_args=command, check=False)
+        return self.result(
+            out['rc'], command, stdout_bytes=None,
+            stderr_bytes=None, stdout=out['stdout'], stderr=out['stderr'])
 
     def run_ansible(self, module_name, module_args=None, **kwargs):
         result = self.ansible_runner.run_module(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/testinfra/backend/ssh.py 
new/testinfra-3.1.0/testinfra/backend/ssh.py
--- old/testinfra-3.0.6/testinfra/backend/ssh.py        2019-08-04 
13:12:17.000000000 +0200
+++ new/testinfra-3.1.0/testinfra/backend/ssh.py        2019-08-18 
13:15:06.000000000 +0200
@@ -23,19 +23,24 @@
     NAME = "ssh"
 
     def __init__(self, hostspec, ssh_config=None, ssh_identity_file=None,
-                 timeout=10, *args, **kwargs):
+                 timeout=10, controlpersist=60, ssh_extra_args=None,
+                 *args, **kwargs):
         self.host = self.parse_hostspec(hostspec)
         self.ssh_config = ssh_config
         self.ssh_identity_file = ssh_identity_file
         self.timeout = int(timeout)
+        self.controlpersist = int(controlpersist)
+        self.ssh_extra_args = ssh_extra_args
         super(SshBackend, self).__init__(self.host.name, *args, **kwargs)
 
     def run(self, command, *args, **kwargs):
         return self.run_ssh(self.get_command(command, *args))
 
-    def run_ssh(self, command):
+    def _build_ssh_command(self, command):
         cmd = ["ssh"]
         cmd_args = []
+        if self.ssh_extra_args:
+            cmd += [self.ssh_extra_args]
         if self.ssh_config:
             cmd.append("-F %s")
             cmd_args.append(self.ssh_config)
@@ -49,8 +54,15 @@
             cmd.append("-i %s")
             cmd_args.append(self.ssh_identity_file)
         cmd.append("-o ConnectTimeout={}".format(self.timeout))
+        if self.controlpersist:
+            cmd.append("-o ControlMaster=auto -o ControlPersist=%ds" % (
+                self.controlpersist))
         cmd.append("%s %s")
         cmd_args.extend([self.host.name, command])
+        return cmd, cmd_args
+
+    def run_ssh(self, command):
+        cmd, cmd_args = self._build_ssh_command(command)
         out = self.run_local(
             " ".join(cmd), *cmd_args)
         out.command = self.encode(command)
@@ -79,6 +91,7 @@
 
     def run(self, command, *args, **kwargs):
         orig_command = self.get_command(command, *args)
+        orig_command = self.get_command('sh -c %s', orig_command)
 
         out = self.run_ssh((
             '''of=$(mktemp)&&ef=$(mktemp)&&%s >$of 2>$ef; r=$?;'''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/testinfra/utils/ansible_runner.py 
new/testinfra-3.1.0/testinfra/utils/ansible_runner.py
--- old/testinfra-3.0.6/testinfra/utils/ansible_runner.py       2019-08-04 
13:25:24.000000000 +0200
+++ new/testinfra-3.1.0/testinfra/utils/ansible_runner.py       2019-08-18 
13:15:06.000000000 +0200
@@ -66,13 +66,16 @@
         return testinfra.get_host('local://')
     hostvars = inventory['_meta'].get('hostvars', {}).get(host, {})
     connection = hostvars.get('ansible_connection', 'ssh')
-    if connection not in ('ssh', 'local', 'docker', 'lxc', 'lxd'):
-        raise NotImplementedError(
-            'unhandled ansible_connection {}'.format(connection))
-    if connection == 'lxd':
-        connection = 'lxc'
-    if connection == 'ssh':
-        connection = 'paramiko'
+    if connection not in (
+        'smart', 'ssh', 'paramiko_ssh', 'local', 'docker', 'lxc', 'lxd',
+    ):
+        # unhandled connection type, must use force_ansible=True
+        return None
+    connection = {
+        'lxd': 'lxc',
+        'paramiko_ssh': 'paramiko',
+        'smart': 'ssh',
+    }.get(connection, connection)
     testinfra_host = hostvars.get('ansible_host', host)
     user = hostvars.get('ansible_user')
     port = hostvars.get('ansible_port')
@@ -92,6 +95,10 @@
     elif 'ansible_private_key_file' in hostvars:
         kwargs['ssh_identity_file'] = hostvars[
             'ansible_private_key_file']
+    kwargs['ssh_extra_args'] = '{} {}'.format(
+        hostvars.get('ansible_ssh_common_args', ''),
+        hostvars.get('ansible_ssh_extra_args', '')
+    ).strip()
 
     spec = '{}://'.format(connection)
     if user:
@@ -177,9 +184,6 @@
                 self.ansible_config, self.inventory, host, **kwargs)
             return self._host_cache[host]
 
-    def run(self, host, command, **kwargs):
-        return self.get_host(host, **kwargs).run(command)
-
     def run_module(self, host, module_name, module_args, become=False,
                    check=True, **kwargs):
         cmd, args = 'ansible --tree %s', [None]
@@ -199,7 +203,7 @@
         args += [host]
         with TemporaryDirectory() as d:
             args[0] = d
-            out = local.run_expect([0, 2], cmd, *args)
+            out = local.run_expect([0, 2, 8], cmd, *args)
             files = os.listdir(d)
             if not files and 'skipped' in out.stdout.lower():
                 return {'failed': True, 'skipped': True,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/testinfra-3.0.6/testinfra.egg-info/PKG-INFO 
new/testinfra-3.1.0/testinfra.egg-info/PKG-INFO
--- old/testinfra-3.0.6/testinfra.egg-info/PKG-INFO     2019-08-04 
14:06:21.000000000 +0200
+++ new/testinfra-3.1.0/testinfra.egg-info/PKG-INFO     2019-08-18 
19:03:00.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: testinfra
-Version: 3.0.6
+Version: 3.1.0
 Summary: Test infrastructures
 Home-page: https://github.com/philpep/testinfra
 Author: Philippe Pepiot


Reply via email to