Merge branch '2014.7' into develop

Conflicts:
	salt/modules/hg.py
This commit is contained in:
Colton Myers 2014-10-31 16:14:34 -06:00
commit 0cc0d64136
12 changed files with 323 additions and 112 deletions

Binary file not shown.

View file

@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
'''
A module to wrap archive calls
A module to wrap (non-Windows) archive calls
.. versionadded:: 2014.1.0
'''
# Import salt libs
import salt._compat
from salt.utils import which as _which, which_bin as _which_bin
from salt.utils import \
which as _which, which_bin as _which_bin, is_windows as _is_windows
import salt.utils.decorators as decorators
# TODO: Check that the passed arguments are correct
@ -19,6 +20,8 @@ __func_alias__ = {
def __virtual__():
if _is_windows():
return False
commands = ('tar', 'gzip', 'gunzip', 'zip', 'unzip', 'rar', 'unrar')
# If none of the above commands are in $PATH this module is a no-go
if not any(_which(cmd) for cmd in commands):

View file

@ -141,15 +141,16 @@ def assign(name, value):
cmd = 'sysctl -w {0}="{1}"'.format(name, value)
data = __salt__['cmd.run_all'](cmd)
out = data['stdout']
err = data['stderr']
# Example:
# # sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
# net.ipv4.tcp_rmem = 4096 87380 16777216
regex = re.compile(r'^{0}\s+=\s+{1}$'.format(re.escape(name), re.escape(value)))
if not regex.match(out):
if data['retcode'] != 0 and data['stderr']:
error = data['stderr']
if not regex.match(out) or 'Invalid argument' in str(err):
if data['retcode'] != 0 and err:
error = err
else:
error = out
raise CommandExecutionError('sysctl -w failed: {0}'.format(error))

View file

@ -70,14 +70,14 @@ def getenforce():
salt '*' selinux.getenforce
'''
enforce = os.path.join(selinux_fs_path(), 'enforce')
try:
enforce = os.path.join(selinux_fs_path(), 'enforce')
with salt.utils.fopen(enforce, 'r') as _fp:
if _fp.readline().strip() == '0':
return 'Permissive'
else:
return 'Enforcing'
except (IOError, OSError) as exc:
except (IOError, OSError, AttributeError) as exc:
msg = 'Could not read SELinux enforce file: {0}'
raise CommandExecutionError(msg.format(str(exc)))

View file

@ -349,7 +349,7 @@ def _strip_clean(returns):
'''
rm_tags = []
for tag in returns:
if not isinstance(tag, dict):
if isinstance(tag, dict):
continue
if returns[tag]['result'] and not returns[tag]['changes']:
rm_tags.append(tag)

View file

@ -1577,7 +1577,7 @@ class State(object):
finish_time = datetime.datetime.now()
ret['start_time'] = start_time.time().isoformat()
delta = (finish_time - start_time)
#duration in milliseconds.microseconds
# duration in milliseconds.microseconds
ret['duration'] = (delta.seconds * 1000000 + delta.microseconds)/1000.0
log.info('Completed state [{0}] at time {1}'.format(low['name'], finish_time.time().isoformat()))
return ret
@ -1706,7 +1706,8 @@ class State(object):
elif 'pre' in fun_stats:
if 'premet' in fun_stats:
status = 'met'
status = 'pre'
else:
status = 'pre'
elif 'onfail' in fun_stats:
status = 'onfail'
elif 'onchanges' in fun_stats:

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
'''
Archive states.
Extract an archive
.. versionadded:: 2014.1.0
'''
@ -12,6 +12,17 @@ from contextlib import closing
log = logging.getLogger(__name__)
__virtualname__ = 'archive'
def __virtual__():
'''
Only load if the npm module is available in __salt__
'''
return __virtualname__ \
if [x for x in __salt__ if x.startswith('archive.')] \
else False
def extracted(name,
source,
@ -95,7 +106,7 @@ def extracted(name,
if archive_format not in valid_archives:
ret['result'] = False
ret['comment'] = '{0} is not supported, valids: {1}'.format(
ret['comment'] = '{0} is not supported, valid formats are: {1}'.format(
archive_format, ','.join(valid_archives))
return ret

View file

@ -8,6 +8,7 @@ import subprocess
# Import salt libs
import salt.utils
import salt.modules.selinux
from salt.exceptions import CommandExecutionError
def recursive_copy(source, dest):
@ -72,7 +73,7 @@ def copyfile(source, dest, backup_mode='', cachedir=''):
policy = False
try:
policy = salt.modules.selinux.getenforce()
except ImportError:
except (ImportError, CommandExecutionError):
pass
if policy == 'Enforcing':
with salt.utils.fopen(os.devnull, 'w') as dev_null:

View file

@ -0,0 +1,24 @@
# A --+
# |
# B <-+ ----+
# |
# C <-------+
# runs before A and/or B
A:
cmd.run:
- name: echo A first
# is running in test mode before B/C
- prereq:
- cmd: B
- cmd: C
# always has to run
B:
cmd.run:
- name: echo B second
# never has to run
C:
cmd.wait:
- name: echo C third

View file

@ -373,73 +373,81 @@ fi
'cmd_|-A_|-echo A_|-run': {
'__run_num__': 2,
'comment': 'Command "echo A" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-B_|-echo B_|-run': {
'__run_num__': 1,
'comment': 'Command "echo B" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-C_|-echo C_|-run': {
'__run_num__': 0,
'comment': 'Command "echo C" run',
'result': True}
'result': True,
'changes': True}
}
expected_result = {
'cmd_|-A_|-echo A fifth_|-run': {
'__run_num__': 4,
'comment': 'Command "echo A fifth" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-B_|-echo B third_|-run': {
'__run_num__': 2,
'comment': 'Command "echo B third" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-C_|-echo C second_|-run': {
'__run_num__': 1,
'comment': 'Command "echo C second" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-D_|-echo D first_|-run': {
'__run_num__': 0,
'comment': 'Command "echo D first" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-E_|-echo E fourth_|-run': {
'__run_num__': 3,
'comment': 'Command "echo E fourth" run',
'result': True}
'result': True,
'changes': True}
}
expected_req_use_result = {
'cmd_|-A_|-echo A_|-run': {
'__run_num__': 1,
'comment': 'Command "echo A" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-B_|-echo B_|-run': {
'__run_num__': 4,
'comment': 'Command "echo B" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-C_|-echo C_|-run': {
'__run_num__': 0,
'comment': 'Command "echo C" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-D_|-echo D_|-run': {
'__run_num__': 5,
'comment': 'Command "echo D" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-E_|-echo E_|-run': {
'__run_num__': 2,
'comment': 'Command "echo E" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-F_|-echo F_|-run': {
'__run_num__': 3,
'comment': 'Command "echo F" run',
'result': True}
'result': True,
'changes': True}
}
result = {}
ret = self.run_function('state.sls', mods='requisites.mixed_simple')
result = self.normalize_ret(ret)
self.assertReturnNonEmptySaltType(ret)
for item, descr in ret.iteritems():
result[item] = {
'__run_num__': descr['__run_num__'],
'comment': descr['comment'],
'result': descr['result']
}
self.assertEqual(expected_simple_result, result)
# test Traceback recursion prereq+require #8785
@ -468,16 +476,24 @@ fi
# undetected infinite loopS prevents this test from running...
# TODO: this is actually failing badly
#result = {}
#ret = self.run_function('state.sls', mods='requisites.mixed_complex1')
#for item, descr in ret.iteritems():
# result[item] = {
# '__run_num__': descr['__run_num__'],
# 'comment': descr['comment'],
# 'result': descr['result']
# }
#result = self.normalize_ret(ret)
#self.assertEqual(expected_result, result)
def normalize_ret(self, ret):
'''
Normalize the return to the format that we'll use for result checking
'''
result = {}
for item, descr in ret.iteritems():
result[item] = {
'__run_num__': descr['__run_num__'],
'comment': descr['comment'],
'result': descr['result'],
'changes': descr['changes'] != {} # whether there where any changes
}
return result
def test_requisites_require_ordering_and_errors(self):
'''
Call sls file containing several require_in and require.
@ -488,59 +504,61 @@ fi
'cmd_|-A_|-echo A fifth_|-run': {
'__run_num__': 4,
'comment': 'Command "echo A fifth" run',
'result': True
'result': True,
'changes': True,
},
'cmd_|-B_|-echo B second_|-run': {
'__run_num__': 1,
'comment': 'Command "echo B second" run',
'result': True
'result': True,
'changes': True,
},
'cmd_|-C_|-echo C third_|-run': {
'__run_num__': 2,
'comment': 'Command "echo C third" run',
'result': True
'result': True,
'changes': True,
},
'cmd_|-D_|-echo D first_|-run': {
'__run_num__': 0,
'comment': 'Command "echo D first" run',
'result': True
'result': True,
'changes': True,
},
'cmd_|-E_|-echo E fourth_|-run': {
'__run_num__': 3,
'comment': 'Command "echo E fourth" run',
'result': True
'result': True,
'changes': True,
},
'cmd_|-F_|-echo F_|-run': {
'__run_num__': 5,
'comment': 'The following requisites were not found:\n'
+ ' require:\n'
+ ' foobar: A\n',
'result': False
'result': False,
'changes': False,
},
'cmd_|-G_|-echo G_|-run': {
'__run_num__': 6,
'comment': 'The following requisites were not found:\n'
+ ' require:\n'
+ ' cmd: Z\n',
'result': False
'result': False,
'changes': False,
},
'cmd_|-H_|-echo H_|-run': {
'__run_num__': 7,
'comment': 'The following requisites were not found:\n'
+ ' require:\n'
+ ' cmd: Z\n',
'result': False
'result': False,
'changes': False,
}
}
result = {}
ret = self.run_function('state.sls', mods='requisites.require')
result = self.normalize_ret(ret)
self.assertReturnNonEmptySaltType(ret)
for item, descr in ret.iteritems():
result[item] = {
'__run_num__': descr['__run_num__'],
'comment': descr['comment'],
'result': descr['result']
}
self.assertEqual(expected_result, result)
ret = self.run_function('state.sls', mods='requisites.require_error1')
@ -581,25 +599,22 @@ fi
'cmd_|-A_|-echo A_|-run': {
'__run_num__': 2,
'comment': 'Command "echo A" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-B_|-echo B_|-run': {
'__run_num__': 0,
'comment': 'Command "echo B" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-C_|-echo C_|-run': {
'__run_num__': 1,
'comment': 'Command "echo C" run',
'result': True},
'result': True,
'changes': True},
}
result = {}
ret = self.run_function('state.sls', mods='requisites.fullsls_require')
self.assertReturnNonEmptySaltType(ret)
for item, descr in ret.iteritems():
result[item] = {
'__run_num__': descr['__run_num__'],
'comment': descr['comment'],
'result': descr['result']
}
result = self.normalize_ret(ret)
self.assertEqual(expected_result, result)
# TODO: not done
@ -621,106 +636,127 @@ fi
'cmd_|-A_|-echo A third_|-run': {
'__run_num__': 2,
'comment': 'Command "echo A third" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-B_|-echo B first_|-run': {
'__run_num__': 0,
'comment': 'Command "echo B first" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-C_|-echo C second_|-run': {
'__run_num__': 1,
'comment': 'Command "echo C second" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-I_|-echo I_|-run': {
'__run_num__': 3,
'comment': 'The following requisites were not found:\n'
+ ' prereq:\n'
+ ' cmd: Z\n',
'result': False},
'result': False,
'changes': False},
'cmd_|-J_|-echo J_|-run': {
'__run_num__': 4,
'comment': 'The following requisites were not found:\n'
+ ' prereq:\n'
+ ' foobar: A\n',
'result': False}
'result': False,
'changes': False}
}
expected_result_simple2 = {
'cmd_|-A_|-echo A_|-run': {
'__run_num__': 1,
'comment': 'Command "echo A" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-B_|-echo B_|-run': {
'__run_num__': 2,
'comment': 'Command "echo B" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-C_|-echo C_|-run': {
'__run_num__': 0,
'comment': 'Command "echo C" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-D_|-echo D_|-run': {
'__run_num__': 3,
'comment': 'Command "echo D" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-E_|-echo E_|-run': {
'__run_num__': 4,
'comment': 'Command "echo E" run',
'result': True}
'result': True,
'changes': True}
}
expected_result_simple3 = {
'cmd_|-A_|-echo A first_|-run': {
'__run_num__': 0,
'comment': 'Command "echo A first" run',
'result': True,
'changes': True,
},
'cmd_|-B_|-echo B second_|-run': {
'__run_num__': 1,
'comment': 'Command "echo B second" run',
'result': True,
'changes': True,
},
'cmd_|-C_|-echo C third_|-wait': {
'__run_num__': 2,
'comment': '',
'result': True,
'changes': False,
}
}
expected_result_complex = {
'cmd_|-A_|-echo A fourth_|-run': {
'__run_num__': 3,
'comment': 'Command "echo A fourth" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-B_|-echo B first_|-run': {
'__run_num__': 0,
'comment': 'Command "echo B first" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-C_|-echo C second_|-run': {
'__run_num__': 1,
'comment': 'Command "echo C second" run',
'result': True},
'result': True,
'changes': True},
'cmd_|-D_|-echo D third_|-run': {
'__run_num__': 2,
'comment': 'Command "echo D third" run',
'result': True},
'result': True,
'changes': True},
}
result = {}
ret = self.run_function('state.sls', mods='requisites.prereq_simple')
self.assertReturnNonEmptySaltType(ret)
for item, descr in ret.iteritems():
result[item] = {
'__run_num__': descr['__run_num__'],
'comment': descr['comment'],
'result': descr['result']
}
result = self.normalize_ret(ret)
self.assertEqual(expected_result_simple, result)
# same test, but not using lists in yaml syntax
# TODO: issue #8235, prereq ignored when not used in list syntax
# Currently fails badly with :
# TypeError encountered executing state.sls: string indices must be integers, not str.
#result = {}
#expected_result_simple.pop('cmd_|-I_|-echo I_|-run')
#expected_result_simple.pop('cmd_|-J_|-echo J_|-run')
#ret = self.run_function('state.sls', mods='requisites.prereq_simple_nolist')
#for item, descr in ret.iteritems():
# result[item] = {
# '__run_num__': descr['__run_num__'],
# 'comment': descr['comment'],
# 'result': descr['result']
# }
#result = self.normalize_ret(ret)
#self.assertEqual(expected_result_simple, result)
result = {}
ret = self.run_function('state.sls', mods='requisites.prereq_simple2')
result = self.normalize_ret(ret)
self.assertReturnNonEmptySaltType(ret)
for item, descr in ret.iteritems():
result[item] = {
'__run_num__': descr['__run_num__'],
'comment': descr['comment'],
'result': descr['result']
}
self.assertEqual(expected_result_simple2, result)
ret = self.run_function('state.sls', mods='requisites.prereq_simple3')
result = self.normalize_ret(ret)
self.assertReturnNonEmptySaltType(ret)
self.assertEqual(expected_result_simple3, result)
#ret = self.run_function('state.sls', mods='requisites.prereq_error_nolist')
#self.assertEqual(
# ret,
@ -748,14 +784,8 @@ fi
# issue #8211, chaining complex prereq & prereq_in
# TODO: Actually this test fails
#result = {}
#ret = self.run_function('state.sls', mods='requisites.prereq_complex')
#for item, descr in ret.iteritems():
# result[item] = {
# '__run_num__': descr['__run_num__'],
# 'comment': descr['comment'],
# 'result': descr['result']
# }
#result = self.normalize_ret(ret)
#self.assertEqual(expected_result_complex, result)
# issue #8210 : prereq recursion undetected

View file

@ -68,8 +68,7 @@ class DarwinSysctlTestCase(TestCase):
'''
Tests adding of config file failure
'''
mock = mock_open()
with patch('salt.utils.fopen', mock_open(read_data=mock)) as m_open:
with patch('salt.utils.fopen', mock_open()) as m_open:
helper_open = m_open()
helper_open.write.assertRaises(CommandExecutionError,
darwin_sysctl.persist,
@ -81,8 +80,7 @@ class DarwinSysctlTestCase(TestCase):
'''
Tests successful add of config file when previously not one
'''
mock = mock_open()
with patch('salt.utils.fopen', mock_open(read_data=mock)) as m_open:
with patch('salt.utils.fopen', mock_open()) as m_open:
darwin_sysctl.persist('net.inet.icmp.icmplim', 50)
helper_open = m_open()
helper_open.write.assert_called_once_with(

View file

@ -0,0 +1,142 @@
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`jmoney <justin@saltstack.com>`
'''
# Import Salt Libs
from salt.modules import linux_sysctl
from salt.modules import systemd
from salt.exceptions import CommandExecutionError
# Import Salt Testing Libs
from salttesting import skipIf, TestCase
from salttesting.helpers import ensure_in_syspath
from salttesting.mock import (
MagicMock,
mock_open,
patch,
NO_MOCK,
NO_MOCK_REASON
)
ensure_in_syspath('../../')
# Globals
linux_sysctl.__salt__ = {}
systemd.__context__ = {}
@skipIf(NO_MOCK, NO_MOCK_REASON)
class LinuxSysctlTestCase(TestCase):
'''
TestCase for salt.modules.linux_sysctl module
'''
def test_get(self):
'''
Tests the return of get function
'''
mock_cmd = MagicMock(return_value=1)
with patch.dict(linux_sysctl.__salt__, {'cmd.run': mock_cmd}):
self.assertEqual(linux_sysctl.get('net.ipv4.ip_forward'), 1)
@patch('os.path.exists', MagicMock(return_value=False))
def test_assign_proc_sys_failed(self):
'''
Tests if /proc/sys/<kernel-subsystem> exists or not
'''
cmd = {'pid': 1337, 'retcode': 0, 'stderr': '',
'stdout': 'net.ipv4.ip_forward = 1'}
mock_cmd = MagicMock(return_value=cmd)
with patch.dict(linux_sysctl.__salt__, {'cmd.run_all': mock_cmd}):
self.assertRaises(CommandExecutionError,
linux_sysctl.assign,
'net.ipv4.ip_forward', 1)
@patch('os.path.exists', MagicMock(return_value=True))
def test_assign_cmd_failed(self):
'''
Tests if the assignment was successful or not
'''
cmd = {'pid': 1337, 'retcode': 0, 'stderr':
'sysctl: setting key "net.ipv4.ip_forward": Invalid argument',
'stdout': 'net.ipv4.ip_forward = backward'}
mock_cmd = MagicMock(return_value=cmd)
with patch.dict(linux_sysctl.__salt__, {'cmd.run_all': mock_cmd}):
self.assertRaises(CommandExecutionError,
linux_sysctl.assign,
'net.ipv4.ip_forward', 'backward')
@patch('os.path.exists', MagicMock(return_value=True))
def test_assign_success(self):
'''
Tests the return of successful assign function
'''
cmd = {'pid': 1337, 'retcode': 0, 'stderr': '',
'stdout': 'net.ipv4.ip_forward = 1'}
ret = {'net.ipv4.ip_forward': '1'}
mock_cmd = MagicMock(return_value=cmd)
with patch.dict(linux_sysctl.__salt__, {'cmd.run_all': mock_cmd}):
self.assertEqual(linux_sysctl.assign(
'net.ipv4.ip_forward', 1), ret)
@patch('os.path.isfile', MagicMock(return_value=False))
def test_persist_no_conf_failure(self):
'''
Tests adding of config file failure
'''
with patch('salt.utils.fopen', mock_open()) as m_open:
helper_open = m_open()
helper_open.write.assertRaises(CommandExecutionError,
linux_sysctl.persist,
'net.ipv4.ip_forward',
1, config=None)
@patch('os.path.isfile', MagicMock(return_value=False))
def test_persist_no_conf_success(self):
'''
Tests successful add of config file when previously not one
'''
asn_cmd = {'pid': 1337, 'retcode': 0, 'stderr': '',
'stdout': 'net.ipv4.ip_forward = 1'}
mock_asn_cmd = MagicMock(return_value=asn_cmd)
sys_cmd = 'systemd 208\n+PAM +LIBWRAP'
mock_sys_cmd = MagicMock(return_value=sys_cmd)
with patch('salt.utils.fopen', mock_open()) as m_open:
with patch.dict(linux_sysctl.__salt__,
{'cmd.run_stdout': mock_sys_cmd,
'cmd.run_all': mock_asn_cmd}):
with patch.dict(systemd.__context__,
{'systemd.sd_booted': True}):
linux_sysctl.persist('net.ipv4.ip_forward', 1)
helper_open = m_open()
helper_open.write.assert_called_once_with(
'#\n# Kernel sysctl configuration\n#\n')
@patch('os.path.isfile', MagicMock(return_value=True))
def test_persist_read_conf_success(self):
'''
Tests sysctl.conf read success
'''
asn_cmd = {'pid': 1337, 'retcode': 0, 'stderr': '',
'stdout': 'net.ipv4.ip_forward = 1'}
mock_asn_cmd = MagicMock(return_value=asn_cmd)
sys_cmd = 'systemd 208\n+PAM +LIBWRAP'
mock_sys_cmd = MagicMock(return_value=sys_cmd)
with patch('salt.utils.fopen', mock_open()):
with patch.dict(linux_sysctl.__salt__,
{'cmd.run_stdout': mock_sys_cmd,
'cmd.run_all': mock_asn_cmd}):
with patch.dict(systemd.__context__,
{'systemd.sd_booted': True}):
self.assertEqual(linux_sysctl.persist(
'net.ipv4.ip_forward', 1), 'Updated')
if __name__ == '__main__':
from integration import run_tests
run_tests(LinuxSysctlTestCase, needs_daemon=False)