From c7cb944315a67fe575d5e83bdb897cdacaea8a44 Mon Sep 17 00:00:00 2001 From: Matt Clay Date: Thu, 28 Jan 2021 14:53:05 -0800 Subject: [PATCH] Always use python exec wrapper in ansible-test. --- .../ansible-test-python-exec-wrapper.yml | 3 +++ .../lib/ansible_test/_internal/util_common.py | 19 +++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 changelogs/fragments/ansible-test-python-exec-wrapper.yml diff --git a/changelogs/fragments/ansible-test-python-exec-wrapper.yml b/changelogs/fragments/ansible-test-python-exec-wrapper.yml new file mode 100644 index 00000000000..fc35dd7f7e3 --- /dev/null +++ b/changelogs/fragments/ansible-test-python-exec-wrapper.yml @@ -0,0 +1,3 @@ +bugfixes: + - ansible-test - Symbolic links are no longer used to inject ``python`` into the environment, since they do not work reliably in all cases. + Instead, the existing Python based exec wrapper is always used. diff --git a/test/lib/ansible_test/_internal/util_common.py b/test/lib/ansible_test/_internal/util_common.py index de3d284d19a..ed7fa08ab2c 100644 --- a/test/lib/ansible_test/_internal/util_common.py +++ b/test/lib/ansible_test/_internal/util_common.py @@ -252,18 +252,17 @@ def get_python_path(args, interpreter): python_path = tempfile.mkdtemp(prefix=prefix, suffix=suffix, dir=root_temp_dir) injected_interpreter = os.path.join(python_path, 'python') - # A symlink is faster than the execv wrapper, but isn't compatible with virtual environments. - # Attempt to detect when it is safe to use a symlink by checking the real path of the interpreter. - use_symlink = os.path.dirname(os.path.realpath(interpreter)) == os.path.dirname(interpreter) + # A symlink is faster than the execv wrapper, but isn't guaranteed to provide the correct result. + # There are several scenarios known not to work with symlinks: + # + # - A virtual environment where the target is a symlink to another directory. + # - A pyenv environment where the target is a shell script that changes behavior based on the program name. + # + # To avoid issues for these and other scenarios, only an exec wrapper is used. - if use_symlink: - display.info('Injecting "%s" as a symlink to the "%s" interpreter.' % (injected_interpreter, interpreter), verbosity=1) + display.info('Injecting "%s" as a execv wrapper for the "%s" interpreter.' % (injected_interpreter, interpreter), verbosity=1) - os.symlink(interpreter, injected_interpreter) - else: - display.info('Injecting "%s" as a execv wrapper for the "%s" interpreter.' % (injected_interpreter, interpreter), verbosity=1) - - create_interpreter_wrapper(interpreter, injected_interpreter) + create_interpreter_wrapper(interpreter, injected_interpreter) os.chmod(python_path, MODE_DIRECTORY)