diff --git a/lib/ansible/config/base.yml b/lib/ansible/config/base.yml index 53f104be02..0f35fea10b 100644 --- a/lib/ansible/config/base.yml +++ b/lib/ansible/config/base.yml @@ -13,6 +13,18 @@ ALLOW_WORLD_READABLE_TMPFILES: type: boolean yaml: {key: defaults.allow_world_readable_tmpfiles} version_added: "2.1" +ANSIBLE_CONNECTION_PATH: + name: Path of ansible-connection script + default: null + description: + - Specify where to look for the ansible-connection script. This location will be checked before searching $PATH. + - If null, ansible will start with the same directory as the ansible script. + type: path + env: [{name: ANSIBLE_CONNECTION_PATH}] + ini: + - {key: ansible_connection_path, section: persistent_connection} + yaml: {key: persistent_connection.ansible_connection_path} + version_added: "2.8" ANSIBLE_COW_SELECTION: name: Cowsay filter selection default: default diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 73c5ab076d..d1f67af8a2 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -936,22 +936,20 @@ class TaskExecutor: ''' Starts the persistent connection ''' - master, slave = pty.openpty() + candidate_paths = [C.ANSIBLE_CONNECTION_PATH or os.path.dirname(sys.argv[0])] + candidate_paths.extend(os.environ['PATH'].split(os.pathsep)) + for dirname in candidate_paths: + ansible_connection = os.path.join(dirname, 'ansible-connection') + if os.path.isfile(ansible_connection): + break + else: + raise AnsibleError("Unable to find location of 'ansible-connection'. " + "Please set or check the value of ANSIBLE_CONNECTION_PATH") python = sys.executable - - def find_file_in_path(filename): - # Check $PATH first, followed by same directory as sys.argv[0] - paths = os.environ['PATH'].split(os.pathsep) + [os.path.dirname(sys.argv[0])] - for dirname in paths: - fullpath = os.path.join(dirname, filename) - if os.path.isfile(fullpath): - return fullpath - - raise AnsibleError("Unable to find location of '%s'" % filename) - + master, slave = pty.openpty() p = subprocess.Popen( - [python, find_file_in_path('ansible-connection'), to_text(os.getppid())], + [python, ansible_connection, to_text(os.getppid())], stdin=slave, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) os.close(slave) diff --git a/lib/ansible/plugins/connection/persistent.py b/lib/ansible/plugins/connection/persistent.py index 800a42843c..f77a23bf1c 100644 --- a/lib/ansible/plugins/connection/persistent.py +++ b/lib/ansible/plugins/connection/persistent.py @@ -91,22 +91,20 @@ class Connection(ConnectionBase): ''' Starts the persistent connection ''' - master, slave = pty.openpty() + candidate_paths = [C.ANSIBLE_CONNECTION_PATH or os.path.dirname(sys.argv[0])] + candidate_paths.extend(os.environ['PATH'].split(os.pathsep)) + for dirname in candidate_paths: + ansible_connection = os.path.join(dirname, 'ansible-connection') + if os.path.isfile(ansible_connection): + break + else: + raise AnsibleError("Unable to find location of 'ansible-connection'. " + "Please set or check the value of ANSIBLE_CONNECTION_PATH") python = sys.executable - - def find_file_in_path(filename): - # Check $PATH first, followed by same directory as sys.argv[0] - paths = os.environ['PATH'].split(os.pathsep) + [os.path.dirname(sys.argv[0])] - for dirname in paths: - fullpath = os.path.join(dirname, filename) - if os.path.isfile(fullpath): - return fullpath - - raise AnsibleError("Unable to find location of '%s'" % filename) - + master, slave = pty.openpty() p = subprocess.Popen( - [python, find_file_in_path('ansible-connection'), to_text(os.getppid())], + [python, ansible_connection, to_text(os.getppid())], stdin=slave, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) os.close(slave)