summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToshio Kuratomi <a.badger@gmail.com>2016-11-01 06:46:22 -0700
committerToshio Kuratomi <a.badger@gmail.com>2016-11-01 07:37:54 -0700
commit8f0ab373d59fd59fbb2942e870ebc6502dce0f89 (patch)
tree2c5299ed592300f92d3692a23243f660b3933299
parentfe9c56a003ba295fb0b872e6676577ddbce8cd83 (diff)
downloadansible-modules-core-8f0ab373d59fd59fbb2942e870ebc6502dce0f89.tar.gz
Need to locate a pip inside a venv when venv is specified
Alternative to #5359 Fixes #5347 (cherry picked from commit d2106f1c929908aaeaeb53a77f71a1b9b0d59049)
-rwxr-xr-xpackaging/language/pip.py58
1 files changed, 36 insertions, 22 deletions
diff --git a/packaging/language/pip.py b/packaging/language/pip.py
index 95cd7caf..7c8aa8cb 100755
--- a/packaging/language/pip.py
+++ b/packaging/language/pip.py
@@ -190,7 +190,7 @@ import re
import os
import sys
-from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.basic import AnsibleModule, is_executable
from ansible.module_utils._text import to_native
from ansible.module_utils.six import PY3
@@ -263,17 +263,14 @@ def _is_present(name, version, installed_pkgs, pkg_command):
def _get_pip(module, env=None, executable=None):
- # On Debian and Ubuntu, pip is pip.
- # On Fedora18 and up, pip is python-pip.
- # On Fedora17 and below, CentOS and RedHat 6 and 5, pip is pip-python.
- # On Fedora, CentOS, and RedHat, the exception is in the virtualenv.
- # There, pip is just pip.
- # On python 3.4, pip should be default, cf PEP 453
- # By default, it will try to use pip required for the current python
+ # Older pip only installed under the "/usr/bin/pip" name. Many Linux
+ # distros install it there.
+ # By default, we try to use pip required for the current python
# interpreter, so people can use pip to install modules dependencies
- candidate_pip_basenames = ['pip2', 'pip', 'python-pip', 'pip-python']
+ candidate_pip_basenames = ('pip2', 'pip')
if PY3:
- candidate_pip_basenames = ['pip3']
+ # pip under python3 installs the "/usr/bin/pip3" name
+ candidate_pip_basenames = ('pip3',)
pip = None
if executable is not None:
@@ -282,22 +279,39 @@ def _get_pip(module, env=None, executable=None):
pip = executable
else:
# If you define your own executable that executable should be the only candidate.
- candidate_pip_basenames = [executable]
+ # As noted in the docs, executable doesn't work with virtualenvs.
+ candidate_pip_basenames = (executable,)
+
if pip is None:
if env is None:
opt_dirs = []
+ for basename in candidate_pip_basenames:
+ pip = module.get_bin_path(basename, False, opt_dirs)
+ if pip is not None:
+ break
+ else:
+ # For-else: Means that we did not break out of the loop
+ # (therefore, that pip was not found)
+ module.fail_json(msg='Unable to find any of %s to use. pip'
+ ' needs to be installed.' % ', '.join(candidate_pip_basenames))
else:
- # Try pip with the virtualenv directory first.
- opt_dirs = ['%s/bin' % env]
- for basename in candidate_pip_basenames:
- pip = module.get_bin_path(basename, False, opt_dirs)
- if pip is not None:
- break
- # pip should have been found by now. The final call to get_bin_path will
- # trigger fail_json.
- if pip is None:
- basename = candidate_pip_basenames[0]
- pip = module.get_bin_path(basename, True, opt_dirs)
+ # If we're using a virtualenv we must use the pip from the
+ # virtualenv
+ venv_dir = os.path.join(env, 'bin')
+ candidate_pip_basenames = (candidate_pip_basenames[0], 'pip')
+ for basename in candidate_pip_basenames:
+ candidate = os.path.join(venv_dir, basename)
+ if os.path.exists(candidate) and is_executable(candidate):
+ pip = candidate
+ break
+ else:
+ # For-else: Means that we did not break out of the loop
+ # (therefore, that pip was not found)
+ module.fail_json(msg='Unable to find pip in the virtualenv,'
+ ' %s, under any of these names: %s. Make sure pip is'
+ ' present in the virtualenv.' % (env,
+ ', '.join(candidate_pip_basenames)))
+
return pip