diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 734254a3051..8754f2cbc32 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -9,6 +9,7 @@ import pty import time import json import subprocess +import sys import traceback from ansible import constants as C @@ -855,7 +856,11 @@ class TaskExecutor: Starts the persistent connection ''' master, slave = pty.openpty() - p = subprocess.Popen(["ansible-connection", to_text(os.getppid())], stdin=slave, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + python = sys.executable + # Assume ansible-connection is in the same dir as sys.argv[0] + ansible_connection = os.path.join(os.path.dirname(sys.argv[0]), 'ansible-connection') + p = subprocess.Popen([python, ansible_connection, to_text(os.getppid())], stdin=slave, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdin = os.fdopen(master, 'wb', 0) os.close(slave) @@ -874,9 +879,12 @@ class TaskExecutor: stdin.close() if p.returncode == 0: - result = json.loads(to_text(stdout)) + result = json.loads(to_text(stdout, errors='surrogate_then_replace')) else: - result = json.loads(to_text(stderr)) + try: + result = json.loads(to_text(stderr, errors='surrogate_then_replace')) + except json.decoder.JSONDecodeError: + result = {'error': to_text(stderr, errors='surrogate_then_replace')} if 'messages' in result: for msg in result.get('messages'): @@ -884,8 +892,9 @@ class TaskExecutor: if 'error' in result: if self._play_context.verbosity > 2: - msg = "The full traceback is:\n" + result['exception'] - display.display(msg, color=C.COLOR_ERROR) + if result.get('exception'): + msg = "The full traceback is:\n" + result['exception'] + display.display(msg, color=C.COLOR_ERROR) raise AnsibleError(result['error']) return result['socket_path'] diff --git a/lib/ansible/plugins/connection/persistent.py b/lib/ansible/plugins/connection/persistent.py index 9a5f8827b56..16faf1a3e6c 100644 --- a/lib/ansible/plugins/connection/persistent.py +++ b/lib/ansible/plugins/connection/persistent.py @@ -17,6 +17,7 @@ import os import pty import json import subprocess +import sys from ansible import constants as C from ansible.plugins.connection import ConnectionBase @@ -75,7 +76,11 @@ class Connection(ConnectionBase): Starts the persistent connection ''' master, slave = pty.openpty() - p = subprocess.Popen(["ansible-connection", to_text(os.getppid())], stdin=slave, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + python = sys.executable + # Assume ansible-connection is in the same dir as sys.argv[0] + ansible_connection = os.path.join(os.path.dirname(sys.argv[0]), 'ansible-connection') + p = subprocess.Popen([python, ansible_connection, to_text(os.getppid())], stdin=slave, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdin = os.fdopen(master, 'wb', 0) os.close(slave) @@ -96,7 +101,10 @@ class Connection(ConnectionBase): if p.returncode == 0: result = json.loads(to_text(stdout, errors='surrogate_then_replace')) else: - result = json.loads(to_text(stderr, errors='surrogate_then_replace')) + try: + result = json.loads(to_text(stderr, errors='surrogate_then_replace')) + except json.decoder.JSONDecodeError: + result = {'error': to_text(stderr, errors='surrogate_then_replace')} if 'messages' in result: for msg in result.get('messages'): @@ -104,8 +112,9 @@ class Connection(ConnectionBase): if 'error' in result: if self._play_context.verbosity > 2: - msg = "The full traceback is:\n" + result['exception'] - display.display(msg, color=C.COLOR_ERROR) + if result.get('exception'): + msg = "The full traceback is:\n" + result['exception'] + display.display(msg, color=C.COLOR_ERROR) raise AnsibleError(result['error']) return result['socket_path']