mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch '2017.7' into '2018.3'
Conflicts: - salt/client/ssh/state.py - salt/client/ssh/wrapper/state.py - salt/modules/dockermod.py - salt/modules/npm.py - salt/modules/testinframod.py - tests/integration/modules/test_mac_system.py - tests/integration/modules/test_mac_timezone.py - tests/integration/ssh/test_state.py - tests/integration/states/test_user.py - tests/unit/modules/test_npm.py - tests/unit/states/test_file.py
This commit is contained in:
commit
e740d3b208
39 changed files with 903 additions and 358 deletions
5
.ci/docs
5
.ci/docs
|
@ -1,8 +1,13 @@
|
|||
pipeline {
|
||||
agent { label 'docs' }
|
||||
options {
|
||||
timestamps()
|
||||
ansiColor('xterm')
|
||||
}
|
||||
environment {
|
||||
PYENV_ROOT = "/usr/local/pyenv"
|
||||
PATH = "$PYENV_ROOT/bin:$PATH"
|
||||
PY_COLORS = 1
|
||||
}
|
||||
stages {
|
||||
stage('github-pending') {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
pipeline {
|
||||
agent { label 'kitchen-slave' }
|
||||
options {
|
||||
timestamps()
|
||||
ansiColor('xterm')
|
||||
}
|
||||
environment {
|
||||
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
|
||||
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
|
||||
|
@ -7,6 +11,7 @@ pipeline {
|
|||
RBENV_VERSION = "2.4.2"
|
||||
TEST_SUITE = "py2"
|
||||
TEST_PLATFORM = "centos-7"
|
||||
PY_COLORS = 1
|
||||
}
|
||||
stages {
|
||||
stage('github-pending') {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
pipeline {
|
||||
agent { label 'kitchen-slave' }
|
||||
options {
|
||||
timestamps()
|
||||
ansiColor('xterm')
|
||||
}
|
||||
environment {
|
||||
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
|
||||
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
|
||||
|
@ -7,6 +11,7 @@ pipeline {
|
|||
RBENV_VERSION = "2.4.2"
|
||||
TEST_SUITE = "py3"
|
||||
TEST_PLATFORM = "centos-7"
|
||||
PY_COLORS = 1
|
||||
}
|
||||
stages {
|
||||
stage('github-pending') {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
pipeline {
|
||||
agent { label 'kitchen-slave' }
|
||||
options {
|
||||
timestamps()
|
||||
ansiColor('xterm')
|
||||
}
|
||||
environment {
|
||||
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
|
||||
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
|
||||
|
@ -7,6 +11,7 @@ pipeline {
|
|||
RBENV_VERSION = "2.4.2"
|
||||
TEST_SUITE = "py2"
|
||||
TEST_PLATFORM = "ubuntu-1604"
|
||||
PY_COLORS = 1
|
||||
}
|
||||
stages {
|
||||
stage('github-pending') {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
pipeline {
|
||||
agent { label 'kitchen-slave' }
|
||||
options {
|
||||
timestamps()
|
||||
ansiColor('xterm')
|
||||
}
|
||||
environment {
|
||||
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
|
||||
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
|
||||
|
@ -7,6 +11,7 @@ pipeline {
|
|||
RBENV_VERSION = "2.4.2"
|
||||
TEST_SUITE = "py3"
|
||||
TEST_PLATFORM = "ubuntu-1604"
|
||||
PY_COLORS = 1
|
||||
}
|
||||
stages {
|
||||
stage('github-pending') {
|
||||
|
|
5
.ci/lint
5
.ci/lint
|
@ -1,8 +1,13 @@
|
|||
pipeline {
|
||||
agent { label 'pr-lint-slave' }
|
||||
options {
|
||||
timestamps()
|
||||
ansiColor('xterm')
|
||||
}
|
||||
environment {
|
||||
PYENV_ROOT = "/usr/local/pyenv"
|
||||
PATH = "$PYENV_ROOT/bin:$PATH"
|
||||
PY_COLORS = 1
|
||||
}
|
||||
stages {
|
||||
stage('github-pending') {
|
||||
|
|
|
@ -130,20 +130,18 @@ If Defined ProgramFiles(x86) (
|
|||
)
|
||||
@echo.
|
||||
|
||||
@echo Copying VCRedist to Prerequisites
|
||||
@echo ----------------------------------------------------------------------
|
||||
:: Make sure the "prereq" directory exists
|
||||
If NOT Exist "%PreDir%" mkdir "%PreDir%"
|
||||
|
||||
:: Set the location of the vcredist to download
|
||||
If %Python%==3 (
|
||||
Set Url64="http://repo.saltstack.com/windows/dependencies/64/vcredist_x64_2015.exe"
|
||||
Set Url32="http://repo.saltstack.com/windows/dependencies/32/vcredist_x86_2015.exe"
|
||||
:: Don't include the vcredist for Py3 installations
|
||||
If %Python%==3 goto :vcredist_end
|
||||
|
||||
) Else (
|
||||
Set Url64="http://repo.saltstack.com/windows/dependencies/64/vcredist_x64_2008_mfc.exe"
|
||||
Set Url32="http://repo.saltstack.com/windows/dependencies/32/vcredist_x86_2008_mfc.exe"
|
||||
)
|
||||
@echo Copying VCRedist to Prerequisites
|
||||
@echo ----------------------------------------------------------------------
|
||||
|
||||
:: Set the location of the vcredist to download
|
||||
Set Url64="http://repo.saltstack.com/windows/dependencies/64/vcredist_x64_2008_mfc.exe"
|
||||
Set Url32="http://repo.saltstack.com/windows/dependencies/32/vcredist_x86_2008_mfc.exe"
|
||||
|
||||
:: Check for 64 bit by finding the Program Files (x86) directory
|
||||
If Defined ProgramFiles(x86) (
|
||||
|
@ -153,6 +151,8 @@ If Defined ProgramFiles(x86) (
|
|||
)
|
||||
@echo.
|
||||
|
||||
:vcredist_end
|
||||
|
||||
:: Remove the fixed path in .exe files
|
||||
@echo Removing fixed path from .exe files
|
||||
@echo ----------------------------------------------------------------------
|
||||
|
|
|
@ -415,26 +415,13 @@ Section -Prerequisites
|
|||
Var /Global CheckVcRedist
|
||||
StrCpy $CheckVcRedist "False"
|
||||
|
||||
# Visual C++ 2015 redist packages
|
||||
!define PY3_VC_REDIST_NAME "VC_Redist_2015"
|
||||
!define PY3_VC_REDIST_X64_GUID "{50A2BC33-C9CD-3BF1-A8FF-53C10A0B183C}"
|
||||
!define PY3_VC_REDIST_X86_GUID "{BBF2AC74-720C-3CB3-8291-5E34039232FA}"
|
||||
|
||||
# Visual C++ 2008 SP1 MFC Security Update redist packages
|
||||
!define PY2_VC_REDIST_NAME "VC_Redist_2008_SP1_MFC"
|
||||
!define PY2_VC_REDIST_X64_GUID "{5FCE6D76-F5DC-37AB-B2B8-22AB8CEDB1D4}"
|
||||
!define PY2_VC_REDIST_X86_GUID "{9BE518E6-ECC6-35A9-88E4-87755C07200F}"
|
||||
|
||||
${If} ${PYTHON_VERSION} == 3
|
||||
StrCpy $VcRedistName ${PY3_VC_REDIST_NAME}
|
||||
${If} ${CPUARCH} == "AMD64"
|
||||
StrCpy $VcRedistGuid ${PY3_VC_REDIST_X64_GUID}
|
||||
${Else}
|
||||
StrCpy $VcRedistGuid ${PY3_VC_REDIST_X86_GUID}
|
||||
${EndIf}
|
||||
StrCpy $CheckVcRedist "True"
|
||||
|
||||
${Else}
|
||||
# VCRedist only needs to be installed for Python 2
|
||||
${If} ${PYTHON_VERSION} == 2
|
||||
|
||||
StrCpy $VcRedistName ${PY2_VC_REDIST_NAME}
|
||||
${If} ${CPUARCH} == "AMD64"
|
||||
|
|
|
@ -167,7 +167,7 @@ def salt_refs(data, ret=None):
|
|||
return ret
|
||||
|
||||
|
||||
def prep_trans_tar(opts, file_client, chunks, file_refs, pillar=None, id_=None, roster_grains=None):
|
||||
def prep_trans_tar(file_client, chunks, file_refs, pillar=None, id_=None, roster_grains=None):
|
||||
'''
|
||||
Generate the execution package from the saltenv file refs and a low state
|
||||
data structure
|
||||
|
|
|
@ -36,6 +36,59 @@ __func_alias__ = {
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _ssh_state(chunks, st_kwargs,
|
||||
kwargs, test=False):
|
||||
'''
|
||||
Function to run a state with the given chunk via salt-ssh
|
||||
'''
|
||||
file_refs = salt.client.ssh.state.lowstate_file_refs(
|
||||
chunks,
|
||||
_merge_extra_filerefs(
|
||||
kwargs.get('extra_filerefs', ''),
|
||||
__opts__.get('extra_filerefs', '')
|
||||
)
|
||||
)
|
||||
# Create the tar containing the state pkg and relevant files.
|
||||
trans_tar = salt.client.ssh.state.prep_trans_tar(
|
||||
__context__['fileclient'],
|
||||
chunks,
|
||||
file_refs,
|
||||
__pillar__,
|
||||
st_kwargs['id_'])
|
||||
trans_tar_sum = salt.utils.get_hash(trans_tar, __opts__['hash_type'])
|
||||
cmd = 'state.pkg {0}/salt_state.tgz test={1} pkg_sum={2} hash_type={3}'.format(
|
||||
__opts__['thin_dir'],
|
||||
test,
|
||||
trans_tar_sum,
|
||||
__opts__['hash_type'])
|
||||
single = salt.client.ssh.Single(
|
||||
__opts__,
|
||||
cmd,
|
||||
fsclient=__context__['fileclient'],
|
||||
minion_opts=__salt__.minion_opts,
|
||||
**st_kwargs)
|
||||
single.shell.send(
|
||||
trans_tar,
|
||||
'{0}/salt_state.tgz'.format(__opts__['thin_dir']))
|
||||
stdout, stderr, _ = single.cmd_block()
|
||||
|
||||
# Clean up our tar
|
||||
try:
|
||||
os.remove(trans_tar)
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
|
||||
# Read in the JSON data and return the data structure
|
||||
try:
|
||||
return json.loads(stdout, object_hook=salt.utils.decode_dict)
|
||||
except Exception as e:
|
||||
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
|
||||
log.error(str(e))
|
||||
|
||||
# If for some reason the json load fails, return the stdout
|
||||
return stdout
|
||||
|
||||
|
||||
def _set_retcode(ret, highstate=None):
|
||||
'''
|
||||
Set the return code based on the data back from the state system
|
||||
|
@ -165,7 +218,6 @@ def sls(mods, saltenv='base', test=None, exclude=None, **kwargs):
|
|||
# Create the tar containing the state pkg and relevant files.
|
||||
_cleanup_slsmod_low_data(chunks)
|
||||
trans_tar = salt.client.ssh.state.prep_trans_tar(
|
||||
opts,
|
||||
__context__['fileclient'],
|
||||
chunks,
|
||||
file_refs,
|
||||
|
@ -310,7 +362,6 @@ def low(data, **kwargs):
|
|||
|
||||
# Create the tar containing the state pkg and relevant files.
|
||||
trans_tar = salt.client.ssh.state.prep_trans_tar(
|
||||
__opts__,
|
||||
__context__['fileclient'],
|
||||
chunks,
|
||||
file_refs,
|
||||
|
@ -401,7 +452,6 @@ def high(data, **kwargs):
|
|||
# Create the tar containing the state pkg and relevant files.
|
||||
_cleanup_slsmod_low_data(chunks)
|
||||
trans_tar = salt.client.ssh.state.prep_trans_tar(
|
||||
opts,
|
||||
__context__['fileclient'],
|
||||
chunks,
|
||||
file_refs,
|
||||
|
@ -647,7 +697,6 @@ def highstate(test=None, **kwargs):
|
|||
# Create the tar containing the state pkg and relevant files.
|
||||
_cleanup_slsmod_low_data(chunks)
|
||||
trans_tar = salt.client.ssh.state.prep_trans_tar(
|
||||
opts,
|
||||
__context__['fileclient'],
|
||||
chunks,
|
||||
file_refs,
|
||||
|
@ -730,7 +779,6 @@ def top(topfn, test=None, **kwargs):
|
|||
# Create the tar containing the state pkg and relevant files.
|
||||
_cleanup_slsmod_low_data(chunks)
|
||||
trans_tar = salt.client.ssh.state.prep_trans_tar(
|
||||
opts,
|
||||
__context__['fileclient'],
|
||||
chunks,
|
||||
file_refs,
|
||||
|
@ -849,6 +897,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
|||
|
||||
salt '*' state.sls_id my_state my_module,a_common_module
|
||||
'''
|
||||
st_kwargs = __salt__.kwargs
|
||||
conflict = _check_queue(queue, kwargs)
|
||||
if conflict is not None:
|
||||
return conflict
|
||||
|
@ -861,13 +910,11 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
|||
if opts['saltenv'] is None:
|
||||
opts['saltenv'] = 'base'
|
||||
|
||||
try:
|
||||
st_ = salt.state.HighState(opts,
|
||||
proxy=__proxy__,
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
except NameError:
|
||||
st_ = salt.state.HighState(opts,
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
st_ = salt.client.ssh.state.SSHHighState(
|
||||
__opts__,
|
||||
__pillar__,
|
||||
__salt__,
|
||||
__context__['fileclient'])
|
||||
|
||||
if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
__context__['retcode'] = 5
|
||||
|
@ -878,10 +925,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
|||
if isinstance(mods, six.string_types):
|
||||
split_mods = mods.split(',')
|
||||
st_.push_active()
|
||||
try:
|
||||
high_, errors = st_.render_highstate({opts['saltenv']: split_mods})
|
||||
finally:
|
||||
st_.pop_active()
|
||||
high_, errors = st_.render_highstate({opts['saltenv']: split_mods})
|
||||
errors += st_.state.verify_high(high_)
|
||||
# Apply requisites to high data
|
||||
high_, req_in_errors = st_.state.requisite_in(high_)
|
||||
|
@ -893,17 +937,22 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
|||
__context__['retcode'] = 1
|
||||
return errors
|
||||
chunks = st_.state.compile_high_data(high_)
|
||||
ret = {}
|
||||
for chunk in chunks:
|
||||
if chunk.get('__id__', '') == id_:
|
||||
ret.update(st_.state.call_chunk(chunk, {}, chunks))
|
||||
chunk = [x for x in chunks if x.get('__id__', '') == id_]
|
||||
|
||||
_set_retcode(ret, highstate=highstate)
|
||||
if not ret:
|
||||
if not chunk:
|
||||
raise SaltInvocationError(
|
||||
'No matches for ID \'{0}\' found in SLS \'{1}\' within saltenv '
|
||||
'\'{2}\''.format(id_, mods, opts['saltenv'])
|
||||
)
|
||||
|
||||
ret = _ssh_state(chunk,
|
||||
st_kwargs,
|
||||
kwargs,
|
||||
test=test)
|
||||
_set_retcode(ret, highstate=highstate)
|
||||
# Work around Windows multiprocessing bug, set __opts__['test'] back to
|
||||
# value from before this function was run.
|
||||
__opts__['test'] = orig_test
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -1093,7 +1142,6 @@ def single(fun, name, test=None, **kwargs):
|
|||
|
||||
# Create the tar containing the state pkg and relevant files.
|
||||
trans_tar = salt.client.ssh.state.prep_trans_tar(
|
||||
opts,
|
||||
__context__['fileclient'],
|
||||
chunks,
|
||||
file_refs,
|
||||
|
|
|
@ -608,9 +608,17 @@ class AsyncAuth(object):
|
|||
error = SaltClientError('Detect mode is on')
|
||||
break
|
||||
if self.opts.get('caller'):
|
||||
print('Minion failed to authenticate with the master, '
|
||||
'has the minion key been accepted?')
|
||||
sys.exit(2)
|
||||
# We have a list of masters, so we should break
|
||||
# and try the next one in the list.
|
||||
if self.opts.get('local_masters', None):
|
||||
error = SaltClientError('Minion failed to authenticate'
|
||||
' with the master, has the '
|
||||
'minion key been accepted?')
|
||||
break
|
||||
else:
|
||||
print('Minion failed to authenticate with the master, '
|
||||
'has the minion key been accepted?')
|
||||
sys.exit(2)
|
||||
if acceptance_wait_time:
|
||||
log.info(
|
||||
'Waiting %s seconds before retry.', acceptance_wait_time
|
||||
|
|
|
@ -67,10 +67,10 @@ if USE_IMPORTLIB:
|
|||
SUFFIXES = []
|
||||
for suffix in importlib.machinery.EXTENSION_SUFFIXES:
|
||||
SUFFIXES.append((suffix, 'rb', MODULE_KIND_EXTENSION))
|
||||
for suffix in importlib.machinery.BYTECODE_SUFFIXES:
|
||||
SUFFIXES.append((suffix, 'rb', MODULE_KIND_COMPILED))
|
||||
for suffix in importlib.machinery.SOURCE_SUFFIXES:
|
||||
SUFFIXES.append((suffix, 'rb', MODULE_KIND_SOURCE))
|
||||
for suffix in importlib.machinery.BYTECODE_SUFFIXES:
|
||||
SUFFIXES.append((suffix, 'rb', MODULE_KIND_COMPILED))
|
||||
MODULE_KIND_MAP = {
|
||||
MODULE_KIND_SOURCE: importlib.machinery.SourceFileLoader,
|
||||
MODULE_KIND_COMPILED: importlib.machinery.SourcelessFileLoader,
|
||||
|
|
|
@ -101,6 +101,7 @@ def cert(name,
|
|||
server=None,
|
||||
owner='root',
|
||||
group='root',
|
||||
mode='0640',
|
||||
certname=None):
|
||||
'''
|
||||
Obtain/renew a certificate from an ACME CA, probably Let's Encrypt.
|
||||
|
@ -113,8 +114,9 @@ def cert(name,
|
|||
:param renew: True/'force' to force a renewal, or a window of renewal before expiry in days
|
||||
:param keysize: RSA key bits
|
||||
:param server: API endpoint to talk to
|
||||
:param owner: owner of private key
|
||||
:param group: group of private key
|
||||
:param owner: owner of the private key file
|
||||
:param group: group of the private key file
|
||||
:param mode: mode of the private key file
|
||||
:param certname: Name of the certificate to save
|
||||
:return: dict with 'result' True/False/None, 'comment' and certificate's expiry date ('not_after')
|
||||
|
||||
|
@ -170,27 +172,17 @@ def cert(name,
|
|||
return {'result': False, 'comment': 'Certificate {0} renewal failed with:\n{1}'.format(name, res['stderr'])}
|
||||
|
||||
if 'no action taken' in res['stdout']:
|
||||
return {'result': None,
|
||||
'comment': 'No action taken on certificate {0}'.format(cert_file),
|
||||
'not_after': expires(name)}
|
||||
|
||||
if renew:
|
||||
comment = 'Certificate {0} unchanged'.format(cert_file)
|
||||
elif renew:
|
||||
comment = 'Certificate {0} renewed'.format(name)
|
||||
else:
|
||||
comment = 'Certificate {0} obtained'.format(name)
|
||||
ret = {'comment': comment, 'not_after': expires(name)}
|
||||
|
||||
res = __salt__['file.check_perms'](_cert_file(name, 'privkey'), {}, owner, group, '0600', follow_symlinks=True)
|
||||
|
||||
if res is None:
|
||||
ret['result'] = False
|
||||
ret['comment'] += ', but setting permissions failed.'
|
||||
elif not res[0].get('result', False):
|
||||
ret['result'] = False
|
||||
ret['comment'] += ', but setting permissions failed with \n{0}'.format(res[0]['comment'])
|
||||
else:
|
||||
ret['result'] = True
|
||||
ret['comment'] += '.'
|
||||
ret = {'comment': comment, 'not_after': expires(name), 'changes': {}, 'result': True}
|
||||
ret, _ = __salt__['file.check_perms'](_cert_file(name, 'privkey'),
|
||||
ret,
|
||||
owner, group, mode,
|
||||
follow_symlinks=True)
|
||||
|
||||
return ret
|
||||
|
||||
|
|
|
@ -6467,7 +6467,6 @@ def _prepare_trans_tar(name, sls_opts, mods=None, pillar=None):
|
|||
refs = salt.client.ssh.state.lowstate_file_refs(chunks)
|
||||
_mk_fileclient()
|
||||
trans_tar = salt.client.ssh.state.prep_trans_tar(
|
||||
sls_opts,
|
||||
__context__['cp.fileclient'],
|
||||
chunks, refs, pillar, name)
|
||||
return trans_tar
|
||||
|
|
|
@ -86,6 +86,9 @@ def fire_master(data, tag, preload=None):
|
|||
channel = salt.transport.Channel.factory(__opts__, master_uri=master)
|
||||
try:
|
||||
channel.send(load)
|
||||
# channel.send was successful.
|
||||
# Ensure ret is True.
|
||||
ret = True
|
||||
except Exception:
|
||||
ret = False
|
||||
return ret
|
||||
|
|
|
@ -5075,7 +5075,7 @@ def manage_file(name,
|
|||
source
|
||||
file reference on the master
|
||||
|
||||
source_hash
|
||||
source_sum
|
||||
sum hash for source
|
||||
|
||||
user
|
||||
|
|
|
@ -162,7 +162,11 @@ def install(pkg=None,
|
|||
env.update({'SUDO_UID': uid, 'SUDO_USER': ''})
|
||||
|
||||
cmd = ' '.join(cmd)
|
||||
result = __salt__['cmd.run_all'](cmd, python_shell=True, cwd=dir, runas=runas, env=env)
|
||||
result = __salt__['cmd.run_all'](cmd,
|
||||
python_shell=True,
|
||||
cwd=dir,
|
||||
runas=runas,
|
||||
env=env)
|
||||
|
||||
if result['retcode'] != 0:
|
||||
raise CommandExecutionError(result['stderr'])
|
||||
|
@ -170,33 +174,9 @@ def install(pkg=None,
|
|||
# npm >1.2.21 is putting the output to stderr even though retcode is 0
|
||||
npm_output = result['stdout'] or result['stderr']
|
||||
try:
|
||||
return salt.utils.json.loads(npm_output)
|
||||
return salt.utils.json.find_json(npm_output)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
json_npm_output = _extract_json(npm_output)
|
||||
return json_npm_output or npm_output
|
||||
|
||||
|
||||
def _extract_json(npm_output):
|
||||
lines = npm_output.splitlines()
|
||||
log.error(lines)
|
||||
|
||||
# Strip all lines until JSON output starts
|
||||
while lines and not lines[0].startswith('{') and not lines[0].startswith('['):
|
||||
lines = lines[1:]
|
||||
while lines and not lines[-1].startswith('}') and not lines[-1].startswith(']'):
|
||||
lines = lines[:-1]
|
||||
# macOS with fsevents includes the following line in the return
|
||||
# when a new module is installed which is invalid JSON:
|
||||
# [fsevents] Success: "..."
|
||||
while lines and (lines[0].startswith('[fsevents]') or lines[0].startswith('Pass ')):
|
||||
lines = lines[1:]
|
||||
try:
|
||||
return salt.utils.json.loads(''.join(lines))
|
||||
except ValueError:
|
||||
pass
|
||||
return None
|
||||
return npm_output
|
||||
|
||||
|
||||
def uninstall(pkg, dir=None, runas=None, env=None):
|
||||
|
|
|
@ -7,50 +7,55 @@ powercfg.
|
|||
|
||||
.. code-block:: bash
|
||||
|
||||
# Set monitor to never turn off on Battery power
|
||||
salt '*' powercfg.set_monitor_timeout 0 power=dc
|
||||
# Set disk timeout to 120 minutes on AC power
|
||||
salt '*' powercfg.set_disk_timeout 120 power=ac
|
||||
'''
|
||||
|
||||
# Import Python Libs
|
||||
from __future__ import absolute_import, unicode_literals, print_function
|
||||
import re
|
||||
import logging
|
||||
|
||||
# Import Salt Libs
|
||||
import salt.utils
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__virtualname__ = "powercfg"
|
||||
__virtualname__ = 'powercfg'
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only work on Windows
|
||||
'''
|
||||
if __grains__['os'] == 'Windows':
|
||||
return __virtualname__
|
||||
return (False, 'Module only works on Windows.')
|
||||
if not salt.utils.is_windows():
|
||||
return False, 'PowerCFG: Module only works on Windows'
|
||||
return __virtualname__
|
||||
|
||||
|
||||
def _get_current_scheme():
|
||||
cmd = "powercfg /getactivescheme"
|
||||
cmd = 'powercfg /getactivescheme'
|
||||
out = __salt__['cmd.run'](cmd, python_shell=False)
|
||||
matches = re.search(r"GUID: (.*) \(", out)
|
||||
matches = re.search(r'GUID: (.*) \(', out)
|
||||
return matches.groups()[0].strip()
|
||||
|
||||
|
||||
def _get_powercfg_minute_values(scheme, guid, subguid, safe_name):
|
||||
'''
|
||||
Returns the AC/DC values in an array for a guid and subguid for a the given scheme
|
||||
Returns the AC/DC values in an dict for a guid and subguid for a the given
|
||||
scheme
|
||||
'''
|
||||
if scheme is None:
|
||||
scheme = _get_current_scheme()
|
||||
|
||||
if __grains__['osrelease'] == '7':
|
||||
cmd = "powercfg /q {0} {1}".format(scheme, guid)
|
||||
cmd = 'powercfg /q {0} {1}'.format(scheme, guid)
|
||||
else:
|
||||
cmd = "powercfg /q {0} {1} {2}".format(scheme, guid, subguid)
|
||||
cmd = 'powercfg /q {0} {1} {2}'.format(scheme, guid, subguid)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=False)
|
||||
|
||||
split = out.split("\r\n\r\n")
|
||||
split = out.split('\r\n\r\n')
|
||||
if len(split) > 1:
|
||||
for s in split:
|
||||
if safe_name in s or subguid in s:
|
||||
|
@ -59,172 +64,309 @@ def _get_powercfg_minute_values(scheme, guid, subguid, safe_name):
|
|||
else:
|
||||
out = split[0]
|
||||
|
||||
raw_settings = re.findall(r"Power Setting Index: ([0-9a-fx]+)", out)
|
||||
return {"ac": int(raw_settings[0], 0) / 60, "dc": int(raw_settings[1], 0) / 60}
|
||||
raw_settings = re.findall(r'Power Setting Index: ([0-9a-fx]+)', out)
|
||||
return {'ac': int(raw_settings[0], 0) / 60,
|
||||
'dc': int(raw_settings[1], 0) / 60}
|
||||
|
||||
|
||||
def _set_powercfg_value(scheme, sub_group, setting_guid, power, value):
|
||||
'''
|
||||
Sets the value of a setting with a given power (ac/dc) to
|
||||
the given scheme
|
||||
Sets the AC/DC values of a setting with the given power for the given scheme
|
||||
'''
|
||||
salt.utils.warn_until(
|
||||
'Fluorine',
|
||||
'This function now expects the timeout value in minutes instead of '
|
||||
'seconds as stated in the documentation. This warning will be removed '
|
||||
'in Salt Fluorine.')
|
||||
if scheme is None:
|
||||
scheme = _get_current_scheme()
|
||||
|
||||
cmd = "powercfg /set{0}valueindex {1} {2} {3} {4}".format(power, scheme, sub_group, setting_guid, value)
|
||||
return __salt__['cmd.run'](cmd, python_shell=False)
|
||||
cmd = 'powercfg /set{0}valueindex {1} {2} {3} {4}' \
|
||||
''.format(power, scheme, sub_group, setting_guid, value * 60)
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
||||
|
||||
def set_monitor_timeout(timeout, power="ac", scheme=None):
|
||||
def set_monitor_timeout(timeout, power='ac', scheme=None):
|
||||
'''
|
||||
Set the monitor timeout in minutes for the given power scheme
|
||||
|
||||
Args:
|
||||
timeout (int):
|
||||
The amount of time in minutes before the monitor will timeout
|
||||
|
||||
power (str):
|
||||
Set the value for AC or DC power. Default is ``ac``. Valid options
|
||||
are:
|
||||
|
||||
- ``ac`` (AC Power)
|
||||
- ``dc`` (Battery)
|
||||
|
||||
scheme (str):
|
||||
The scheme to use, leave as ``None`` to use the current. Default is
|
||||
``None``. This can be the GUID or the Alias for the Scheme. Known
|
||||
Aliases are:
|
||||
|
||||
- ``SCHEME_BALANCED`` - Balanced
|
||||
- ``SCHEME_MAX`` - Power saver
|
||||
- ``SCHEME_MIN`` - High performance
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if successful, otherwise ``False``
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' powercfg.set_monitor_timeout 30 power=ac
|
||||
|
||||
timeout
|
||||
The amount of time in minutes before the monitor will timeout
|
||||
|
||||
power
|
||||
Should we set the value for AC or DC (battery)? Valid options ac,dc.
|
||||
|
||||
scheme
|
||||
The scheme to use, leave as None to use the current.
|
||||
|
||||
# Sets the monitor timeout to 30 minutes
|
||||
salt '*' powercfg.set_monitor_timeout 30
|
||||
'''
|
||||
return _set_powercfg_value(scheme, "SUB_VIDEO", "VIDEOIDLE", power, timeout)
|
||||
return _set_powercfg_value(
|
||||
scheme=scheme,
|
||||
sub_group='SUB_VIDEO',
|
||||
setting_guid='VIDEOIDLE',
|
||||
power=power,
|
||||
value=timeout)
|
||||
|
||||
|
||||
def get_monitor_timeout(scheme=None):
|
||||
'''
|
||||
Get the current monitor timeout of the given scheme
|
||||
|
||||
Args:
|
||||
scheme (str):
|
||||
The scheme to use, leave as ``None`` to use the current. Default is
|
||||
``None``. This can be the GUID or the Alias for the Scheme. Known
|
||||
Aliases are:
|
||||
|
||||
- ``SCHEME_BALANCED`` - Balanced
|
||||
- ``SCHEME_MAX`` - Power saver
|
||||
- ``SCHEME_MIN`` - High performance
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of both the AC and DC settings
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' powercfg.get_monitor_timeout
|
||||
|
||||
scheme
|
||||
The scheme to use, leave as None to use the current.
|
||||
'''
|
||||
return _get_powercfg_minute_values(scheme, "SUB_VIDEO", "VIDEOIDLE", "Turn off display after")
|
||||
return _get_powercfg_minute_values(
|
||||
scheme=scheme,
|
||||
guid='SUB_VIDEO',
|
||||
subguid='VIDEOIDLE',
|
||||
safe_name='Turn off display after')
|
||||
|
||||
|
||||
def set_disk_timeout(timeout, power="ac", scheme=None):
|
||||
def set_disk_timeout(timeout, power='ac', scheme=None):
|
||||
'''
|
||||
Set the disk timeout in minutes for the given power scheme
|
||||
|
||||
Args:
|
||||
timeout (int):
|
||||
The amount of time in minutes before the disk will timeout
|
||||
|
||||
power (str):
|
||||
Set the value for AC or DC power. Default is ``ac``. Valid options
|
||||
are:
|
||||
|
||||
- ``ac`` (AC Power)
|
||||
- ``dc`` (Battery)
|
||||
|
||||
scheme (str):
|
||||
The scheme to use, leave as ``None`` to use the current. Default is
|
||||
``None``. This can be the GUID or the Alias for the Scheme. Known
|
||||
Aliases are:
|
||||
|
||||
- ``SCHEME_BALANCED`` - Balanced
|
||||
- ``SCHEME_MAX`` - Power saver
|
||||
- ``SCHEME_MIN`` - High performance
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if successful, otherwise ``False``
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Sets the disk timeout to 30 minutes on battery
|
||||
salt '*' powercfg.set_disk_timeout 30 power=dc
|
||||
|
||||
timeout
|
||||
The amount of time in minutes before the disk will timeout
|
||||
|
||||
power
|
||||
Should we set the value for AC or DC (battery)? Valid options ac,dc.
|
||||
|
||||
scheme
|
||||
The scheme to use, leave as None to use the current.
|
||||
|
||||
'''
|
||||
return _set_powercfg_value(scheme, "SUB_DISK", "DISKIDLE", power, timeout)
|
||||
return _set_powercfg_value(
|
||||
scheme=scheme,
|
||||
sub_group='SUB_DISK',
|
||||
setting_guid='DISKIDLE',
|
||||
power=power,
|
||||
value=timeout)
|
||||
|
||||
|
||||
def get_disk_timeout(scheme=None):
|
||||
'''
|
||||
Get the current disk timeout of the given scheme
|
||||
|
||||
Args:
|
||||
scheme (str):
|
||||
The scheme to use, leave as ``None`` to use the current. Default is
|
||||
``None``. This can be the GUID or the Alias for the Scheme. Known
|
||||
Aliases are:
|
||||
|
||||
- ``SCHEME_BALANCED`` - Balanced
|
||||
- ``SCHEME_MAX`` - Power saver
|
||||
- ``SCHEME_MIN`` - High performance
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of both the AC and DC settings
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' powercfg.get_disk_timeout
|
||||
|
||||
scheme
|
||||
The scheme to use, leave as None to use the current.
|
||||
'''
|
||||
return _get_powercfg_minute_values(scheme, "SUB_DISK", "DISKIDLE", "Turn off hard disk after")
|
||||
return _get_powercfg_minute_values(
|
||||
scheme=scheme,
|
||||
guid='SUB_DISK',
|
||||
subguid='DISKIDLE',
|
||||
safe_name='Turn off hard disk after')
|
||||
|
||||
|
||||
def set_standby_timeout(timeout, power="ac", scheme=None):
|
||||
def set_standby_timeout(timeout, power='ac', scheme=None):
|
||||
'''
|
||||
Set the standby timeout in minutes for the given power scheme
|
||||
|
||||
Args:
|
||||
timeout (int):
|
||||
The amount of time in minutes before the computer sleeps
|
||||
|
||||
power (str):
|
||||
Set the value for AC or DC power. Default is ``ac``. Valid options
|
||||
are:
|
||||
|
||||
- ``ac`` (AC Power)
|
||||
- ``dc`` (Battery)
|
||||
|
||||
scheme (str):
|
||||
The scheme to use, leave as ``None`` to use the current. Default is
|
||||
``None``. This can be the GUID or the Alias for the Scheme. Known
|
||||
Aliases are:
|
||||
|
||||
- ``SCHEME_BALANCED`` - Balanced
|
||||
- ``SCHEME_MAX`` - Power saver
|
||||
- ``SCHEME_MIN`` - High performance
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if successful, otherwise ``False``
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Sets the system standby timeout to 30 minutes on Battery
|
||||
salt '*' powercfg.set_standby_timeout 30 power=dc
|
||||
|
||||
timeout
|
||||
The amount of time in minutes before the computer sleeps
|
||||
|
||||
power
|
||||
Should we set the value for AC or DC (battery)? Valid options ac,dc.
|
||||
|
||||
scheme
|
||||
The scheme to use, leave as None to use the current.
|
||||
|
||||
'''
|
||||
return _set_powercfg_value(scheme, "SUB_SLEEP", "STANDBYIDLE", power, timeout)
|
||||
return _set_powercfg_value(
|
||||
scheme=scheme,
|
||||
sub_group='SUB_SLEEP',
|
||||
setting_guid='STANDBYIDLE',
|
||||
power=power,
|
||||
value=timeout)
|
||||
|
||||
|
||||
def get_standby_timeout(scheme=None):
|
||||
'''
|
||||
Get the current standby timeout of the given scheme
|
||||
|
||||
scheme (str):
|
||||
The scheme to use, leave as ``None`` to use the current. Default is
|
||||
``None``. This can be the GUID or the Alias for the Scheme. Known
|
||||
Aliases are:
|
||||
|
||||
- ``SCHEME_BALANCED`` - Balanced
|
||||
- ``SCHEME_MAX`` - Power saver
|
||||
- ``SCHEME_MIN`` - High performance
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of both the AC and DC settings
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' powercfg.get_standby_timeout
|
||||
|
||||
scheme
|
||||
The scheme to use, leave as None to use the current.
|
||||
'''
|
||||
return _get_powercfg_minute_values(scheme, "SUB_SLEEP", "STANDBYIDLE", "Sleep after")
|
||||
return _get_powercfg_minute_values(
|
||||
scheme=scheme,
|
||||
guid='SUB_SLEEP',
|
||||
subguid='STANDBYIDLE',
|
||||
safe_name='Sleep after')
|
||||
|
||||
|
||||
def set_hibernate_timeout(timeout, power="ac", scheme=None):
|
||||
def set_hibernate_timeout(timeout, power='ac', scheme=None):
|
||||
'''
|
||||
Set the hibernate timeout in minutes for the given power scheme
|
||||
|
||||
Args:
|
||||
timeout (int):
|
||||
The amount of time in minutes before the computer hibernates
|
||||
|
||||
power (str):
|
||||
Set the value for AC or DC power. Default is ``ac``. Valid options
|
||||
are:
|
||||
|
||||
- ``ac`` (AC Power)
|
||||
- ``dc`` (Battery)
|
||||
|
||||
scheme (str):
|
||||
The scheme to use, leave as ``None`` to use the current. Default is
|
||||
``None``. This can be the GUID or the Alias for the Scheme. Known
|
||||
Aliases are:
|
||||
|
||||
- ``SCHEME_BALANCED`` - Balanced
|
||||
- ``SCHEME_MAX`` - Power saver
|
||||
- ``SCHEME_MIN`` - High performance
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if successful, otherwise ``False``
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' powercfg.set_hibernate_timeout 30 power=pc
|
||||
|
||||
timeout
|
||||
The amount of time in minutes before the computer hibernates
|
||||
|
||||
power
|
||||
Should we set the value for AC or DC (battery)? Valid options ac,dc.
|
||||
|
||||
scheme
|
||||
The scheme to use, leave as None to use the current.
|
||||
# Sets the hibernate timeout to 30 minutes on Battery
|
||||
salt '*' powercfg.set_hibernate_timeout 30 power=dc
|
||||
'''
|
||||
return _set_powercfg_value(scheme, "SUB_SLEEP", "HIBERNATEIDLE", power, timeout)
|
||||
return _set_powercfg_value(
|
||||
scheme=scheme,
|
||||
sub_group='SUB_SLEEP',
|
||||
setting_guid='HIBERNATEIDLE',
|
||||
power=power,
|
||||
value=timeout)
|
||||
|
||||
|
||||
def get_hibernate_timeout(scheme=None):
|
||||
'''
|
||||
Get the current hibernate timeout of the given scheme
|
||||
|
||||
scheme (str):
|
||||
The scheme to use, leave as ``None`` to use the current. Default is
|
||||
``None``. This can be the GUID or the Alias for the Scheme. Known
|
||||
Aliases are:
|
||||
|
||||
- ``SCHEME_BALANCED`` - Balanced
|
||||
- ``SCHEME_MAX`` - Power saver
|
||||
- ``SCHEME_MIN`` - High performance
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of both the AC and DC settings
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' powercfg.get_hibernate_timeout
|
||||
|
||||
scheme
|
||||
The scheme to use, leave as None to use the current.
|
||||
'''
|
||||
return _get_powercfg_minute_values(scheme, "SUB_SLEEP", "HIBERNATEIDLE", "Hibernate after")
|
||||
return _get_powercfg_minute_values(
|
||||
scheme=scheme,
|
||||
guid='SUB_SLEEP',
|
||||
subguid='HIBERNATEIDLE',
|
||||
safe_name='Hibernate after')
|
||||
|
|
|
@ -584,6 +584,8 @@ def latest_version(*names, **kwargs):
|
|||
status = pkg_info.get('status', '').lower()
|
||||
if status.find('not installed') > -1 or status.find('out-of-date') > -1:
|
||||
ret[name] = pkg_info.get('version')
|
||||
else:
|
||||
ret[name] = ''
|
||||
|
||||
# Return a string if only one package name passed
|
||||
if len(names) == 1 and len(ret):
|
||||
|
|
|
@ -49,6 +49,7 @@ def cert(name,
|
|||
server=None,
|
||||
owner='root',
|
||||
group='root',
|
||||
mode='0640',
|
||||
certname=None):
|
||||
'''
|
||||
Obtain/renew a certificate from an ACME CA, probably Let's Encrypt.
|
||||
|
@ -61,8 +62,9 @@ def cert(name,
|
|||
:param renew: True/'force' to force a renewal, or a window of renewal before expiry in days
|
||||
:param keysize: RSA key bits
|
||||
:param server: API endpoint to talk to
|
||||
:param owner: owner of private key
|
||||
:param group: group of private key
|
||||
:param owner: owner of the private key file
|
||||
:param group: group of the private key file
|
||||
:param mode: mode of the private key file
|
||||
:param certname: Name of the certificate to save
|
||||
'''
|
||||
|
||||
|
@ -105,7 +107,8 @@ def cert(name,
|
|||
keysize=keysize,
|
||||
server=server,
|
||||
owner=owner,
|
||||
group=group
|
||||
group=group,
|
||||
mode=mode
|
||||
)
|
||||
|
||||
ret = {
|
||||
|
|
|
@ -275,9 +275,13 @@ def bootstrap(name, user=None, silent=True):
|
|||
if __opts__['test']:
|
||||
try:
|
||||
call = __salt__['npm.install'](dir=name, runas=user, pkg=None, silent=silent, dry_run=True)
|
||||
ret['result'] = None
|
||||
ret['changes'] = {'old': [], 'new': call}
|
||||
ret['comment'] = '{0} is set to be bootstrapped'.format(name)
|
||||
if call:
|
||||
ret['result'] = None
|
||||
ret['changes'] = {'old': [], 'new': call}
|
||||
ret['comment'] = '{0} is set to be bootstrapped'.format(name)
|
||||
else:
|
||||
ret['result'] = True
|
||||
ret['comment'] = '{0} is already bootstrapped'.format(name)
|
||||
except (CommandNotFoundError, CommandExecutionError) as err:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Error Bootstrapping \'{0}\': {1}'.format(name, err)
|
||||
|
|
|
@ -8,6 +8,7 @@ powercfg.
|
|||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Set timeout to 30 minutes on battery power
|
||||
monitor:
|
||||
powercfg.set_timeout:
|
||||
- value: 30
|
||||
|
@ -18,82 +19,131 @@ powercfg.
|
|||
from __future__ import absolute_import, unicode_literals, print_function
|
||||
import logging
|
||||
|
||||
# Import Salt Libs
|
||||
import salt.utils
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__virtualname__ = "powercfg"
|
||||
__virtualname__ = 'powercfg'
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only work on Windows
|
||||
'''
|
||||
if __grains__['os'] == 'Windows':
|
||||
return __virtualname__
|
||||
return False
|
||||
if not salt.utils.is_windows():
|
||||
return False, 'PowerCFG: Module only works on Windows'
|
||||
return __virtualname__
|
||||
|
||||
|
||||
def _check_or_set(check_func, set_func, value, power):
|
||||
values = check_func()
|
||||
if values[power] == value:
|
||||
return True
|
||||
else:
|
||||
set_func(value, power)
|
||||
return False
|
||||
|
||||
|
||||
def set_timeout(name, value, power="ac", scheme=None):
|
||||
def set_timeout(name, value, power='ac', scheme=None):
|
||||
'''
|
||||
Set the sleep timeouts of specific items such as disk, monitor.
|
||||
Set the sleep timeouts of specific items such as disk, monitor, etc.
|
||||
|
||||
Args:
|
||||
|
||||
name (str)
|
||||
The setting to change, can be one of the following:
|
||||
|
||||
- ``monitor``
|
||||
- ``disk``
|
||||
- ``standby``
|
||||
- ``hibernate``
|
||||
|
||||
value (int):
|
||||
The amount of time in minutes before the item will timeout
|
||||
|
||||
power (str):
|
||||
Set the value for AC or DC power. Default is ``ac``. Valid options
|
||||
are:
|
||||
|
||||
- ``ac`` (AC Power)
|
||||
- ``dc`` (Battery)
|
||||
|
||||
scheme (str):
|
||||
The scheme to use, leave as ``None`` to use the current. Default is
|
||||
``None``. This can be the GUID or the Alias for the Scheme. Known
|
||||
Aliases are:
|
||||
|
||||
- ``SCHEME_BALANCED`` - Balanced
|
||||
- ``SCHEME_MAX`` - Power saver
|
||||
- ``SCHEME_MIN`` - High performance
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Set monitor timeout to 30 minutes on Battery
|
||||
monitor:
|
||||
powercfg.set_timeout:
|
||||
- value: 30
|
||||
- power: dc
|
||||
powercfg.set_timeout:
|
||||
- value: 30
|
||||
- power: dc
|
||||
|
||||
# Set disk timeout to 10 minutes on AC Power
|
||||
disk:
|
||||
powercfg.set_timeout:
|
||||
- value: 12
|
||||
- power: ac
|
||||
|
||||
name
|
||||
The setting to change, can be one of the following: monitor, disk, standby, hibernate
|
||||
|
||||
timeout
|
||||
The amount of time in minutes before the item will timeout i.e the monitor
|
||||
|
||||
power
|
||||
Should we set the value for AC or DC (battery)? Valid options ac,dc.
|
||||
|
||||
scheme
|
||||
The scheme to use, leave as None to use the current.
|
||||
powercfg.set_timeout:
|
||||
- value: 10
|
||||
- power: ac
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}}
|
||||
|
||||
comment = []
|
||||
# Validate name values
|
||||
name = name.lower()
|
||||
if name not in ['monitor', 'disk', 'standby', 'hibernate']:
|
||||
ret['result'] = False
|
||||
ret['comment'] = '"{0}" is not a valid setting'.format(name)
|
||||
log.debug(ret['comment'])
|
||||
return ret
|
||||
|
||||
if name not in ["monitor", "disk", "standby", "hibernate"]:
|
||||
ret["result"] = False
|
||||
comment.append("{0} is not a valid setting".format(name))
|
||||
elif power not in ["ac", "dc"]:
|
||||
ret["result"] = False
|
||||
comment.append("{0} is not a power type".format(power))
|
||||
# Validate power values
|
||||
power = power.lower()
|
||||
if power not in ['ac', 'dc']:
|
||||
ret['result'] = False
|
||||
ret['comment'] = '"{0}" is not a power type'.format(power)
|
||||
log.debug(ret['comment'])
|
||||
return ret
|
||||
|
||||
# Get current settings
|
||||
old = __salt__['powercfg.get_{0}_timeout'.format(name)](scheme=scheme)
|
||||
|
||||
# Check current settings
|
||||
if old[power] == value:
|
||||
ret['comment'] = '{0} timeout on {1} power is already set to {2}' \
|
||||
''.format(name.capitalize(), power.upper(), value)
|
||||
return ret
|
||||
else:
|
||||
check_func = __salt__["powercfg.get_{0}_timeout".format(name)]
|
||||
set_func = __salt__["powercfg.set_{0}_timeout".format(name)]
|
||||
ret['comment'] = '{0} timeout on {1} power will be set to {2}' \
|
||||
''.format(name.capitalize(), power.upper(), value)
|
||||
|
||||
values = check_func(scheme=scheme)
|
||||
if values[power] == value:
|
||||
comment.append("{0} {1} is already set with the value {2}.".format(name, power, value))
|
||||
else:
|
||||
ret['changes'] = {name: {power: value}}
|
||||
set_func(value, power, scheme=scheme)
|
||||
# Check for test=True
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
return ret
|
||||
|
||||
# Set the timeout value
|
||||
__salt__['powercfg.set_{0}_timeout'.format(name)](
|
||||
timeout=value,
|
||||
power=power,
|
||||
scheme=scheme)
|
||||
|
||||
# Get the setting after the change
|
||||
new = __salt__['powercfg.get_{0}_timeout'.format(name)](scheme=scheme)
|
||||
|
||||
changes = salt.utils.compare_dicts(old, new)
|
||||
|
||||
if changes:
|
||||
ret['changes'] = {name: changes}
|
||||
ret['comment'] = '{0} timeout on {1} power set to {2}' \
|
||||
''.format(name.capitalize(), power.upper(), value)
|
||||
log.debug(ret['comment'])
|
||||
else:
|
||||
ret['changes'] = {}
|
||||
ret['comment'] = 'Failed to set {0} timeout on {1} power to {2}' \
|
||||
''.format(name, power.upper(), value)
|
||||
log.debug(ret['comment'])
|
||||
ret['result'] = False
|
||||
|
||||
ret['comment'] = ' '.join(comment)
|
||||
return ret
|
||||
|
|
|
@ -71,10 +71,9 @@ def _init_libcrypto():
|
|||
libcrypto.RSA_public_decrypt.argtypes = (c_int, c_char_p, c_char_p, c_void_p, c_int)
|
||||
|
||||
try:
|
||||
if libcrypto.OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG |
|
||||
OPENSSL_INIT_ADD_ALL_CIPHERS |
|
||||
OPENSSL_INIT_ADD_ALL_DIGESTS, None) != 1:
|
||||
raise OSError("Failed to initialize OpenSSL library (OPENSSL_init_crypto failed)")
|
||||
libcrypto.OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG |
|
||||
OPENSSL_INIT_ADD_ALL_CIPHERS |
|
||||
OPENSSL_INIT_ADD_ALL_DIGESTS, None)
|
||||
except AttributeError:
|
||||
# Support for OpenSSL < 1.1 (OPENSSL_API_COMPAT < 0x10100000L)
|
||||
libcrypto.OPENSSL_no_config()
|
||||
|
|
|
@ -162,20 +162,23 @@ def query(key, keyid, method='GET', params=None, headers=None,
|
|||
headers=headers,
|
||||
data=data,
|
||||
verify=verify_ssl,
|
||||
stream=True)
|
||||
stream=True,
|
||||
timeout=300)
|
||||
elif method == 'GET' and local_file and not return_bin:
|
||||
result = requests.request(method,
|
||||
requesturl,
|
||||
headers=headers,
|
||||
data=data,
|
||||
verify=verify_ssl,
|
||||
stream=True)
|
||||
stream=True,
|
||||
timeout=300)
|
||||
else:
|
||||
result = requests.request(method,
|
||||
requesturl,
|
||||
headers=headers,
|
||||
data=data,
|
||||
verify=verify_ssl)
|
||||
verify=verify_ssl,
|
||||
timeout=300)
|
||||
finally:
|
||||
if fh is not None:
|
||||
fh.close()
|
||||
|
|
|
@ -3,3 +3,7 @@ ssh-file-test:
|
|||
file.managed:
|
||||
- name: /tmp/{{ jinja }}
|
||||
- contents: 'test'
|
||||
|
||||
second_id:
|
||||
cmd.run:
|
||||
- name: echo test
|
||||
|
|
|
@ -200,11 +200,12 @@ class MacServiceModuleTest(ModuleCase):
|
|||
self.assertFalse(
|
||||
self.run_function('service.disabled', [SERVICE_NAME]))
|
||||
|
||||
self.assertTrue(self.run_function('service.stop', [SERVICE_NAME]))
|
||||
self.assertTrue(self.run_function('service.disable', [SERVICE_NAME]))
|
||||
self.assertTrue(
|
||||
self.run_function('service.disabled', [SERVICE_NAME]))
|
||||
self.assertTrue(self.run_function('service.enable', [SERVICE_NAME]))
|
||||
|
||||
self.assertTrue(self.run_function('service.disabled', ['spongebob']))
|
||||
self.assertFalse(self.run_function('service.disabled', ['spongebob']))
|
||||
|
||||
def test_get_all(self):
|
||||
'''
|
||||
|
|
|
@ -11,7 +11,7 @@ import string
|
|||
# Import Salt Testing libs
|
||||
from tests.support.case import ModuleCase
|
||||
from tests.support.unit import skipIf
|
||||
from tests.support.helpers import destructiveTest, skip_if_not_root
|
||||
from tests.support.helpers import destructiveTest, skip_if_not_root, flaky
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils.path
|
||||
|
@ -34,6 +34,7 @@ SET_SUBNET_NAME = __random_string()
|
|||
|
||||
|
||||
@skip_if_not_root
|
||||
@flaky
|
||||
@skipIf(not salt.utils.platform.is_darwin(), 'Test only available on macOS')
|
||||
@skipIf(not salt.utils.path.which('systemsetup'), '\'systemsetup\' binary not found in $PATH')
|
||||
class MacSystemModuleTest(ModuleCase):
|
||||
|
|
|
@ -17,7 +17,7 @@ import datetime
|
|||
# Import Salt Testing libs
|
||||
from tests.support.case import ModuleCase
|
||||
from tests.support.unit import skipIf
|
||||
from tests.support.helpers import destructiveTest, skip_if_not_root
|
||||
from tests.support.helpers import destructiveTest, skip_if_not_root, flaky
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils.path
|
||||
|
@ -28,6 +28,7 @@ from salt.ext import six
|
|||
|
||||
|
||||
@skip_if_not_root
|
||||
@flaky
|
||||
@skipIf(not salt.utils.platform.is_darwin(), 'Test only available on macOS')
|
||||
@skipIf(not salt.utils.path.which('systemsetup'), '\'systemsetup\' binary not found in $PATH')
|
||||
class MacTimezoneModuleTest(ModuleCase):
|
||||
|
|
33
tests/integration/modules/test_win_ip.py
Normal file
33
tests/integration/modules/test_win_ip.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
import re
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.case import ModuleCase
|
||||
from tests.support.unit import skipIf
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils
|
||||
|
||||
|
||||
@skipIf(not salt.utils.is_windows(), 'windows test only')
|
||||
class WinIPTest(ModuleCase):
|
||||
'''
|
||||
Tests for salt.modules.win_ip
|
||||
'''
|
||||
def test_get_default_gateway(self):
|
||||
'''
|
||||
Test getting default gateway
|
||||
'''
|
||||
ip = re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
|
||||
ret = self.run_function('ip.get_default_gateway')
|
||||
assert ip.match(ret)
|
||||
|
||||
def test_ip_is_enabled(self):
|
||||
'''
|
||||
Test ip.is_enabled
|
||||
'''
|
||||
assert self.run_function('ip.is_enabled', ['Ethernet'])
|
||||
assert 'not found' in self.run_function('ip.is_enabled', ['doesnotexist'])
|
84
tests/integration/modules/test_win_pkg.py
Normal file
84
tests/integration/modules/test_win_pkg.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
import textwrap
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.case import ModuleCase
|
||||
from tests.support.unit import skipIf
|
||||
from tests.support.helpers import destructiveTest
|
||||
from tests.support.runtests import RUNTIME_VARS
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils
|
||||
|
||||
CURL = os.path.join(RUNTIME_VARS.FILES, 'file', 'base', 'win', 'repo-ng', 'curl.sls')
|
||||
|
||||
|
||||
@skipIf(not salt.utils.is_windows(), 'windows test only')
|
||||
class WinPKGTest(ModuleCase):
|
||||
'''
|
||||
Tests for salt.modules.win_pkg. There are already
|
||||
some pkg execution module tests in the the test
|
||||
integration.modules.test_pkg but this will be for
|
||||
specific windows software respository tests while
|
||||
using the win_pkg module.
|
||||
'''
|
||||
@destructiveTest
|
||||
def test_adding_removing_pkg_sls(self):
|
||||
'''
|
||||
Test add and removing a new pkg sls
|
||||
in the windows software repository
|
||||
'''
|
||||
def _check_pkg(pkgs, exists=True):
|
||||
self.run_function('pkg.refresh_db')
|
||||
repo_data = self.run_function('pkg.get_repo_data')
|
||||
repo_cache = os.path.join(RUNTIME_VARS.TMP, 'rootdir', 'cache', 'files', 'base', 'win', 'repo-ng')
|
||||
for pkg in pkgs:
|
||||
if exists:
|
||||
assert pkg in str(repo_data)
|
||||
else:
|
||||
assert pkg not in str(repo_data)
|
||||
|
||||
for root, dirs, files in os.walk(repo_cache):
|
||||
if exists:
|
||||
assert pkg + '.sls' in files
|
||||
else:
|
||||
assert pkg + '.sls' not in files
|
||||
|
||||
pkgs = ['putty', '7zip']
|
||||
# check putty and 7zip are in cache and repo query
|
||||
_check_pkg(pkgs)
|
||||
|
||||
# now add new sls
|
||||
with salt.utils.fopen(CURL, 'w') as fp_:
|
||||
fp_.write(textwrap.dedent('''
|
||||
curl:
|
||||
'7.46.0':
|
||||
full_name: 'cURL'
|
||||
{% if grains['cpuarch'] == 'AMD64' %}
|
||||
installer: 'salt://win/repo-ng/curl/curl-7.46.0-win64.msi'
|
||||
uninstaller: 'salt://win/repo-ng/curl/curl-7.46.0-win64.msi'
|
||||
{% else %}
|
||||
installer: 'salt://win/repo-ng/curl/curl-7.46.0-win32.msi'
|
||||
uninstaller: 'salt://win/repo-ng/curl/curl-7.46.0-win32.msi'
|
||||
{% endif %}
|
||||
install_flags: '/qn /norestart'
|
||||
uninstall_flags: '/qn /norestart'
|
||||
msiexec: True
|
||||
locale: en_US
|
||||
reboot: False
|
||||
'''))
|
||||
# now check if curl is also in cache and repo query
|
||||
pkgs.append('curl')
|
||||
_check_pkg(pkgs)
|
||||
|
||||
# remove curl sls and check its not in cache and repo query
|
||||
os.remove(CURL)
|
||||
_check_pkg(['curl'], exists=False)
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.isfile(CURL):
|
||||
os.remove(CURL)
|
|
@ -27,11 +27,14 @@ class SSHStateTest(SSHCase):
|
|||
'''
|
||||
testing the state system with salt-ssh
|
||||
'''
|
||||
def _check_dict_ret(self, ret, val, exp_ret):
|
||||
def _check_dict_ret(self, ret, val, exp_ret, equal=True):
|
||||
self.assertIsInstance(ret, dict)
|
||||
for key, value in ret.items():
|
||||
self.assertIsInstance(value, dict)
|
||||
self.assertEqual(value[val], exp_ret)
|
||||
if equal:
|
||||
self.assertEqual(value[val], exp_ret)
|
||||
else:
|
||||
self.assertNotEqual(value[val], exp_ret)
|
||||
|
||||
def _check_request(self, empty=False):
|
||||
check = self.run_function('state.check_request', wipe=False)
|
||||
|
@ -55,12 +58,31 @@ class SSHStateTest(SSHCase):
|
|||
'''
|
||||
test state.sls_id with salt-ssh
|
||||
'''
|
||||
# check state.sls_id with test=True
|
||||
ret = self.run_function('state.sls_id', ['ssh-file-test', SSH_SLS,
|
||||
'test=True'])
|
||||
self._check_dict_ret(ret=ret, val='comment',
|
||||
exp_ret='The file /tmp/test is set to be changed')
|
||||
|
||||
# check state.sls_id without test=True
|
||||
ret = self.run_function('state.sls_id', ['ssh-file-test', SSH_SLS])
|
||||
self._check_dict_ret(ret=ret, val='__sls__', exp_ret=SSH_SLS)
|
||||
|
||||
# make sure the other id in the state was not run
|
||||
self._check_dict_ret(ret=ret, val='__id__',
|
||||
exp_ret='second_id', equal=False)
|
||||
|
||||
check_file = self.run_function('file.file_exists', ['/tmp/test'])
|
||||
self.assertTrue(check_file)
|
||||
|
||||
def test_state_sls_wrong_id(self):
|
||||
'''
|
||||
test state.sls_id when id does not exist
|
||||
'''
|
||||
# check state.sls_id with test=True
|
||||
ret = self.run_function('state.sls_id', ['doesnotexist', SSH_SLS])
|
||||
assert 'No matches for ID' in ret
|
||||
|
||||
def test_state_show_sls(self):
|
||||
'''
|
||||
test state.show_sls with salt-ssh
|
||||
|
|
|
@ -22,6 +22,11 @@ from tests.support.mixins import SaltReturnAssertsMixin
|
|||
# Import Salt libs
|
||||
import salt.utils.platform
|
||||
|
||||
try:
|
||||
import grp
|
||||
except ImportError:
|
||||
grp = None
|
||||
|
||||
if salt.utils.platform.is_darwin():
|
||||
USER = 'macuser'
|
||||
GROUP = 'macuser'
|
||||
|
@ -32,13 +37,11 @@ elif salt.utils.platform.is_windows():
|
|||
GROUP = 'winuser'
|
||||
GID = randint(400, 500)
|
||||
NOGROUPGID = randint(400, 500)
|
||||
grp = None
|
||||
else:
|
||||
USER = 'nobody'
|
||||
GROUP = 'nobody'
|
||||
GID = 'nobody'
|
||||
NOGROUPGID = 'nogroup'
|
||||
import grp
|
||||
|
||||
|
||||
@destructiveTest
|
||||
|
|
|
@ -14,6 +14,7 @@ import logging
|
|||
import os
|
||||
import shutil
|
||||
import signal
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
@ -590,8 +591,24 @@ class TestSaltProgram(six.with_metaclass(TestSaltProgramMeta, TestProgram)):
|
|||
'log_dir',
|
||||
'script_dir',
|
||||
])
|
||||
|
||||
pub_port = 4505
|
||||
ret_port = 4506
|
||||
for port in [pub_port, ret_port]:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
connect = sock.bind(('localhost', port))
|
||||
except:
|
||||
# these ports are already in use, use different ones
|
||||
pub_port = 4606
|
||||
ret_port = 4607
|
||||
break
|
||||
sock.close()
|
||||
|
||||
config_base = {
|
||||
'root_dir': '{test_dir}',
|
||||
'publish_port': pub_port,
|
||||
'ret_port': ret_port,
|
||||
}
|
||||
configs = {}
|
||||
config_dir = os.path.join('etc', 'salt')
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
# Import Python Libs
|
||||
from __future__ import absolute_import, unicode_literals, print_function
|
||||
import textwrap
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
|
@ -34,43 +35,87 @@ class NpmTestCase(TestCase, LoaderModuleMockMixin):
|
|||
self.addCleanup(patcher.stop)
|
||||
return {npm: {}}
|
||||
|
||||
# 'install' function tests: 1
|
||||
# 'install' function tests: 4
|
||||
|
||||
def test_install(self):
|
||||
'''
|
||||
Test if it install an NPM package.
|
||||
Test if it installs an NPM package.
|
||||
'''
|
||||
mock = MagicMock(return_value={'retcode': 1, 'stderr': 'error'})
|
||||
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
|
||||
self.assertRaises(CommandExecutionError, npm.install,
|
||||
'coffee-script')
|
||||
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stderr': 'error',
|
||||
'stdout': '{"salt": ["SALT"]}'})
|
||||
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
|
||||
mock_err = MagicMock(return_value='SALT')
|
||||
with patch.object(salt.utils.json, 'loads', mock_err):
|
||||
self.assertEqual(npm.install('coffee-script'), 'SALT')
|
||||
# This is at least somewhat closer to the actual output format.
|
||||
mock_json_out = textwrap.dedent('''\
|
||||
[
|
||||
{
|
||||
"salt": "SALT"
|
||||
}
|
||||
]''')
|
||||
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stderr': 'error',
|
||||
'stdout': '{"salt": ["SALT"]}'})
|
||||
# Successful run, expected output format
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stderr': '',
|
||||
'stdout': mock_json_out})
|
||||
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
|
||||
self.assertEqual(npm.install('coffee-script'),
|
||||
[{u'salt': u'SALT'}])
|
||||
|
||||
mock_json_out_extra = textwrap.dedent('''\
|
||||
Compilation output here
|
||||
|
||||
[bcrypt] Success: "/tmp/node_modules/bcrypt/foo" is installed via remote"
|
||||
[grpc] Success: "/usr/lib/node_modules/@foo/bar" is installed via remote"
|
||||
[
|
||||
{
|
||||
"from" : "express@",
|
||||
"name" : "express",
|
||||
"dependencies" : {
|
||||
"escape-html" : {
|
||||
"from" : "escape-html@~1.0.3",
|
||||
"dependencies" : {},
|
||||
"version" : "1.0.3"
|
||||
}
|
||||
},
|
||||
"version" : "4.16.3"
|
||||
}
|
||||
]''')
|
||||
extra_expected = [{u'dependencies':
|
||||
{u'escape-html': {
|
||||
u'dependencies': {},
|
||||
u'from': u'escape-html@~1.0.3',
|
||||
u'version': u'1.0.3'}
|
||||
},
|
||||
u'from': u'express@',
|
||||
u'name': u'express',
|
||||
u'version': u'4.16.3'}]
|
||||
|
||||
# Successful run, expected output format with additional leading text
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stderr': '',
|
||||
'stdout': mock_json_out_extra})
|
||||
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
|
||||
self.assertEqual(npm.install('coffee-script'), extra_expected)
|
||||
|
||||
# Successful run, unexpected output format
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stderr': '',
|
||||
'stdout': 'SALT'})
|
||||
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
|
||||
mock_err = MagicMock(side_effect=ValueError())
|
||||
# When JSON isn't successfully parsed, return should equal input
|
||||
with patch.object(salt.utils.json, 'loads', mock_err):
|
||||
self.assertEqual(npm.install('coffee-script'),
|
||||
'{"salt": ["SALT"]}')
|
||||
self.assertEqual(npm.install('coffee-script'), 'SALT')
|
||||
|
||||
# 'uninstall' function tests: 1
|
||||
|
||||
def test_uninstall(self):
|
||||
'''
|
||||
Test if it uninstall an NPM package.
|
||||
Test if it uninstalls an NPM package.
|
||||
'''
|
||||
mock = MagicMock(return_value={'retcode': 1, 'stderr': 'error'})
|
||||
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
|
||||
self.assertFalse(npm.uninstall('coffee-script'))
|
||||
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stderr': 'error'})
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stderr': ''})
|
||||
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
|
||||
self.assertTrue(npm.uninstall('coffee-script'))
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ from tests.support.mock import (
|
|||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
|
||||
'''
|
||||
Validate the powercfg state
|
||||
Validate the powercfg state
|
||||
'''
|
||||
|
||||
def setup_loader_modules(self):
|
||||
|
@ -40,76 +40,103 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
|
|||
|
||||
def test_set_monitor_timeout(self):
|
||||
'''
|
||||
Test to make sure we can set the monitor timeout value
|
||||
Test to make sure we can set the monitor timeout value
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
|
||||
mock = MagicMock(return_value=0)
|
||||
mock.side_effect = [
|
||||
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
|
||||
self.query_output]
|
||||
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
powercfg.set_monitor_timeout(0, "dc")
|
||||
calls = [
|
||||
call('powercfg /getactivescheme', python_shell=False),
|
||||
call('powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_VIDEO VIDEOIDLE 0', python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock_retcode}):
|
||||
powercfg.set_monitor_timeout(0, 'dc')
|
||||
mock.assert_called_once_with(
|
||||
'powercfg /getactivescheme',
|
||||
python_shell=False)
|
||||
mock_retcode.assert_called_once_with(
|
||||
'powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_VIDEO VIDEOIDLE 0',
|
||||
python_shell=False)
|
||||
|
||||
def test_set_disk_timeout(self):
|
||||
'''
|
||||
Test to make sure we can set the disk timeout value
|
||||
Test to make sure we can set the disk timeout value
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
|
||||
mock.side_effect = [
|
||||
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
|
||||
self.query_output]
|
||||
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
powercfg.set_disk_timeout(0, "dc")
|
||||
calls = [
|
||||
call('powercfg /getactivescheme', python_shell=False),
|
||||
call('powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK DISKIDLE 0', python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock_retcode}):
|
||||
powercfg.set_disk_timeout(0, 'dc')
|
||||
mock.assert_called_once_with(
|
||||
'powercfg /getactivescheme',
|
||||
python_shell=False)
|
||||
mock_retcode.assert_called_once_with(
|
||||
'powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK DISKIDLE 0',
|
||||
python_shell=False)
|
||||
|
||||
def test_set_standby_timeout(self):
|
||||
'''
|
||||
Test to make sure we can set the standby timeout value
|
||||
Test to make sure we can set the standby timeout value
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
|
||||
mock = MagicMock(return_value=0)
|
||||
mock.side_effect = [
|
||||
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
|
||||
self.query_output]
|
||||
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
powercfg.set_standby_timeout(0, "dc")
|
||||
calls = [
|
||||
call('powercfg /getactivescheme', python_shell=False),
|
||||
call('powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP STANDBYIDLE 0', python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock_retcode}):
|
||||
powercfg.set_standby_timeout(0, 'dc')
|
||||
mock.assert_called_once_with(
|
||||
'powercfg /getactivescheme',
|
||||
python_shell=False)
|
||||
mock_retcode.assert_called_once_with(
|
||||
'powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP STANDBYIDLE 0',
|
||||
python_shell=False)
|
||||
|
||||
def test_set_hibernate_timeout(self):
|
||||
'''
|
||||
Test to make sure we can set the hibernate timeout value
|
||||
Test to make sure we can set the hibernate timeout value
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
|
||||
mock = MagicMock(return_value=0)
|
||||
mock.side_effect = [
|
||||
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
|
||||
self.query_output]
|
||||
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
powercfg.set_hibernate_timeout(0, "dc")
|
||||
calls = [
|
||||
call('powercfg /getactivescheme', python_shell=False),
|
||||
call('powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP HIBERNATEIDLE 0', python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock_retcode}):
|
||||
powercfg.set_hibernate_timeout(0, 'dc')
|
||||
mock.assert_called_once_with(
|
||||
'powercfg /getactivescheme',
|
||||
python_shell=False)
|
||||
mock_retcode.assert_called_once_with(
|
||||
'powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP HIBERNATEIDLE 0',
|
||||
python_shell=False)
|
||||
|
||||
def test_get_monitor_timeout(self):
|
||||
'''
|
||||
Test to make sure we can get the monitor timeout value
|
||||
Test to make sure we can get the monitor timeout value
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
|
||||
mock.side_effect = [
|
||||
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
|
||||
self.query_output]
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
ret = powercfg.get_monitor_timeout()
|
||||
calls = [
|
||||
call('powercfg /getactivescheme', python_shell=False),
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_VIDEO VIDEOIDLE', python_shell=False)
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_VIDEO VIDEOIDLE',
|
||||
python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
|
||||
|
@ -117,16 +144,19 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
|
|||
|
||||
def test_get_disk_timeout(self):
|
||||
'''
|
||||
Test to make sure we can get the disk timeout value
|
||||
Test to make sure we can get the disk timeout value
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
|
||||
mock.side_effect = [
|
||||
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
|
||||
self.query_output]
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
ret = powercfg.get_disk_timeout()
|
||||
calls = [
|
||||
call('powercfg /getactivescheme', python_shell=False),
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK DISKIDLE', python_shell=False)
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK DISKIDLE',
|
||||
python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
|
||||
|
@ -134,16 +164,19 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
|
|||
|
||||
def test_get_standby_timeout(self):
|
||||
'''
|
||||
Test to make sure we can get the standby timeout value
|
||||
Test to make sure we can get the standby timeout value
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
|
||||
mock.side_effect = [
|
||||
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
|
||||
self.query_output]
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
ret = powercfg.get_standby_timeout()
|
||||
calls = [
|
||||
call('powercfg /getactivescheme', python_shell=False),
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP STANDBYIDLE', python_shell=False)
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP STANDBYIDLE',
|
||||
python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
|
||||
|
@ -151,16 +184,19 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
|
|||
|
||||
def test_get_hibernate_timeout(self):
|
||||
'''
|
||||
Test to make sure we can get the hibernate timeout value
|
||||
Test to make sure we can get the hibernate timeout value
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
|
||||
mock.side_effect = [
|
||||
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
|
||||
self.query_output]
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
ret = powercfg.get_hibernate_timeout()
|
||||
calls = [
|
||||
call('powercfg /getactivescheme', python_shell=False),
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP HIBERNATEIDLE', python_shell=False)
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP HIBERNATEIDLE',
|
||||
python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
|
||||
|
@ -168,17 +204,20 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
|
|||
|
||||
def test_windows_7(self):
|
||||
'''
|
||||
Test to make sure we can get the hibernate timeout value on windows 7
|
||||
Test to make sure we can get the hibernate timeout value on windows 7
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
|
||||
mock.side_effect = [
|
||||
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
|
||||
self.query_output]
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
with patch.dict(powercfg.__grains__, {'osrelease': '7'}):
|
||||
ret = powercfg.get_hibernate_timeout()
|
||||
calls = [
|
||||
call('powercfg /getactivescheme', python_shell=False),
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP', python_shell=False)
|
||||
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP',
|
||||
python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
|
||||
|
@ -186,30 +225,29 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
|
|||
|
||||
def test_set_hibernate_timeout_scheme(self):
|
||||
'''
|
||||
Test to make sure we can set the hibernate timeout value
|
||||
Test to make sure we can set the hibernate timeout value
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock = MagicMock(return_value=0)
|
||||
mock.side_effect = [self.query_output]
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
powercfg.set_hibernate_timeout(0, "dc", scheme="SCHEME_MIN")
|
||||
calls = [
|
||||
call('powercfg /setdcvalueindex SCHEME_MIN SUB_SLEEP HIBERNATEIDLE 0', python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock}):
|
||||
powercfg.set_hibernate_timeout(0, 'dc', scheme='SCHEME_MIN')
|
||||
mock.assert_called_once_with(
|
||||
'powercfg /setdcvalueindex SCHEME_MIN SUB_SLEEP HIBERNATEIDLE 0',
|
||||
python_shell=False)
|
||||
|
||||
def test_get_hibernate_timeout_scheme(self):
|
||||
'''
|
||||
Test to make sure we can get the hibernate timeout value with a specified scheme
|
||||
Test to make sure we can get the hibernate timeout value with a
|
||||
specified scheme
|
||||
'''
|
||||
mock = MagicMock()
|
||||
mock.side_effect = [self.query_output]
|
||||
|
||||
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
|
||||
ret = powercfg.get_hibernate_timeout(scheme="SCHEME_MIN")
|
||||
calls = [
|
||||
call('powercfg /q SCHEME_MIN SUB_SLEEP HIBERNATEIDLE', python_shell=False)
|
||||
]
|
||||
mock.assert_has_calls(calls)
|
||||
ret = powercfg.get_hibernate_timeout(scheme='SCHEME_MIN')
|
||||
mock.assert_called_once_with(
|
||||
'powercfg /q SCHEME_MIN SUB_SLEEP HIBERNATEIDLE',
|
||||
python_shell=False)
|
||||
|
||||
self.assertEqual({'ac': 30, 'dc': 15}, ret)
|
||||
|
|
|
@ -362,6 +362,7 @@ class ZypperTestCase(TestCase, LoaderModuleMockMixin):
|
|||
ZyppCallMock(return_value=get_test_data('zypper-available.txt'))), \
|
||||
patch('salt.modules.zypper.refresh_db', MagicMock(return_value=True)):
|
||||
self.assertEqual(zypper.latest_version('vim'), '7.4.326-2.62')
|
||||
self.assertDictEqual(zypper.latest_version('vim', 'fakepkg'), {'vim': '7.4.326-2.62', 'fakepkg': ''})
|
||||
|
||||
def test_upgrade_success(self):
|
||||
'''
|
||||
|
|
|
@ -59,6 +59,15 @@ class TestFileState(TestCase, LoaderModuleMockMixin):
|
|||
}
|
||||
}
|
||||
|
||||
def tearDown(self):
|
||||
remove_dir = '/tmp/etc'
|
||||
if salt.utils.is_windows():
|
||||
remove_dir = 'c:\\tmp\\etc'
|
||||
try:
|
||||
salt.utils.rm_rf(remove_dir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def test_serialize(self):
|
||||
def returner(contents, *args, **kwargs):
|
||||
returner.returned = contents
|
||||
|
@ -1177,9 +1186,10 @@ class TestFileState(TestCase, LoaderModuleMockMixin):
|
|||
'''
|
||||
Test to ensure that some text appears at the beginning of a file.
|
||||
'''
|
||||
name = '/etc/motd'
|
||||
name = '/tmp/etc/motd'
|
||||
if salt.utils.platform.is_windows():
|
||||
name = 'c:\\etc\\motd'
|
||||
name = 'c:\\tmp\\etc\\motd'
|
||||
assert not os.path.exists(os.path.split(name)[0])
|
||||
source = ['salt://motd/hr-messages.tmpl']
|
||||
sources = ['salt://motd/devops-messages.tmpl']
|
||||
text = ['Trust no one unless you have eaten much salt with him.']
|
||||
|
@ -1205,16 +1215,15 @@ class TestFileState(TestCase, LoaderModuleMockMixin):
|
|||
{'file.directory_exists': mock_f,
|
||||
'file.makedirs': mock_t,
|
||||
'file.stats': mock_f,
|
||||
'file.touch': mock_t,
|
||||
'cp.get_template': mock_f,
|
||||
'file.search': mock_f,
|
||||
'file.prepend': mock_t}):
|
||||
comt = ('The following files will be changed:\n/etc:'
|
||||
comt = ('The following files will be changed:\n/tmp/etc:'
|
||||
' directory - new\n')
|
||||
pchanges = {'/etc': {'directory': 'new'}}
|
||||
pchanges = {'/tmp/etc': {'directory': 'new'}}
|
||||
if salt.utils.platform.is_windows():
|
||||
comt = 'The directory "c:\\etc" will be changed'
|
||||
pchanges = {'c:\\etc': {'directory': 'new'}}
|
||||
comt = 'The directory "c:\\tmp\\etc" will be changed'
|
||||
pchanges = {'c:\\tmp\\etc': {'directory': 'new'}}
|
||||
ret.update({'comment': comt, 'name': name, 'pchanges': pchanges})
|
||||
self.assertDictEqual(filestate.prepend(name, makedirs=True),
|
||||
ret)
|
||||
|
|
|
@ -27,36 +27,71 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
|
|||
|
||||
def test_set_monitor(self):
|
||||
'''
|
||||
Test to make sure we can set the monitor timeout value
|
||||
Test to make sure we can set the monitor timeout value
|
||||
'''
|
||||
ret = {'changes': {'monitor': {'ac': 0}}, 'comment': '', 'name': 'monitor', 'result': True}
|
||||
monitor_val = {"ac": 45, "dc": 22}
|
||||
with patch.dict(powercfg.__salt__, {"powercfg.get_monitor_timeout": MagicMock(return_value=monitor_val),
|
||||
"powercfg.set_monitor_timeout": MagicMock(return_value=True)}):
|
||||
|
||||
self.assertEqual(powercfg.set_timeout("monitor", 0), ret)
|
||||
ret = {
|
||||
'changes': {
|
||||
'monitor': {
|
||||
'ac': {
|
||||
'new': 0,
|
||||
'old': 45
|
||||
}
|
||||
}
|
||||
},
|
||||
'comment': 'Monitor timeout on AC power set to 0',
|
||||
'name': 'monitor',
|
||||
'result': True}
|
||||
get_monitor_side_effect = MagicMock(side_effect=[{"ac": 45, "dc": 22},
|
||||
{"ac": 0, "dc": 22}])
|
||||
with patch.dict(powercfg.__salt__,
|
||||
{"powercfg.get_monitor_timeout": get_monitor_side_effect,
|
||||
"powercfg.set_monitor_timeout": MagicMock(return_value=True)}):
|
||||
with patch.dict(powercfg.__opts__, {"test": False}):
|
||||
self.assertEqual(powercfg.set_timeout("monitor", 0), ret)
|
||||
|
||||
def test_set_monitor_already_set(self):
|
||||
'''
|
||||
Test to make sure we can set the monitor timeout value
|
||||
Test to make sure we can set the monitor timeout value
|
||||
'''
|
||||
ret = {'changes': {}, 'comment': 'monitor ac is already set with the value 0.', 'name': 'monitor', 'result': True}
|
||||
monitor_val = {"ac": 0, "dc": 0}
|
||||
with patch.dict(powercfg.__salt__, {"powercfg.get_monitor_timeout": MagicMock(return_value=monitor_val),
|
||||
"powercfg.set_monitor_timeout": MagicMock(return_value=True)}):
|
||||
|
||||
ret = {'changes': {},
|
||||
'comment': 'Monitor timeout on AC power is already set to 0',
|
||||
'name': 'monitor',
|
||||
'result': True}
|
||||
monitor_val = MagicMock(return_value={"ac": 0, "dc": 0})
|
||||
with patch.dict(powercfg.__salt__, {"powercfg.get_monitor_timeout": monitor_val}):
|
||||
self.assertEqual(powercfg.set_timeout("monitor", 0), ret)
|
||||
|
||||
def test_set_monitor_test_true_with_change(self):
|
||||
'''
|
||||
Test to make sure set monitor works correctly with test=True with
|
||||
changes
|
||||
'''
|
||||
ret = {'changes': {},
|
||||
'comment': 'Monitor timeout on AC power will be set to 0',
|
||||
'name': 'monitor',
|
||||
'result': None}
|
||||
get_monitor_return_value = MagicMock(return_value={"ac": 45, "dc": 22})
|
||||
with patch.dict(powercfg.__salt__, {"powercfg.get_monitor_timeout": get_monitor_return_value}):
|
||||
with patch.dict(powercfg.__opts__, {"test": True}):
|
||||
self.assertEqual(powercfg.set_timeout("monitor", 0), ret)
|
||||
|
||||
def test_fail_invalid_setting(self):
|
||||
'''
|
||||
Test to make sure we can set the monitor timeout value
|
||||
Test to make sure we can set the monitor timeout value
|
||||
'''
|
||||
ret = {'changes': {}, 'comment': 'fakesetting is not a valid setting', 'name': 'fakesetting', 'result': False}
|
||||
ret = {'changes': {},
|
||||
'comment': '"fakesetting" is not a valid setting',
|
||||
'name': 'fakesetting',
|
||||
'result': False}
|
||||
self.assertEqual(powercfg.set_timeout("fakesetting", 0), ret)
|
||||
|
||||
def test_fail_invalid_power(self):
|
||||
'''
|
||||
Test to make sure we can set the monitor timeout value
|
||||
Test to make sure we can set the monitor timeout value
|
||||
'''
|
||||
ret = {'changes': {}, 'comment': 'fakepower is not a power type', 'name': 'monitor', 'result': False}
|
||||
self.assertEqual(powercfg.set_timeout("monitor", 0, power="fakepower"), ret)
|
||||
ret = {'changes': {},
|
||||
'comment': '"fakepower" is not a power type',
|
||||
'name': 'monitor',
|
||||
'result': False}
|
||||
self.assertEqual(powercfg.set_timeout("monitor", 0, power="fakepower"),
|
||||
ret)
|
||||
|
|
|
@ -30,6 +30,7 @@ integration.modules.test_system
|
|||
integration.modules.test_test
|
||||
integration.modules.test_useradd
|
||||
integration.modules.test_win_dns_client
|
||||
integration.modules.test_win_pkg
|
||||
integration.reactor.test_reactor
|
||||
integration.renderers.test_pydsl
|
||||
integration.returners.test_librato_return
|
||||
|
|
Loading…
Add table
Reference in a new issue