mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch '2017.7' into 42676_backport_44071
This commit is contained in:
commit
ec2a8b2032
7 changed files with 186 additions and 43 deletions
|
@ -586,7 +586,18 @@ class RemoteFuncs(object):
|
|||
ret = {}
|
||||
if not salt.utils.verify.valid_id(self.opts, load['id']):
|
||||
return ret
|
||||
match_type = load.get('tgt_type', 'glob')
|
||||
expr_form = load.get('expr_form')
|
||||
if expr_form is not None and 'tgt_type' not in load:
|
||||
salt.utils.warn_until(
|
||||
u'Neon',
|
||||
u'_mine_get: minion {0} uses pre-Nitrogen API key '
|
||||
u'"expr_form". Accepting for backwards compatibility '
|
||||
u'but this is not guaranteed '
|
||||
u'after the Neon release'.format(load['id'])
|
||||
)
|
||||
match_type = expr_form
|
||||
else:
|
||||
match_type = load.get('tgt_type', 'glob')
|
||||
if match_type.lower() == 'pillar':
|
||||
match_type = 'pillar_exact'
|
||||
if match_type.lower() == 'compound':
|
||||
|
|
|
@ -337,6 +337,10 @@ def zone_compare(timezone):
|
|||
if 'Solaris' in __grains__['os_family'] or 'AIX' in __grains__['os_family']:
|
||||
return timezone == get_zone()
|
||||
|
||||
if 'FreeBSD' in __grains__['os_family']:
|
||||
if not os.path.isfile(_get_etc_localtime_path()):
|
||||
return timezone == get_zone()
|
||||
|
||||
tzfile = _get_etc_localtime_path()
|
||||
zonepath = _get_zone_file(timezone)
|
||||
try:
|
||||
|
|
|
@ -41,6 +41,18 @@ def present(name,
|
|||
grants:
|
||||
foo_db: read
|
||||
bar_db: all
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: yaml
|
||||
example user present in influxdb:
|
||||
influxdb_user.present:
|
||||
- name: example
|
||||
- password: somepassword
|
||||
- admin: False
|
||||
- grants:
|
||||
foo_db: read
|
||||
bar_db: all
|
||||
'''
|
||||
create = False
|
||||
ret = {'name': name,
|
||||
|
|
|
@ -10,7 +10,7 @@ import salt.runner
|
|||
|
||||
def cmd(
|
||||
name,
|
||||
fun=None,
|
||||
func=None,
|
||||
arg=(),
|
||||
**kwargs):
|
||||
'''
|
||||
|
@ -22,14 +22,14 @@ def cmd(
|
|||
|
||||
run_cloud:
|
||||
runner.cmd:
|
||||
- fun: cloud.create
|
||||
- func: cloud.create
|
||||
- arg:
|
||||
- my-ec2-config
|
||||
- myinstance
|
||||
|
||||
run_cloud:
|
||||
runner.cmd:
|
||||
- fun: cloud.create
|
||||
- func: cloud.create
|
||||
- kwargs:
|
||||
provider: my-ec2-config
|
||||
instances: myinstance
|
||||
|
@ -38,11 +38,16 @@ def cmd(
|
|||
'changes': {},
|
||||
'comment': '',
|
||||
'result': True}
|
||||
if fun is None:
|
||||
fun = name
|
||||
client = salt.runner.RunnerClient(__opts__)
|
||||
low = {'fun': fun,
|
||||
'arg': arg,
|
||||
'kwargs': kwargs}
|
||||
client.cmd_async(low)
|
||||
if func is None:
|
||||
func = name
|
||||
local_opts = {}
|
||||
local_opts.update(__opts__)
|
||||
local_opts['async'] = True # ensure this will be run async
|
||||
local_opts.update({
|
||||
'fun': func,
|
||||
'arg': arg,
|
||||
'kwarg': kwargs
|
||||
})
|
||||
runner = salt.runner.Runner(local_opts)
|
||||
runner.run()
|
||||
return ret
|
||||
|
|
69
tests/unit/daemons/test_masterapi.py
Normal file
69
tests/unit/daemons/test_masterapi.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt libs
|
||||
import salt.config
|
||||
import salt.daemons.masterapi as masterapi
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from tests.support.unit import TestCase
|
||||
from tests.support.mock import (
|
||||
patch,
|
||||
MagicMock,
|
||||
)
|
||||
|
||||
|
||||
class FakeCache(object):
|
||||
|
||||
def __init__(self):
|
||||
self.data = {}
|
||||
|
||||
def store(self, bank, key, value):
|
||||
self.data[bank, key] = value
|
||||
|
||||
def fetch(self, bank, key):
|
||||
return self.data[bank, key]
|
||||
|
||||
|
||||
class RemoteFuncsTestCase(TestCase):
|
||||
'''
|
||||
TestCase for salt.daemons.masterapi.RemoteFuncs class
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
opts = salt.config.master_config(None)
|
||||
self.funcs = masterapi.RemoteFuncs(opts)
|
||||
self.funcs.cache = FakeCache()
|
||||
|
||||
def test_mine_get(self, tgt_type_key='tgt_type'):
|
||||
'''
|
||||
Asserts that ``mine_get`` gives the expected results.
|
||||
|
||||
Actually this only tests that:
|
||||
|
||||
- the correct check minions method is called
|
||||
- the correct cache key is subsequently used
|
||||
'''
|
||||
self.funcs.cache.store('minions/webserver', 'mine',
|
||||
dict(ip_addr='2001:db8::1:3'))
|
||||
with patch('salt.utils.minions.CkMinions._check_compound_minions',
|
||||
MagicMock(return_value=['webserver'])):
|
||||
ret = self.funcs._mine_get(
|
||||
{
|
||||
'id': 'requester_minion',
|
||||
'tgt': 'G@roles:web',
|
||||
'fun': 'ip_addr',
|
||||
tgt_type_key: 'compound',
|
||||
}
|
||||
)
|
||||
self.assertDictEqual(ret, dict(webserver='2001:db8::1:3'))
|
||||
|
||||
def test_mine_get_pre_nitrogen_compat(self):
|
||||
'''
|
||||
Asserts that pre-Nitrogen API key ``expr_form`` is still accepted.
|
||||
|
||||
This is what minions before Nitrogen would issue.
|
||||
'''
|
||||
self.test_mine_get(tgt_type_key='expr_form')
|
|
@ -8,12 +8,11 @@ from __future__ import absolute_import
|
|||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
from tests.support.unit import skipIf, TestCase
|
||||
from tests.support.unit import TestCase
|
||||
from tests.support.mock import MagicMock, patch
|
||||
|
||||
# Import Salt libs
|
||||
import salt.modules.disk as disk
|
||||
import salt.utils
|
||||
|
||||
STUB_DISK_USAGE = {
|
||||
'/': {'filesystem': None, '1K-blocks': 10000, 'used': 10000, 'available': 10000, 'capacity': 10000},
|
||||
|
@ -141,15 +140,14 @@ class DiskTestCase(TestCase, LoaderModuleMockMixin):
|
|||
self.assertEqual(len(args[0].split()), 6)
|
||||
self.assertEqual(kwargs, {'python_shell': False})
|
||||
|
||||
@skipIf(not salt.utils.which('sync'), 'sync not found')
|
||||
@skipIf(not salt.utils.which('mkfs'), 'mkfs not found')
|
||||
def test_format(self):
|
||||
'''
|
||||
unit tests for disk.format
|
||||
'''
|
||||
device = '/dev/sdX1'
|
||||
mock = MagicMock(return_value=0)
|
||||
with patch.dict(disk.__salt__, {'cmd.retcode': mock}):
|
||||
with patch.dict(disk.__salt__, {'cmd.retcode': mock}),\
|
||||
patch('salt.utils.which', MagicMock(return_value=True)):
|
||||
self.assertEqual(disk.format_(device), True)
|
||||
|
||||
def test_fstype(self):
|
||||
|
@ -159,17 +157,18 @@ class DiskTestCase(TestCase, LoaderModuleMockMixin):
|
|||
device = '/dev/sdX1'
|
||||
fs_type = 'ext4'
|
||||
mock = MagicMock(return_value='FSTYPE\n{0}'.format(fs_type))
|
||||
with patch.dict(disk.__grains__, {'kernel': 'Linux'}):
|
||||
with patch.dict(disk.__salt__, {'cmd.run': mock}):
|
||||
self.assertEqual(disk.fstype(device), fs_type)
|
||||
with patch.dict(disk.__grains__, {'kernel': 'Linux'}), \
|
||||
patch.dict(disk.__salt__, {'cmd.run': mock}), \
|
||||
patch('salt.utils.which', MagicMock(return_value=True)):
|
||||
self.assertEqual(disk.fstype(device), fs_type)
|
||||
|
||||
@skipIf(not salt.utils.which('resize2fs'), 'resize2fs not found')
|
||||
def test_resize2fs(self):
|
||||
'''
|
||||
unit tests for disk.resize2fs
|
||||
'''
|
||||
device = '/dev/sdX1'
|
||||
mock = MagicMock()
|
||||
with patch.dict(disk.__salt__, {'cmd.run_all': mock}):
|
||||
with patch.dict(disk.__salt__, {'cmd.run_all': mock}), \
|
||||
patch('salt.utils.which', MagicMock(return_value=True)):
|
||||
disk.resize2fs(device)
|
||||
mock.assert_called_once_with('resize2fs {0}'.format(device), python_shell=False)
|
||||
|
|
|
@ -7,6 +7,7 @@ import sys
|
|||
import time
|
||||
import signal
|
||||
import multiprocessing
|
||||
import functools
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.unit import TestCase, skipIf
|
||||
|
@ -20,19 +21,67 @@ import salt.ext.six as six
|
|||
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
|
||||
|
||||
|
||||
def die(func):
|
||||
'''
|
||||
Add proc title
|
||||
'''
|
||||
@functools.wraps(func)
|
||||
def wrapper(self):
|
||||
# Strip off the "test_" from the function name
|
||||
name = func.__name__[5:]
|
||||
|
||||
def _die():
|
||||
salt.utils.appendproctitle('test_{0}'.format(name))
|
||||
setattr(self, 'die_' + name, _die)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def incr(func):
|
||||
'''
|
||||
Increment counter
|
||||
'''
|
||||
@functools.wraps(func)
|
||||
def wrapper(self):
|
||||
# Strip off the "test_" from the function name
|
||||
name = func.__name__[5:]
|
||||
|
||||
def _incr(counter, num):
|
||||
salt.utils.appendproctitle('test_{0}'.format(name))
|
||||
for _ in range(0, num):
|
||||
counter.value += 1
|
||||
setattr(self, 'incr_' + name, _incr)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def spin(func):
|
||||
'''
|
||||
Spin indefinitely
|
||||
'''
|
||||
@functools.wraps(func)
|
||||
def wrapper(self):
|
||||
# Strip off the "test_" from the function name
|
||||
name = func.__name__[5:]
|
||||
|
||||
def _spin():
|
||||
salt.utils.appendproctitle('test_{0}'.format(name))
|
||||
while True:
|
||||
time.sleep(1)
|
||||
setattr(self, 'spin_' + name, _spin)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class TestProcessManager(TestCase):
|
||||
|
||||
@spin
|
||||
def test_basic(self):
|
||||
'''
|
||||
Make sure that the process is alive 2s later
|
||||
'''
|
||||
def spin():
|
||||
salt.utils.appendproctitle('test_basic')
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
process_manager = salt.utils.process.ProcessManager()
|
||||
process_manager.add_process(spin)
|
||||
process_manager.add_process(self.spin_basic)
|
||||
initial_pid = next(six.iterkeys(process_manager._process_map))
|
||||
time.sleep(2)
|
||||
process_manager.check_children()
|
||||
|
@ -48,17 +97,16 @@ class TestProcessManager(TestCase):
|
|||
process_manager.stop_restarting()
|
||||
process_manager.kill_children()
|
||||
|
||||
@spin
|
||||
def test_kill(self):
|
||||
def spin():
|
||||
salt.utils.appendproctitle('test_kill')
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
process_manager = salt.utils.process.ProcessManager()
|
||||
process_manager.add_process(spin)
|
||||
process_manager.add_process(self.spin_kill)
|
||||
initial_pid = next(six.iterkeys(process_manager._process_map))
|
||||
# kill the child
|
||||
os.kill(initial_pid, signal.SIGKILL)
|
||||
if salt.utils.is_windows():
|
||||
os.kill(initial_pid, signal.SIGTERM)
|
||||
else:
|
||||
os.kill(initial_pid, signal.SIGKILL)
|
||||
# give the OS time to give the signal...
|
||||
time.sleep(0.1)
|
||||
process_manager.check_children()
|
||||
|
@ -74,15 +122,13 @@ class TestProcessManager(TestCase):
|
|||
process_manager.stop_restarting()
|
||||
process_manager.kill_children()
|
||||
|
||||
@die
|
||||
def test_restarting(self):
|
||||
'''
|
||||
Make sure that the process is alive 2s later
|
||||
'''
|
||||
def die():
|
||||
salt.utils.appendproctitle('test_restarting')
|
||||
|
||||
process_manager = salt.utils.process.ProcessManager()
|
||||
process_manager.add_process(die)
|
||||
process_manager.add_process(self.die_restarting)
|
||||
initial_pid = next(six.iterkeys(process_manager._process_map))
|
||||
time.sleep(2)
|
||||
process_manager.check_children()
|
||||
|
@ -99,14 +145,11 @@ class TestProcessManager(TestCase):
|
|||
process_manager.kill_children()
|
||||
|
||||
@skipIf(sys.version_info < (2, 7), 'Needs > Py 2.7 due to bug in stdlib')
|
||||
@incr
|
||||
def test_counter(self):
|
||||
def incr(counter, num):
|
||||
salt.utils.appendproctitle('test_counter')
|
||||
for _ in range(0, num):
|
||||
counter.value += 1
|
||||
counter = multiprocessing.Value('i', 0)
|
||||
process_manager = salt.utils.process.ProcessManager()
|
||||
process_manager.add_process(incr, args=(counter, 2))
|
||||
process_manager.add_process(self.incr_counter, args=(counter, 2))
|
||||
time.sleep(1)
|
||||
process_manager.check_children()
|
||||
time.sleep(1)
|
||||
|
|
Loading…
Add table
Reference in a new issue