summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Rabotyagov <noonedeadpunk@ya.ru>2023-05-02 09:52:11 +0200
committerGitHub <noreply@github.com>2023-05-02 09:52:11 +0200
commit7f48fa01295e85f94437041688fb898e870c5154 (patch)
tree86ab5a4f3789cf4f3be2eec8cf3a7a8268dce423
parent251360314d0b385322d36001f3deb9820c3febc8 (diff)
downloadansible-7f48fa01295e85f94437041688fb898e870c5154.tar.gz
Better parse virtualenv_command option for pip (#80624)
Atthe moment if a users wants to protect virtualenv_command by using quotes around 'venv', module will fail out as literal parsing is used at the moment. In order to imrpove things, argparse is leveraged to parse out passed value to the virtualenv_command Closes-Bug: #76372 Signed-off-by: Dmitriy Rabotyagov <noonedeadpunk@gmail.com>
-rw-r--r--changelogs/fragments/76372-fix-pip-virtualenv-command-parsing.yml6
-rw-r--r--lib/ansible/modules/pip.py15
-rw-r--r--test/integration/targets/pip/tasks/pip.yml22
3 files changed, 42 insertions, 1 deletions
diff --git a/changelogs/fragments/76372-fix-pip-virtualenv-command-parsing.yml b/changelogs/fragments/76372-fix-pip-virtualenv-command-parsing.yml
new file mode 100644
index 0000000000..96cd8b646a
--- /dev/null
+++ b/changelogs/fragments/76372-fix-pip-virtualenv-command-parsing.yml
@@ -0,0 +1,6 @@
+---
+bugfixes:
+ - >-
+ Fixed `pip` module failure in case of usage quotes for
+ `virtualenv_command` option for the venv command.
+ (https://github.com/ansible/ansible/issues/76372)
diff --git a/lib/ansible/modules/pip.py b/lib/ansible/modules/pip.py
index 15c8c4420a..a77d2fdabd 100644
--- a/lib/ansible/modules/pip.py
+++ b/lib/ansible/modules/pip.py
@@ -264,6 +264,7 @@ virtualenv:
sample: "/tmp/virtualenv"
'''
+import argparse
import os
import re
import sys
@@ -306,6 +307,18 @@ def _is_vcs_url(name):
return re.match(_VCS_RE, name)
+def _is_venv_command(command):
+ venv_parser = argparse.ArgumentParser()
+ venv_parser.add_argument('-m', type=str)
+ argv = shlex.split(command)
+ if argv[0] == 'pyvenv':
+ return True
+ args, dummy = venv_parser.parse_known_args(argv[1:])
+ if args.m == 'venv':
+ return True
+ return False
+
+
def _is_package_name(name):
"""Test whether the name is a package name or a version specifier."""
return not name.lstrip().startswith(tuple(op_dict.keys()))
@@ -540,7 +553,7 @@ def setup_virtualenv(module, env, chdir, out, err):
virtualenv_python = module.params['virtualenv_python']
# -p is a virtualenv option, not compatible with pyenv or venv
# 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 not _is_venv_command(module.params['virtualenv_command']):
if virtualenv_python:
cmd.append('-p%s' % virtualenv_python)
elif PY3:
diff --git a/test/integration/targets/pip/tasks/pip.yml b/test/integration/targets/pip/tasks/pip.yml
index 39480614ab..9f1034d29a 100644
--- a/test/integration/targets/pip/tasks/pip.yml
+++ b/test/integration/targets/pip/tasks/pip.yml
@@ -568,6 +568,28 @@
that:
- "version13 is success"
+- name: Test virtualenv command with venv formatting
+ when: ansible_python.version.major > 2
+ block:
+ - name: Clean up the virtualenv
+ file:
+ state: absent
+ name: "{{ remote_tmp_dir }}/pipenv"
+
+ # ref: https://github.com/ansible/ansible/issues/76372
+ - name: install using different venv formatting
+ pip:
+ name: "{{ pip_test_package }}"
+ virtualenv: "{{ remote_tmp_dir }}/pipenv"
+ virtualenv_command: "{{ ansible_python_interpreter ~ ' -mvenv' }}"
+ state: present
+ register: version14
+
+ - name: ensure install using virtualenv_command with venv formatting
+ assert:
+ that:
+ - "version14 is changed"
+
### test virtualenv_command end ###
# https://github.com/ansible/ansible/issues/68592