Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow arbitrary arguments to be bassed through the pip module #55492

Merged
merged 2 commits into from
Dec 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions salt/modules/pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
use_vt=False,
trusted_host=None,
no_cache_dir=False,
extra_args=None,
cache_dir=None,
no_binary=None,
disable_version_check=False,
Expand Down Expand Up @@ -605,6 +606,24 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
no_cache_dir
Disable the cache.
extra_args
pip keyword and positional arguments not yet implemented in salt
.. code-block:: yaml
salt '*' pip.install pandas extra_args="[{'--latest-pip-kwarg':'param'}, '--latest-pip-arg']"
.. warning::
If unsupported options are passed here that are not supported in a
minion's version of pip, a `No such option error` will be thrown.
Will be translated into the following pip command:
.. code-block:: bash
pip install pandas --latest-pip-kwarg param --latest-pip-arg
disable_version_check
Pip may periodically check PyPI to determine whether a new version of
pip is available to download. Passing True for this option disables
Expand Down Expand Up @@ -896,6 +915,24 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
if trusted_host:
cmd.extend(['--trusted-host', trusted_host])

if extra_args:
# These are arguments from the latest version of pip that
# have not yet been implemented in salt
for arg in extra_args:
# It is a keyword argument
if isinstance(arg, dict):
# There will only ever be one item in this dictionary
key, val = arg.popitem()
# Don't allow any recursion into keyword arg definitions
# Don't allow multiple definitions of a keyword
if isinstance(val, (dict, list)):
raise TypeError("Too many levels in: {}".format(key))
# This is a a normal one-to-one keyword argument
cmd.extend([key, val])
# It is a positional argument, append it to the list
else:
cmd.append(arg)

cmd_kwargs = dict(saltenv=saltenv, use_vt=use_vt, runas=user)

if kwargs:
Expand Down
19 changes: 19 additions & 0 deletions salt/states/pip_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ def installed(name,
no_cache_dir=False,
cache_dir=None,
no_binary=None,
extra_args=None,
**kwargs):
'''
Make sure the package is installed
Expand Down Expand Up @@ -665,6 +666,23 @@ def installed(name,
- reload_modules: True
- exists_action: i
extra_args
pip keyword and positional arguments not yet implemented in salt
.. code-block:: yaml
pandas:
pip.installed:
- name: pandas
- extra_args:
- --latest-pip-kwarg: param
- --latest-pip-arg
.. warning::
If unsupported options are passed here that are not supported in a
minion's version of pip, a `No such option error` will be thrown.
.. _`virtualenv`: http://www.virtualenv.org/en/latest/
'''
Expand Down Expand Up @@ -901,6 +919,7 @@ def installed(name,
use_vt=use_vt,
trusted_host=trusted_host,
no_cache_dir=no_cache_dir,
extra_args=extra_args,
disable_version_check=True,
**kwargs
)
Expand Down
38 changes: 36 additions & 2 deletions tests/unit/modules/test_pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,41 @@ def test_install_multiple_requirements_arguments_in_resulting_command(self):
python_shell=False,
)

def test_install_extra_args_arguments_in_resulting_command(self):
pkg = 'pep8'
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
with patch.dict(pip.__salt__, {'cmd.run_all': mock}):
pip.install(pkg, extra_args=[
{"--latest-pip-kwarg": "param"},
"--latest-pip-arg"
])
expected = [
sys.executable, '-m', 'pip', 'install', pkg,
"--latest-pip-kwarg", "param", "--latest-pip-arg"
]
mock.assert_called_with(
expected,
saltenv='base',
runas=None,
use_vt=False,
python_shell=False,
)

def test_install_extra_args_arguments_recursion_error(self):
pkg = 'pep8'
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
with patch.dict(pip.__salt__, {'cmd.run_all': mock}):

self.assertRaises(TypeError, lambda: pip.install(
pkg, extra_args=[
{"--latest-pip-kwarg": ["param1", "param2"]},
]))

self.assertRaises(TypeError, lambda: pip.install(
pkg, extra_args=[
{"--latest-pip-kwarg": [{"--too-deep": dict()}]},
]))

def test_uninstall_multiple_requirements_arguments_in_resulting_command(self):
with patch('salt.modules.pip._get_cached_requirements') as get_cached_requirements:
cached_reqs = [
Expand Down Expand Up @@ -1280,8 +1315,7 @@ def test_is_installed_false(self):

def test_install_pre_argument_in_resulting_command(self):
pkg = 'pep8'
# Lower than 1.4 versions don't end-up with `--pre` in the resulting
# output
# Lower than 1.4 versions don't end up with `--pre` in the resulting output
mock = MagicMock(side_effect=[
{'retcode': 0, 'stdout': 'pip 1.2.0 /path/to/site-packages/pip'},
{'retcode': 0, 'stdout': ''}
Expand Down