mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #25561 from twangboy/fix_21041_again
Fixed the gem module to work on windows... without injection
This commit is contained in:
commit
3c32b0b669
2 changed files with 135 additions and 42 deletions
|
@ -4,15 +4,41 @@ Manage ruby gems.
|
|||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
try:
|
||||
from shlex import quote as _cmd_quote # pylint: disable=E0611
|
||||
except ImportError:
|
||||
from pipes import quote as _cmd_quote
|
||||
|
||||
# Import python libs
|
||||
import re
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
__func_alias__ = {
|
||||
'list_': 'list'
|
||||
}
|
||||
|
||||
|
||||
def _gem(command, ruby=None, runas=None, gem_bin=None):
|
||||
'''
|
||||
Run the actual gem command. If rvm or rbenv is installed, run the command
|
||||
using the corresponding module. rbenv is not available on windows, so don't
|
||||
try.
|
||||
|
||||
:param command: string
|
||||
Command to run
|
||||
:param ruby: string : None
|
||||
If RVM or rbenv are installed, the ruby version and gemset to use.
|
||||
Ignored if ``gem_bin`` is specified.
|
||||
:param runas: string : None
|
||||
The user to run gem as.
|
||||
:param gem_bin: string : None
|
||||
Full path to the ``gem`` binary
|
||||
|
||||
:return:
|
||||
Returns the full standard out including success codes or False if it fails
|
||||
'''
|
||||
cmdline = '{gem} {command}'.format(gem=gem_bin or 'gem', command=command)
|
||||
|
||||
# If a custom gem is given, use that and don't check for rvm/rbenv. User
|
||||
|
@ -21,7 +47,7 @@ def _gem(command, ruby=None, runas=None, gem_bin=None):
|
|||
if __salt__['rvm.is_installed'](runas=runas):
|
||||
return __salt__['rvm.do'](ruby, cmdline, runas=runas)
|
||||
|
||||
if __salt__['rbenv.is_installed'](runas=runas):
|
||||
if not salt.utils.is_windows() and __salt__['rbenv.is_installed'](runas=runas):
|
||||
if ruby is None:
|
||||
return __salt__['rbenv.do'](cmdline, runas=runas)
|
||||
else:
|
||||
|
@ -30,7 +56,7 @@ def _gem(command, ruby=None, runas=None, gem_bin=None):
|
|||
ret = __salt__['cmd.run_all'](
|
||||
cmdline,
|
||||
runas=runas,
|
||||
python_shell=False
|
||||
python_shell=True
|
||||
)
|
||||
|
||||
if ret['retcode'] == 0:
|
||||
|
@ -51,25 +77,25 @@ def install(gems, # pylint: disable=C0103
|
|||
'''
|
||||
Installs one or several gems.
|
||||
|
||||
gems
|
||||
:param gems: string
|
||||
The gems to install
|
||||
gem_bin : None
|
||||
:param gem_bin: string : None
|
||||
Full path to ``gem`` binary to use.
|
||||
ruby : None
|
||||
:param ruby: string : None
|
||||
If RVM or rbenv are installed, the ruby version and gemset to use.
|
||||
Ignored if ``gem_bin`` is specified.
|
||||
runas : None
|
||||
:param runas: string : None
|
||||
The user to run gem as.
|
||||
version : None
|
||||
:param version: string : None
|
||||
Specify the version to install for the gem.
|
||||
Doesn't play nice with multiple gems at once
|
||||
rdoc : False
|
||||
:param rdoc: boolean : False
|
||||
Generate RDoc documentation for the gem(s).
|
||||
ri : False
|
||||
:param ri: boolean : False
|
||||
Generate RI documentation for the gem(s).
|
||||
pre_releases
|
||||
:param pre_releases: boolean : False
|
||||
Include pre-releases in the available versions
|
||||
proxy : None
|
||||
:param proxy: string : None
|
||||
Use the specified HTTP proxy server for all outgoing traffic.
|
||||
Format: http://hostname[:port]
|
||||
|
||||
|
@ -81,8 +107,18 @@ def install(gems, # pylint: disable=C0103
|
|||
|
||||
salt '*' gem.install redphone gem_bin=/opt/sensu/embedded/bin/gem
|
||||
'''
|
||||
|
||||
# Check for injection
|
||||
if gems:
|
||||
gems = ' '.join([_cmd_quote(gem) for gem in gems.split()])
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
options = []
|
||||
if version:
|
||||
version = _cmd_quote(version) # injection check
|
||||
options.append('--version {0}'.format(version))
|
||||
if not rdoc:
|
||||
options.append('--no-rdoc')
|
||||
|
@ -91,6 +127,7 @@ def install(gems, # pylint: disable=C0103
|
|||
if pre_releases:
|
||||
options.append('--pre')
|
||||
if proxy:
|
||||
proxy = _cmd_quote(proxy) # injection check
|
||||
options.append('-p {0}'.format(proxy))
|
||||
|
||||
cmdline_args = ' '.join(options)
|
||||
|
@ -105,14 +142,14 @@ def uninstall(gems, ruby=None, runas=None, gem_bin=None):
|
|||
'''
|
||||
Uninstall one or several gems.
|
||||
|
||||
gems
|
||||
:param gems: string
|
||||
The gems to uninstall.
|
||||
gem_bin : None
|
||||
:param gem_bin: string : None
|
||||
Full path to ``gem`` binary to use.
|
||||
ruby : None
|
||||
:param ruby: string : None
|
||||
If RVM or rbenv are installed, the ruby version and gemset to use.
|
||||
Ignored if ``gem_bin`` is specified.
|
||||
runas : None
|
||||
:param runas: string : None
|
||||
The user to run gem as.
|
||||
|
||||
CLI Example:
|
||||
|
@ -121,7 +158,15 @@ def uninstall(gems, ruby=None, runas=None, gem_bin=None):
|
|||
|
||||
salt '*' gem.uninstall vagrant
|
||||
'''
|
||||
return _gem('uninstall {gems}'.format(gems=gems),
|
||||
# Check for injection
|
||||
if gems:
|
||||
gems = ' '.join([_cmd_quote(gem) for gem in gems.split()])
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
return _gem('uninstall {gems} -a -x'.format(gems=gems),
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
|
@ -131,14 +176,14 @@ def update(gems, ruby=None, runas=None, gem_bin=None):
|
|||
'''
|
||||
Update one or several gems.
|
||||
|
||||
gems
|
||||
:param gems: string
|
||||
The gems to update.
|
||||
gem_bin : None
|
||||
:param gem_bin: string : None
|
||||
Full path to ``gem`` binary to use.
|
||||
ruby : None
|
||||
:param ruby: string : None
|
||||
If RVM or rbenv are installed, the ruby version and gemset to use.
|
||||
Ignored if ``gem_bin`` is specified.
|
||||
runas : None
|
||||
:param runas: string : None
|
||||
The user to run gem as.
|
||||
|
||||
CLI Example:
|
||||
|
@ -147,6 +192,14 @@ def update(gems, ruby=None, runas=None, gem_bin=None):
|
|||
|
||||
salt '*' gem.update vagrant
|
||||
'''
|
||||
# Check for injection
|
||||
if gems:
|
||||
gems = ' '.join([_cmd_quote(gem) for gem in gems.split()])
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
return _gem('update {gems}'.format(gems=gems),
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
|
@ -157,14 +210,14 @@ def update_system(version='', ruby=None, runas=None, gem_bin=None):
|
|||
'''
|
||||
Update rubygems.
|
||||
|
||||
version : (newest)
|
||||
:param version: string : (newest)
|
||||
The version of rubygems to install.
|
||||
gem_bin : None
|
||||
:param gem_bin: string : None
|
||||
Full path to ``gem`` binary to use.
|
||||
ruby : None
|
||||
:param ruby: string : None
|
||||
If RVM or rbenv are installed, the ruby version and gemset to use.
|
||||
Ignored if ``gem_bin`` is specified.
|
||||
runas : None
|
||||
:param runas: string : None
|
||||
The user to run gem as.
|
||||
|
||||
CLI Example:
|
||||
|
@ -173,6 +226,14 @@ def update_system(version='', ruby=None, runas=None, gem_bin=None):
|
|||
|
||||
salt '*' gem.update_system
|
||||
'''
|
||||
# Check for injection
|
||||
if version:
|
||||
version = _cmd_quote(version)
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
return _gem('update --system {version}'.format(version=version),
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
|
@ -183,14 +244,14 @@ def list_(prefix='', ruby=None, runas=None, gem_bin=None):
|
|||
'''
|
||||
List locally installed gems.
|
||||
|
||||
prefix :
|
||||
:param prefix: string :
|
||||
Only list gems when the name matches this prefix.
|
||||
gem_bin : None
|
||||
:param gem_bin: string : None
|
||||
Full path to ``gem`` binary to use.
|
||||
ruby : None
|
||||
:param ruby: string : None
|
||||
If RVM or rbenv are installed, the ruby version and gemset to use.
|
||||
Ignored if ``gem_bin`` is specified.
|
||||
runas : None
|
||||
:param runas: string : None
|
||||
The user to run gem as.
|
||||
|
||||
CLI Example:
|
||||
|
@ -200,10 +261,19 @@ def list_(prefix='', ruby=None, runas=None, gem_bin=None):
|
|||
salt '*' gem.list
|
||||
'''
|
||||
gems = {}
|
||||
# Check for injection
|
||||
if prefix:
|
||||
prefix = _cmd_quote(prefix)
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
stdout = _gem('list {prefix}'.format(prefix=prefix),
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
|
||||
lines = []
|
||||
if isinstance(stdout, str):
|
||||
lines = stdout.splitlines()
|
||||
|
@ -213,6 +283,7 @@ def list_(prefix='', ruby=None, runas=None, gem_bin=None):
|
|||
gem = match.group(1)
|
||||
versions = match.group(2).split(', ')
|
||||
gems[gem] = versions
|
||||
|
||||
return gems
|
||||
|
||||
|
||||
|
@ -220,14 +291,14 @@ def sources_add(source_uri, ruby=None, runas=None, gem_bin=None):
|
|||
'''
|
||||
Add a gem source.
|
||||
|
||||
source_uri
|
||||
:param source_uri: string
|
||||
The source URI to add.
|
||||
gem_bin : None
|
||||
:param gem_bin: string : None
|
||||
Full path to ``gem`` binary to use.
|
||||
ruby : None
|
||||
:param ruby: string : None
|
||||
If RVM or rbenv are installed, the ruby version and gemset to use.
|
||||
Ignored if ``gem_bin`` is specified.
|
||||
runas : None
|
||||
:param runas: string : None
|
||||
The user to run gem as.
|
||||
|
||||
CLI Example:
|
||||
|
@ -236,6 +307,14 @@ def sources_add(source_uri, ruby=None, runas=None, gem_bin=None):
|
|||
|
||||
salt '*' gem.sources_add http://rubygems.org/
|
||||
'''
|
||||
# Check for injection
|
||||
if source_uri:
|
||||
source_uri = _cmd_quote(source_uri)
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
return _gem('sources --add {source_uri}'.format(source_uri=source_uri),
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
|
@ -246,14 +325,14 @@ def sources_remove(source_uri, ruby=None, runas=None, gem_bin=None):
|
|||
'''
|
||||
Remove a gem source.
|
||||
|
||||
source_uri
|
||||
:param source_uri: string
|
||||
The source URI to remove.
|
||||
gem_bin : None
|
||||
:param gem_bin: string : None
|
||||
Full path to ``gem`` binary to use.
|
||||
ruby : None
|
||||
:param ruby: string : None
|
||||
If RVM or rbenv are installed, the ruby version and gemset to use.
|
||||
Ignored if ``gem_bin`` is specified.
|
||||
runas : None
|
||||
:param runas: string : None
|
||||
The user to run gem as.
|
||||
|
||||
CLI Example:
|
||||
|
@ -262,6 +341,14 @@ def sources_remove(source_uri, ruby=None, runas=None, gem_bin=None):
|
|||
|
||||
salt '*' gem.sources_remove http://rubygems.org/
|
||||
'''
|
||||
# Check for injection
|
||||
if source_uri:
|
||||
source_uri = _cmd_quote(source_uri)
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
return _gem('sources --remove {source_uri}'.format(source_uri=source_uri),
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
|
@ -272,12 +359,12 @@ def sources_list(ruby=None, runas=None, gem_bin=None):
|
|||
'''
|
||||
List the configured gem sources.
|
||||
|
||||
gem_bin : None
|
||||
:param gem_bin: string : None
|
||||
Full path to ``gem`` binary to use.
|
||||
ruby : None
|
||||
:param ruby: string : None
|
||||
If RVM or rbenv are installed, the ruby version and gemset to use.
|
||||
Ignored if ``gem_bin`` is specified.
|
||||
runas : None
|
||||
:param runas: string : None
|
||||
The user to run gem as.
|
||||
|
||||
CLI Example:
|
||||
|
@ -286,5 +373,11 @@ def sources_list(ruby=None, runas=None, gem_bin=None):
|
|||
|
||||
salt '*' gem.sources_list
|
||||
'''
|
||||
# Check for injection
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
ret = _gem('sources', ruby, gem_bin=gem_bin, runas=runas)
|
||||
return [] if ret is False else ret.splitlines()[2:]
|
||||
|
|
|
@ -22,7 +22,7 @@ class TestGemModule(TestCase):
|
|||
'rbenv.is_installed': MagicMock(return_value=False),
|
||||
'cmd.run_all': mock}):
|
||||
gem._gem('install rails')
|
||||
mock.assert_called_once_with('gem install rails', runas=None, python_shell=False)
|
||||
mock.assert_called_once_with('gem install rails', runas=None, python_shell=True)
|
||||
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
||||
rvm_mock = MagicMock()
|
||||
|
@ -32,7 +32,7 @@ class TestGemModule(TestCase):
|
|||
'cmd.run_all': mock}):
|
||||
gem._gem('install rails', gem_bin="/usr/local/bin/gem")
|
||||
self.assertEqual(False, rvm_mock.called, "Should never call rvm.is_installed if gem_bin provided")
|
||||
mock.assert_called_once_with('/usr/local/bin/gem install rails', runas=None, python_shell=False)
|
||||
mock.assert_called_once_with('/usr/local/bin/gem install rails', runas=None, python_shell=True)
|
||||
|
||||
mock = MagicMock(return_value=None)
|
||||
with patch.dict(gem.__salt__,
|
||||
|
@ -62,7 +62,7 @@ class TestGemModule(TestCase):
|
|||
'cmd.run_all': mock}):
|
||||
gem.install('rails', pre_releases=True)
|
||||
mock.assert_called_once_with(
|
||||
'gem install rails --no-rdoc --no-ri --pre', runas=None, python_shell=False
|
||||
'gem install rails --no-rdoc --no-ri --pre', runas=None, python_shell=True
|
||||
)
|
||||
|
||||
def test_list(self):
|
||||
|
|
Loading…
Add table
Reference in a new issue