diff options
author | Dmitriy Rabotyagov <noonedeadpunk@ya.ru> | 2023-05-02 09:52:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-02 09:52:11 +0200 |
commit | 7f48fa01295e85f94437041688fb898e870c5154 (patch) | |
tree | 86ab5a4f3789cf4f3be2eec8cf3a7a8268dce423 | |
parent | 251360314d0b385322d36001f3deb9820c3febc8 (diff) | |
download | ansible-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.yml | 6 | ||||
-rw-r--r-- | lib/ansible/modules/pip.py | 15 | ||||
-rw-r--r-- | test/integration/targets/pip/tasks/pip.yml | 22 |
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 |