summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Pretorius (odyssey4me) <jesse@odyssey4.me>2020-02-13 21:32:11 +0000
committerMatt Clay <matt@mystile.com>2020-05-05 21:17:12 -0700
commit82378406ea261a1b0801bcca6abf3fbb11656d0c (patch)
treee3632a02e593a2d30c41224a5f2851cdc2388f44
parent081ce0e4e132a855550772379eedd7ae1be5335a (diff)
downloadansible-82378406ea261a1b0801bcca6abf3fbb11656d0c.tar.gz
[pip] Enable virtualenv_command to have arguments
Currently if virtualenv_command has arguments, then the search for the binary in the path does not work so the user has to specify the full path to it. To allow arguments to be used without having to specify the path to the binary, we split the module argument into the command and anything after the first space. This makes using this module argument more flexible and user friendly. Fixes: #52275 (cherry picked from commit da390b297e64878512bd96ffde4283bb0694c9b5)
-rw-r--r--changelogs/fragments/67407-pip-virtualenv_command-args.yml4
-rw-r--r--lib/ansible/modules/packaging/language/pip.py27
-rw-r--r--test/integration/targets/pip/tasks/pip.yml26
3 files changed, 47 insertions, 10 deletions
diff --git a/changelogs/fragments/67407-pip-virtualenv_command-args.yml b/changelogs/fragments/67407-pip-virtualenv_command-args.yml
new file mode 100644
index 0000000000..b072a17f48
--- /dev/null
+++ b/changelogs/fragments/67407-pip-virtualenv_command-args.yml
@@ -0,0 +1,4 @@
+bugfixes:
+ - pip - The virtualenv_command option can now include arguments without
+ requiring the full path to the binary.
+ (https://github.com/ansible/ansible/issues/52275)
diff --git a/lib/ansible/modules/packaging/language/pip.py b/lib/ansible/modules/packaging/language/pip.py
index 19744623d0..9ce74e6b09 100644
--- a/lib/ansible/modules/packaging/language/pip.py
+++ b/lib/ansible/modules/packaging/language/pip.py
@@ -471,23 +471,30 @@ def setup_virtualenv(module, env, chdir, out, err):
if module.check_mode:
module.exit_json(changed=True)
- cmd = module.params['virtualenv_command']
- if os.path.basename(cmd) == cmd:
- cmd = module.get_bin_path(cmd, True)
+ cmd = shlex.split(module.params['virtualenv_command'])
+ # Find the binary for the command in the PATH
+ # and switch the command for the explicit path.
+ if os.path.basename(cmd[0]) == cmd[0]:
+ cmd[0] = module.get_bin_path(cmd[0], True)
+
+ # Add the system-site-packages option if that
+ # is enabled, otherwise explicitly set the option
+ # to not use system-site-packages if that is an
+ # option provided by the command's help function.
if module.params['virtualenv_site_packages']:
- cmd += ' --system-site-packages'
+ cmd.append('--system-site-packages')
else:
- cmd_opts = _get_cmd_options(module, cmd)
+ cmd_opts = _get_cmd_options(module, cmd[0])
if '--no-site-packages' in cmd_opts:
- cmd += ' --no-site-packages'
+ cmd.append('--no-site-packages')
virtualenv_python = module.params['virtualenv_python']
# -p is a virtualenv option, not compatible with pyenv or venv
- # this if validates if the command being used is not any of them
+ # this conditional validates if the command being used is not any of them
if not any(ex in module.params['virtualenv_command'] for ex in ('pyvenv', '-m venv')):
if virtualenv_python:
- cmd += ' -p%s' % virtualenv_python
+ cmd.append('-p%s' % virtualenv_python)
elif PY3:
# Ubuntu currently has a patch making virtualenv always
# try to use python2. Since Ubuntu16 works without
@@ -495,7 +502,7 @@ def setup_virtualenv(module, env, chdir, out, err):
# the upstream behaviour of using the python which invoked
# virtualenv to determine which python is used inside of
# the virtualenv (when none are specified).
- cmd += ' -p%s' % sys.executable
+ cmd.append('-p%s' % sys.executable)
# if venv or pyvenv are used and virtualenv_python is defined, then
# virtualenv_python is ignored, this has to be acknowledged
@@ -505,7 +512,7 @@ def setup_virtualenv(module, env, chdir, out, err):
' using the venv module or pyvenv as virtualenv_command'
)
- cmd = "%s %s" % (cmd, env)
+ cmd.append(env)
rc, out_venv, err_venv = module.run_command(cmd, cwd=chdir)
out += out_venv
err += err_venv
diff --git a/test/integration/targets/pip/tasks/pip.yml b/test/integration/targets/pip/tasks/pip.yml
index 5018cd11e4..09640176f4 100644
--- a/test/integration/targets/pip/tasks/pip.yml
+++ b/test/integration/targets/pip/tasks/pip.yml
@@ -525,6 +525,32 @@
that: "'distribute' in remove_distribute.cmd"
when: ansible_python.version.major == 2
+### test virtualenv_command begin ###
+
+- name: Test virtualenv command with arguments
+ when: "ansible_system == 'Linux'"
+ block:
+ - name: make sure the virtualenv does not exist
+ file:
+ state: absent
+ name: "{{ output_dir }}/pipenv"
+
+ # ref: https://github.com/ansible/ansible/issues/52275
+ - name: install using virtualenv_command with arguments
+ pip:
+ name: "{{ pip_test_package }}"
+ virtualenv: "{{ output_dir }}/pipenv"
+ virtualenv_command: "virtualenv --verbose"
+ state: present
+ register: version13
+
+ - name: ensure install using virtualenv_command with arguments was successful
+ assert:
+ that:
+ - "version13 is success"
+
+### test virtualenv_command end ###
+
# https://github.com/ansible/ansible/issues/68592
# Handle pre-release version numbers in check_mode for already-installed
# packages.