Merge branch '2017.7' into '2018.3'

Conflicts:
  - salt/config/__init__.py
  - salt/minion.py
  - salt/modules/pip.py
  - salt/states/pip_state.py
  - salt/states/virtualenv_mod.py
  - tests/integration/modules/test_status.py
This commit is contained in:
rallytime 2018-04-19 17:15:20 -04:00
commit 4718d31e53
No known key found for this signature in database
GPG key ID: E8F1A4B90D0DEA19
21 changed files with 437 additions and 94 deletions

View file

@ -188,7 +188,7 @@ execution modules
iwtools
jboss7
jboss7_cli
jenkins
jenkinsmod
junos
k8s
kapacitor

View file

@ -1,5 +0,0 @@
salt.modules.jenkins module
===========================
.. automodule:: salt.modules.jenkins
:members:

View file

@ -0,0 +1,5 @@
salt.modules.jenkinsmod module
==============================
.. automodule:: salt.modules.jenkinsmod
:members:

View file

@ -157,7 +157,7 @@ If (Test-Path "$($ini[$bitPaths]['VCforPythonDir'])\vcvarsall.bat") {
# Install Microsoft Visual C++ for Python2.7
Write-Output " - Installing $($ini['Prerequisites']['VCforPython']) . . ."
$file = "$($ini['Settings']['DownloadDir'])\$($ini['Prerequisites']['VCforPython'])"
$p = Start-Process msiexec.exe -ArgumentList "/i $file /qb ALLUSERS=1" -Wait -NoNewWindow -PassThru
$p = Start-Process msiexec.exe -ArgumentList "/i $file /quiet ALLUSERS=1" -Wait -NoNewWindow -PassThru
}
#------------------------------------------------------------------------------
@ -175,7 +175,7 @@ If (Test-Path "$($ini['Settings']['Python2Dir'])\python.exe") {
DownloadFileWithProgress $url $file
Write-Output " - $script_name :: Installing $($ini[$bitPrograms]['Python2']) . . ."
$p = Start-Process msiexec -ArgumentList "/i $file /qb ADDLOCAL=DefaultFeature,SharedCRT,Extensions,pip_feature,PrependPath TARGETDIR=`"$($ini['Settings']['Python2Dir'])`"" -Wait -NoNewWindow -PassThru
$p = Start-Process msiexec -ArgumentList "/i $file /quiet ADDLOCAL=DefaultFeature,SharedCRT,Extensions,pip_feature,PrependPath TARGETDIR=`"$($ini['Settings']['Python2Dir'])`"" -Wait -NoNewWindow -PassThru
}
#------------------------------------------------------------------------------
@ -197,17 +197,17 @@ Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Updating PIP and SetupTools . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_PIP_LOCAL_CACHE) {
Start_Process_and_test_exitcode "$($ini['Settings']['Python2Dir'])\python.exe" "-m pip --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
} else {
$p = New-Item $Env:SALT_PIP_LOCAL_CACHE -ItemType Directory -Force # Ensure directory exists
if ( (Get-ChildItem $Env:SALT_PIP_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req_pip.txt into empty local cache SALT_REQ_PIP $Env:SALT_PIP_LOCAL_CACHE"
Start_Process_and_test_exitcode "$($ini['Settings']['Python2Dir'])\python.exe" "-m pip download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_PIP_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "$($ini['Settings']['Python2Dir'])\python.exe" "-m pip install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
}
#==============================================================================
@ -218,16 +218,16 @@ Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Installing pypi resources using pip . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_REQ_LOCAL_CACHE) {
Start_Process_and_test_exitcode "$($ini['Settings']['Scripts2Dir'])\pip.exe" "--no-cache-dir install -r $($script_path)\req.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --no-cache-dir install -r $($script_path)\req.txt" "pip install"
} else {
if ( (Get-ChildItem $Env:SALT_REQ_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req.txt into empty local cache SALT_REQ $Env:SALT_REQ_LOCAL_CACHE"
Start_Process_and_test_exitcode "$($ini['Settings']['Python2Dir'])\python.exe" "-m pip download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_REQ_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "$($ini['Settings']['Python2Dir'])\python.exe" "-m pip install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
}
#==============================================================================

View file

@ -157,7 +157,7 @@ If (Test-Path "$($ini[$bitPaths]['VCppBuildToolsDir'])\vcbuildtools.bat") {
# Install Microsoft Visual C++ Build Tools
Write-Output " - Installing $($ini['Prerequisites']['VCppBuildTools']) . . ."
$file = "$($ini['Settings']['DownloadDir'])\$($ini['Prerequisites']['VCppBuildTools'])"
$p = Start-Process $file -ArgumentList '/Passive' -Wait -NoNewWindow -PassThru
$p = Start-Process $file -ArgumentList '/Quiet' -Wait -NoNewWindow -PassThru
}
#------------------------------------------------------------------------------
@ -175,7 +175,7 @@ If (Test-Path "$($ini['Settings']['Python3Dir'])\python.exe") {
DownloadFileWithProgress $url $file
Write-Output " - $script_name :: Installing $($ini[$bitPrograms]['Python3']) . . ."
$p = Start-Process $file -ArgumentList "/passive InstallAllUsers=1 TargetDir=`"$($ini['Settings']['Python3Dir'])`" Include_doc=0 Include_tcltk=0 Include_test=0 Include_launcher=0 PrependPath=1 Shortcuts=0" -Wait -NoNewWindow -PassThru
$p = Start-Process $file -ArgumentList "/Quiet InstallAllUsers=1 TargetDir=`"$($ini['Settings']['Python3Dir'])`" Include_doc=0 Include_tcltk=0 Include_test=0 Include_launcher=0 PrependPath=1 Shortcuts=0" -Wait -NoNewWindow -PassThru
}
#------------------------------------------------------------------------------
@ -197,17 +197,17 @@ Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Updating PIP and SetupTools . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_PIP_LOCAL_CACHE) {
Start_Process_and_test_exitcode "$($ini['Settings']['Python3Dir'])\python.exe" "-m pip --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
} else {
$p = New-Item $Env:SALT_PIP_LOCAL_CACHE -ItemType Directory -Force # Ensure directory exists
if ( (Get-ChildItem $Env:SALT_PIP_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req_pip.txt into empty local cache SALT_REQ_PIP $Env:SALT_PIP_LOCAL_CACHE"
Start_Process_and_test_exitcode "$($ini['Settings']['Python3Dir'])\python.exe" "-m pip download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_PIP_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "$($ini['Settings']['Python3Dir'])\python.exe" "-m pip install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
}
#==============================================================================
@ -218,16 +218,16 @@ Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Installing pypi resources using pip . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_REQ_LOCAL_CACHE) {
Start_Process_and_test_exitcode "$($ini['Settings']['Scripts3Dir'])\pip.exe" "--no-cache-dir install -r $($script_path)\req.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --no-cache-dir install -r $($script_path)\req.txt" "pip install"
} else {
if ( (Get-ChildItem $Env:SALT_REQ_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req.txt into empty local cache SALT_REQ $Env:SALT_REQ_LOCAL_CACHE"
Start_Process_and_test_exitcode "$($ini['Settings']['Python3Dir'])\python.exe" "-m pip download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_REQ_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "$($ini['Settings']['Python3Dir'])\python.exe" "-m pip install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
}
#==============================================================================

View file

@ -50,8 +50,6 @@ goto CheckPython3
echo Failed, please remove manually
)
goto eof
:CheckPython3
if exist "\Python35" goto RemovePython3
@ -63,13 +61,13 @@ goto eof
:: 64 bit
if exist "%LOCALAPPDATA%\Package Cache\{b94f45d6-8461-440c-aa4d-bf197b2c2499}" (
echo %0 :: - 3.5.3 64bit
"%LOCALAPPDATA%\Package Cache\{b94f45d6-8461-440c-aa4d-bf197b2c2499}\python-3.5.3-amd64.exe" /uninstall /passive
"%LOCALAPPDATA%\Package Cache\{b94f45d6-8461-440c-aa4d-bf197b2c2499}\python-3.5.3-amd64.exe" /uninstall /quiet
)
:: 32 bit
if exist "%LOCALAPPDATA%\Package Cache\{a10037e1-4247-47c9-935b-c5ca049d0299}" (
echo %0 :: - 3.5.3 32bit
"%LOCALAPPDATA%\Package Cache\{a10037e1-4247-47c9-935b-c5ca049d0299}\python-3.5.3" /uninstall /passive
"%LOCALAPPDATA%\Package Cache\{a10037e1-4247-47c9-935b-c5ca049d0299}\python-3.5.3" /uninstall /quiet
)
rem wipe the Python directory

View file

@ -3883,6 +3883,8 @@ def apply_master_config(overrides=None, defaults=None):
if overrides:
opts.update(overrides)
opts['__cli'] = os.path.basename(sys.argv[0])
if 'environment' in opts:
if opts['saltenv'] is not None:
log.warning(

View file

@ -629,10 +629,16 @@ class MinionBase(object):
break
except SaltClientError as exc:
last_exc = exc
log.info(
'Master %s could not be reached, trying next '
'next master (if any)', opts['master']
)
if exc.strerror.startswith('Could not access'):
msg = (
'Failed to initiate connection with Master '
'%s: check ownership/permissions. Error '
'message: %s', opts['master'], exc
)
else:
msg = ('Master %s could not be reached, trying next '
'next master (if any)', opts['master'])
log.info(msg)
continue
if not conn:

View file

@ -397,7 +397,8 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
use_vt=False,
trusted_host=None,
no_cache_dir=False,
cache_dir=None):
cache_dir=None,
no_binary=None):
'''
Install packages with pip
@ -423,7 +424,12 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
Prefer wheel archives (requires pip>=1.4)
no_use_wheel
Force to not use wheel archives (requires pip>=1.4)
Force to not use wheel archives (requires pip>=1.4,<10.0.0)
no_binary
Force to not use binary packages (requires pip >= 7.0.0)
Accepts either :all: to disable all binary packages, :none: to empty the set,
or one or more package names with commas between them
log
Log file where a complete (maximum verbosity) record will be kept
@ -595,29 +601,48 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
if use_wheel:
min_version = '1.4'
max_version = '9.0.3'
cur_version = __salt__['pip.version'](bin_env)
if not salt.utils.versions.compare(ver1=cur_version, oper='>=',
ver2=min_version):
too_low = salt.utils.compare_versions(ver1=cur_version, oper='<', ver2=min_version)
too_high = salt.utils.compare_versions(ver1=cur_version, oper='>', ver2=max_version)
if too_low or too_high:
logger.error(
'The --use-wheel option is only supported in pip %s and '
'newer. The version of pip detected is %s. This option '
'will be ignored.', min_version, cur_version
'The --use-wheel option is only supported in pip between %s and '
'%s. The version of pip detected is %s. This option '
'will be ignored.', min_version, max_version, cur_version
)
else:
cmd.append('--use-wheel')
if no_use_wheel:
min_version = '1.4'
max_version = '9.0.3'
cur_version = __salt__['pip.version'](bin_env)
if not salt.utils.versions.compare(ver1=cur_version, oper='>=',
ver2=min_version):
too_low = salt.utils.compare_versions(ver1=cur_version, oper='<', ver2=min_version)
too_high = salt.utils.compare_versions(ver1=cur_version, oper='>', ver2=max_version)
if too_low or too_high:
logger.error(
'The --no-use-wheel option is only supported in pip %s and '
'The --no-use-wheel option is only supported in pip between %s and '
'%s. The version of pip detected is %s. This option '
'will be ignored.', min_version, max_version, cur_version
)
else:
cmd.append('--no-use-wheel')
if no_binary:
min_version = '7.0.0'
cur_version = __salt__['pip.version'](bin_env)
too_low = salt.utils.compare_versions(ver1=cur_version, oper='<', ver2=min_version)
if too_low:
logger.error(
'The --no-binary option is only supported in pip %s and '
'newer. The version of pip detected is %s. This option '
'will be ignored.', min_version, cur_version
)
else:
cmd.append('--no-use-wheel')
if isinstance(no_binary, list):
no_binary = ','.join(no_binary)
cmd.extend(['--no-binary', no_binary])
if log:
if os.path.isdir(log):
@ -783,6 +808,11 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
# Put the commas back in while making sure the names are contained in
# quotes, this allows for proper version spec passing salt>=0.17.0
cmd.extend([p.replace(';', ',') for p in pkgs])
elif not any([requirements, editable]):
# Starting with pip 10.0.0, if no packages are specified in the
# command, it returns a retcode 1. So instead of running the command,
# just return the output without running pip.
return {'retcode': 0, 'stdout': 'No packages to install.'}
if editable:
egg_match = re.compile(r'(?:#|#.*?&)egg=([^&]*)')

View file

@ -422,7 +422,7 @@ def _check_queue(queue, kwargs):
def _get_initial_pillar(opts):
return __pillar__ if __opts__['__cli'] == 'salt-call' \
return __pillar__ if __opts__.get('__cli', None) == 'salt-call' \
and opts['pillarenv'] == __opts__['pillarenv'] \
else None

View file

@ -302,7 +302,7 @@ class EventListener(object):
self.event.set_event_handler(self._handle_event_socket_recv)
def clean_timeout_futures(self, request):
def clean_by_request(self, request):
'''
Remove all futures that were waiting for request `request` since it is done waiting
'''
@ -494,7 +494,7 @@ class BaseSaltAPIHandler(tornado.web.RequestHandler): # pylint: disable=W0223
timeout a session
'''
# TODO: set a header or something??? so we know it was a timeout
self.application.event_listener.clean_timeout_futures(self)
self.application.event_listener.clean_by_request(self)
def on_finish(self):
'''
@ -977,8 +977,7 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
tag = tagify([jid, 'ret', minion], 'job')
minion_future = self.application.event_listener.get_event(self,
tag=tag,
matcher=EventListener.exact_matcher,
timeout=self.application.opts['timeout'])
matcher=EventListener.exact_matcher)
future_minion_map[minion_future] = minion
return future_minion_map
@ -1044,8 +1043,7 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
try:
event = self.application.event_listener.get_event(self,
tag=ping_tag,
timeout=self.application.opts['gather_job_timeout'],
)
timeout=self.application.opts['gather_job_timeout'])
f = yield Any([event, is_finished])
# When finished entire routine, cleanup other futures and return result
if f is is_finished:

View file

@ -41,14 +41,18 @@ except ImportError:
if HAS_PIP is True:
try:
import pip.req
from pip.req import InstallRequirement
except ImportError:
HAS_PIP = False
# Remove references to the loaded pip module above so reloading works
import sys
del pip
if 'pip' in sys.modules:
del sys.modules['pip']
# pip 10.0.0 move req module under pip._internal
try:
from pip._internal.req import InstallRequirement
except ImportError:
HAS_PIP = False
# Remove references to the loaded pip module above so reloading works
import sys
del pip
if 'pip' in sys.modules:
del sys.modules['pip']
try:
from pip.exceptions import InstallationError
@ -127,7 +131,7 @@ def _check_pkg_version_format(pkg):
# The next line is meant to trigger an AttributeError and
# handle lower pip versions
log.debug('Installed pip version: %s', pip.__version__)
install_req = pip.req.InstallRequirement.from_line(pkg)
install_req = InstallRequirement.from_line(pkg)
except AttributeError:
log.debug('Installed pip version is lower than 1.2')
supported_vcs = ('git', 'svn', 'hg', 'bzr')
@ -135,12 +139,12 @@ def _check_pkg_version_format(pkg):
for vcs in supported_vcs:
if pkg.startswith(vcs):
from_vcs = True
install_req = pip.req.InstallRequirement.from_line(
install_req = InstallRequirement.from_line(
pkg.split('{0}+'.format(vcs))[-1]
)
break
else:
install_req = pip.req.InstallRequirement.from_line(pkg)
install_req = InstallRequirement.from_line(pkg)
except (ValueError, InstallationError) as exc:
ret['result'] = False
if not from_vcs and '=' in pkg and '==' not in pkg:
@ -320,7 +324,8 @@ def installed(name,
use_vt=False,
trusted_host=None,
no_cache_dir=False,
cache_dir=None):
cache_dir=None,
no_binary=None):
'''
Make sure the package is installed
@ -355,6 +360,25 @@ def installed(name,
no_use_wheel : False
Force to not use wheel archives (requires pip>=1.4)
no_binary
Force to not use binary packages (requires pip >= 7.0.0)
Accepts either :all: to disable all binary packages, :none: to empty the set,
or a list of one or more packages
Example:
.. code-block:: yaml
django:
pip.installed:
- no_binary: ':all:'
flask:
pip.installed:
- no_binary:
- itsdangerous
- click
log
Log file where a complete (maximum verbosity) record will be kept
@ -597,23 +621,39 @@ def installed(name,
# Check that the pip binary supports the 'use_wheel' option
if use_wheel:
min_version = '1.4'
max_version = '9.0.3'
cur_version = __salt__['pip.version'](bin_env)
if not salt.utils.versions.compare(ver1=cur_version, oper='>=',
ver2=min_version):
too_low = salt.utils.compare_versions(ver1=cur_version, oper='<', ver2=min_version)
too_high = salt.utils.compare_versions(ver1=cur_version, oper='>', ver2=max_version)
if too_low or too_high:
ret['result'] = False
ret['comment'] = ('The \'use_wheel\' option is only supported in '
'pip {0} and newer. The version of pip detected '
'was {1}.').format(min_version, cur_version)
'pip between {0} and {1}. The version of pip detected '
'was {2}.').format(min_version, max_version, cur_version)
return ret
# Check that the pip binary supports the 'no_use_wheel' option
if no_use_wheel:
min_version = '1.4'
max_version = '9.0.3'
cur_version = __salt__['pip.version'](bin_env)
if not salt.utils.versions.compare(ver1=cur_version, oper='>=',
ver2=min_version):
too_low = salt.utils.compare_versions(ver1=cur_version, oper='<', ver2=min_version)
too_high = salt.utils.compare_versions(ver1=cur_version, oper='>', ver2=max_version)
if too_low or too_high:
ret['result'] = False
ret['comment'] = ('The \'no_use_wheel\' option is only supported in '
'pip between {0} and {1}. The version of pip detected '
'was {2}.').format(min_version, max_version, cur_version)
return ret
# Check that the pip binary supports the 'no_binary' option
if no_binary:
min_version = '7.0.0'
cur_version = __salt__['pip.version'](bin_env)
too_low = salt.utils.compare_versions(ver1=cur_version, oper='<', ver2=min_version)
if too_low:
ret['result'] = False
ret['comment'] = ('The \'no_binary\' option is only supported in '
'pip {0} and newer. The version of pip detected '
'was {1}.').format(min_version, cur_version)
return ret
@ -729,6 +769,7 @@ def installed(name,
bin_env=bin_env,
use_wheel=use_wheel,
no_use_wheel=no_use_wheel,
no_binary=no_binary,
log=log,
proxy=proxy,
timeout=timeout,

View file

@ -60,7 +60,8 @@ def managed(name,
pip_pkgs=None,
pip_no_cache_dir=False,
pip_cache_dir=None,
process_dependency_links=False):
process_dependency_links=False,
no_binary=None):
'''
Create a virtualenv and optionally manage it with pip
@ -110,6 +111,11 @@ def managed(name,
no_use_wheel: False
Force to not use wheel archives (requires pip>=1.4)
no_binary
Force to not use binary packages (requires pip >= 7.0.0)
Accepts either :all: to disable all binary packages, :none: to empty the set,
or a list of one or more packages
pip_upgrade: False
Pass `--upgrade` to `pip install`.
@ -229,27 +235,44 @@ def managed(name,
elif venv_exists:
ret['comment'] = 'virtualenv exists'
# Check that the pip binary supports the 'use_wheel' option
if use_wheel:
min_version = '1.4'
max_version = '9.0.3'
cur_version = __salt__['pip.version'](bin_env=name)
if not salt.utils.versions.compare(ver1=cur_version, oper='>=',
ver2=min_version):
too_low = salt.utils.compare_versions(ver1=cur_version, oper='<', ver2=min_version)
too_high = salt.utils.compare_versions(ver1=cur_version, oper='>', ver2=max_version)
if too_low or too_high:
ret['result'] = False
ret['comment'] = ('The \'use_wheel\' option is only supported in '
'pip {0} and newer. The version of pip detected '
'was {1}.').format(min_version, cur_version)
'pip between {0} and {1}. The version of pip detected '
'was {2}.').format(min_version, max_version, cur_version)
return ret
# Check that the pip binary supports the 'no_use_wheel' option
if no_use_wheel:
min_version = '1.4'
max_version = '9.0.3'
cur_version = __salt__['pip.version'](bin_env=name)
if not salt.utils.versions.compare(ver1=cur_version, oper='>=',
ver2=min_version):
too_low = salt.utils.compare_versions(ver1=cur_version, oper='<', ver2=min_version)
too_high = salt.utils.compare_versions(ver1=cur_version, oper='>', ver2=max_version)
if too_low or too_high:
ret['result'] = False
ret['comment'] = ('The \'no_use_wheel\' option is only supported '
'in pip {0} and newer. The version of pip '
'detected was {1}.').format(min_version,
cur_version)
ret['comment'] = ('The \'no_use_wheel\' option is only supported in '
'pip between {0} and {1}. The version of pip detected '
'was {2}.').format(min_version, max_version, cur_version)
return ret
# Check that the pip binary supports the 'no_binary' option
if no_binary:
min_version = '7.0.0'
cur_version = __salt__['pip.version'](bin_env=name)
too_low = salt.utils.compare_versions(ver1=cur_version, oper='<', ver2=min_version)
if too_low:
ret['result'] = False
ret['comment'] = ('The \'no_binary\' option is only supported in '
'pip {0} and newer. The version of pip detected '
'was {1}.').format(min_version, cur_version)
return ret
# Populate the venv via a requirements file
@ -282,6 +305,7 @@ def managed(name,
bin_env=name,
use_wheel=use_wheel,
no_use_wheel=no_use_wheel,
no_binary=no_binary,
user=user,
cwd=cwd,
index_url=index_url,

View file

@ -4,6 +4,5 @@
- user: issue-1959
{%- if grains.get('pythonversion')[0] != 2 %}
{#- wheels are disabled because the pip cache dir will not be owned by the above issue-1959 user. Need to check this ASAP #}
- use_wheel: False
- no_use_wheel: True
- no_binary: ':all:'
{%- endif %}

View file

@ -9,6 +9,7 @@ from tests.support.case import ModuleCase
from tests.support.unit import skipIf
# Import Salt libs
from salt.ext import six
import salt.utils.platform
@ -26,3 +27,49 @@ class StatusModuleTest(ModuleCase):
random_pid = random.choice(grab_pids)
grep_salt = self.run_function('cmd.run', ['ps aux | grep salt'])
self.assertIn(random_pid, grep_salt)
@skipIf(not salt.utils.is_windows(), 'windows only test')
def test_status_cpuload(self):
'''
status.cpuload
'''
ret = self.run_function('status.cpuload')
self.assertTrue(isinstance(ret, float))
@skipIf(not salt.utils.is_windows(), 'windows only test')
def test_status_saltmem(self):
'''
status.saltmem
'''
ret = self.run_function('status.saltmem')
self.assertTrue(isinstance(ret, int))
def test_status_diskusage(self):
'''
status.diskusage
'''
ret = self.run_function('status.diskusage')
if salt.utils.is_windows():
self.assertTrue(isinstance(ret['percent'], float))
else:
self.assertIn('total', str(ret))
self.assertIn('available', str(ret))
def test_status_procs(self):
'''
status.procs
'''
ret = self.run_function('status.procs')
for x, y in six.iteritems(ret):
self.assertIn('cmd', y)
def test_status_uptime(self):
'''
status.uptime
'''
ret = self.run_function('status.uptime')
if salt.utils.is_windows():
self.assertTrue(isinstance(ret, float))
else:
self.assertTrue(isinstance(ret['days'], int))

View file

@ -117,6 +117,31 @@ class UseraddModuleTestWindows(ModuleCase):
random.choice(string.ascii_uppercase + string.digits)
for x in range(size))
def setUp(self):
self.user_name = self.__random_string()
self.group_name = self.__random_string()
def tearDown(self):
self.run_function('user.delete', [self.user_name, True, True])
self.run_function('group.delete', [self.group_name])
def _add_user(self):
'''
helper class to add user
'''
if self.run_function('user.add', [self.user_name]) is False:
self.run_function('user.delete', [self.user_name, True, True])
self.skipTest('Failed to create user')
def _add_group(self):
'''
helper class to add group
'''
if self.run_function('group.add', [self.group_name]) is False:
# Skip because creating is not what we're testing here
self.run_function('group.delete', [self.group_name, True, True])
self.skipTest('Failed to create group')
def test_add_user(self):
'''
Test adding a user
@ -185,3 +210,84 @@ class UseraddModuleTestWindows(ModuleCase):
finally:
self.run_function('user.delete', [user_name, True, True])
self.run_function('group.delete', [group_name])
def test_add_user_addgroup(self):
'''
Test adding a user to a group with groupadd
'''
self._add_group()
self._add_user()
self.run_function('user.addgroup', [self.user_name, self.group_name])
info = self.run_function('user.info', [self.user_name])
self.assertEqual(info['groups'], [self.group_name])
def test_user_chhome(self):
'''
Test changing a users home dir
'''
self._add_user()
user_dir = r'c:\salt'
self.run_function('user.chhome', [self.user_name, user_dir])
info = self.run_function('user.info', [self.user_name])
self.assertEqual(info['home'], user_dir)
def test_user_chprofile(self):
'''
Test changing a users profile
'''
self._add_user()
config = r'c:\salt\config'
self.run_function('user.chprofile', [self.user_name, config])
info = self.run_function('user.info', [self.user_name])
self.assertEqual(info['profile'], config)
def test_user_chfullname(self):
'''
Test changing a users fullname
'''
self._add_user()
name = 'Salt Test'
self.run_function('user.chfullname', [self.user_name, name])
info = self.run_function('user.info', [self.user_name])
self.assertEqual(info['fullname'], name)
def test_user_delete(self):
'''
Test deleting a user
'''
self._add_user()
self.assertTrue(self.run_function('user.info', [self.user_name])['active'])
self.run_function('user.delete', [self.user_name])
self.assertEqual({}, self.run_function('user.info', [self.user_name]))
def test_user_removegroup(self):
'''
Test removing a group
'''
self._add_user()
self._add_group()
self.run_function('user.addgroup', [self.user_name, self.group_name])
self.assertIn(self.group_name, self.run_function('user.list_groups', [self.user_name]))
self.run_function('user.removegroup', [self.group_name])
self.assertIn(self.group_name, self.run_function('user.list_groups', [self.user_name]))
def test_user_rename(self):
'''
Test changing a users name
'''
self._add_user()
name = 'newuser'
self.run_function('user.rename', [self.user_name, name])
info = self.run_function('user.info', [name])
self.assertTrue(info['active'])
#delete new user
self.run_function('user.delete', [name, True, True])
def test_user_setpassword(self):
'''
Test setting a password
'''
self._add_user()
passwd = 'sup3rs3cr3T!'
self.assertTrue(self.run_function('user.setpassword', [self.user_name, passwd]))

View file

@ -10,6 +10,7 @@ from __future__ import absolute_import, print_function
import os
import sys
import time
import warnings
TESTS_DIR = os.path.dirname(os.path.normpath(os.path.abspath(__file__)))
if os.name == 'nt':
@ -517,20 +518,26 @@ class SaltTestsuiteParser(SaltCoverageTestingParser):
is_admin = True
else:
is_admin = salt.utils.win_functions.is_admin(current_user)
if self.options.coverage and any((
self.options.name,
not is_admin,
not self.options.run_destructive)) \
and self._check_enabled_suites(include_unit=True):
warnings.warn("Test suite not running with elevated priviledges")
else:
is_admin = os.geteuid() == 0
if self.options.coverage and any((
self.options.name,
not is_admin,
not self.options.run_destructive)) \
and self._check_enabled_suites(include_unit=True):
self.error(
'No sense in generating the tests coverage report when '
'not running the full test suite, including the '
'destructive tests, as \'root\'. It would only produce '
'incorrect results.'
)
if self.options.coverage and any((
self.options.name,
not is_admin,
not self.options.run_destructive)) \
and self._check_enabled_suites(include_unit=True):
self.error(
'No sense in generating the tests coverage report when '
'not running the full test suite, including the '
'destructive tests, as \'root\'. It would only produce '
'incorrect results.'
)
# When no tests are specifically enumerated on the command line, setup
# a default run: +unit -cloud_provider

View file

@ -138,11 +138,12 @@ class PipTestCase(TestCase, LoaderModuleMockMixin):
expected = ['pip', 'install', '--use-mirrors']
for item in mirrors:
expected.extend(['--mirrors', item])
expected.append('pep8')
# Passing mirrors as a list
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
with patch.dict(pip.__salt__, {'cmd.run_all': mock}):
pip.install(mirrors=mirrors)
pip.install(pkgs=['pep8'], mirrors=mirrors)
mock.assert_called_once_with(
expected,
saltenv='base',
@ -154,7 +155,7 @@ class PipTestCase(TestCase, LoaderModuleMockMixin):
# Passing mirrors as a comma separated list
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
with patch.dict(pip.__salt__, {'cmd.run_all': mock}):
pip.install(mirrors=','.join(mirrors))
pip.install(pkgs=['pep8'], mirrors=','.join(mirrors))
mock.assert_called_once_with(
expected,
saltenv='base',
@ -166,9 +167,9 @@ class PipTestCase(TestCase, LoaderModuleMockMixin):
# As single string (just use the first element from mirrors)
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
with patch.dict(pip.__salt__, {'cmd.run_all': mock}):
pip.install(mirrors=mirrors[0])
pip.install(pkgs=['pep8'], mirrors=mirrors[0])
mock.assert_called_once_with(
['pip', 'install', '--use-mirrors', '--mirrors', mirrors[0]],
['pip', 'install', '--use-mirrors', '--mirrors', mirrors[0], 'pep8'],
saltenv='base',
runas=None,
use_vt=False,

View file

@ -140,3 +140,84 @@ class TestEventListener(AsyncTestCase):
self.assertTrue(event_future.done())
with self.assertRaises(saltnado.TimeoutException):
event_future.result()
def test_clean_by_request(self):
'''
Make sure the method clean_by_request clean up every related data in EventListener
request_future_1 : will be timeout-ed by clean_by_request(self)
request_future_2 : will be finished by me.fire_event ...
dummy_request_future_1 : will be finished by me.fire_event ...
dummy_request_future_2 : will be timeout-ed by clean-by_request(dummy_request)
'''
class DummyRequest(object):
'''
Dummy request object to simulate the request object
'''
@property
def _finished(self):
'''
Simulate _finished of the request object
'''
return False
# Inner functions never permit modifying primitive values directly
cnt = [0]
def stop():
'''
To realize the scenario of this test, define a custom stop method to call
self.stop after finished two events.
'''
cnt[0] += 1
if cnt[0] == 2:
self.stop()
with eventpublisher_process():
me = event.MasterEvent(SOCK_DIR)
event_listener = saltnado.EventListener({}, # we don't use mod_opts, don't save?
{'sock_dir': SOCK_DIR,
'transport': 'zeromq'})
self.assertEqual(0, len(event_listener.tag_map))
self.assertEqual(0, len(event_listener.request_map))
self._finished = False # fit to event_listener's behavior
dummy_request = DummyRequest()
request_future_1 = event_listener.get_event(self, tag='evt1')
request_future_2 = event_listener.get_event(self, tag='evt2', callback=lambda f: stop())
dummy_request_future_1 = event_listener.get_event(dummy_request, tag='evt3', callback=lambda f: stop())
dummy_request_future_2 = event_listener.get_event(dummy_request, timeout=10, tag='evt4')
self.assertEqual(4, len(event_listener.tag_map))
self.assertEqual(2, len(event_listener.request_map))
me.fire_event({'data': 'foo2'}, 'evt2')
me.fire_event({'data': 'foo3'}, 'evt3')
self.wait()
event_listener.clean_by_request(self)
me.fire_event({'data': 'foo1'}, 'evt1')
self.assertTrue(request_future_1.done())
with self.assertRaises(saltnado.TimeoutException):
request_future_1.result()
self.assertTrue(request_future_2.done())
self.assertEqual(request_future_2.result()['tag'], 'evt2')
self.assertEqual(request_future_2.result()['data']['data'], 'foo2')
self.assertTrue(dummy_request_future_1.done())
self.assertEqual(dummy_request_future_1.result()['tag'], 'evt3')
self.assertEqual(dummy_request_future_1.result()['data']['data'], 'foo3')
self.assertFalse(dummy_request_future_2.done())
self.assertEqual(2, len(event_listener.tag_map))
self.assertEqual(1, len(event_listener.request_map))
event_listener.clean_by_request(dummy_request)
with self.assertRaises(saltnado.TimeoutException):
dummy_request_future_2.result()
self.assertEqual(0, len(event_listener.tag_map))
self.assertEqual(0, len(event_listener.request_map))

View file

@ -75,7 +75,7 @@ class VirtualenvModTestCase(TestCase, LoaderModuleMockMixin):
with patch.dict(virtualenv_mod.__opts__, {"test": False}):
ret.update({'comment': "The 'use_wheel' option is"
" only supported in pip 1.4 and newer."
" only supported in pip between 1.4 and 9.0.3."
" The version of pip detected was 1.1.",
'result': False})
self.assertDictEqual(virtualenv_mod.managed('salt',

View file

@ -1,5 +1,6 @@
integration.client.test_runner
integration.client.test_standard
integration.grains.test_core
integration.loader.test_ext_grains
integration.loader.test_ext_modules
integration.modules.test_aliases
@ -17,9 +18,11 @@ integration.modules.test_pillar
integration.modules.test_pkg
integration.modules.test_publish
integration.modules.test_state
integration.modules.test_status
integration.modules.test_sysmod
integration.modules.test_test
integration.modules.test_useradd
integration.reactor.test_reactor
integration.renderers.test_pydsl
integration.returners.test_librato_return
integration.runners.test_fileserver