Merge branch '2016.11' into 'develop'

No conflicts.
This commit is contained in:
rallytime 2017-01-06 10:31:51 -05:00
commit 342a5ac0b8
14 changed files with 104 additions and 44 deletions

View File

@ -38,6 +38,14 @@ This package can be installed using `pip` or `easy_install`:
.. _Issue #29537: https://github.com/saltstack/salt/issues/29537
.. note::
pyVmomi doesn't expose the ability to specify the locale when connecting to
VMware. This causes parsing issues when connecting to an instance of VMware
running under a non-English locale. Until this feature is added upstream
`Issue #38402`_ contains a workaround.
.. _Issue #38402: https://github.com/saltstack/salt/issues/38402
Configuration
=============

View File

@ -16,18 +16,7 @@ Install Salt stable releases from the Arch Linux Official repositories as follow
.. code-block:: bash
pacman -S salt-zmq
To install Salt stable releases using the :ref:`RAET protocol<raet>`,
use the following:
.. code-block:: bash
pacman -S salt-raet
.. note:: transports
Unlike other linux distributions, please be aware that Arch Linux's package manager pacman defaults to RAET as the Salt transport. If you want to use ZeroMQ instead, make sure to enter the associated number for the salt-zmq repository when prompted.
pacman -S salt
Tracking develop
----------------

View File

@ -12,9 +12,6 @@ from __future__ import absolute_import
import logging
import re
# Import Salt libs
import salt.utils
# Import Third Party Libs
try:
import psutil
@ -28,9 +25,7 @@ __virtualname__ = 'memusage'
def __virtual__():
if salt.utils.is_windows():
return False
elif HAS_PSUTIL is False:
if HAS_PSUTIL is False:
return False
else:
return __virtualname__

View File

@ -2958,6 +2958,8 @@ def is_profile_configured(opts, provider, profile_name, vm_=None):
if driver == 'linode' and profile_key.get('clonefrom', False):
non_image_drivers.append('linode')
non_size_drivers.append('linode')
elif driver == 'gce' and 'sourceImage' in str(vm_.get('ex_disks_gce_struct')):
non_image_drivers.append('gce')
# If cloning on VMware, specifying image is not necessary.
if driver == 'vmware' and 'image' not in list(profile_key.keys()):
@ -3456,10 +3458,15 @@ def api_config(path):
Read in the Salt Master config file and add additional configs that
need to be stubbed out for salt-api
'''
# Let's grab a copy of salt-api's required defaults
opts = DEFAULT_API_OPTS
# Let's override them with salt's master opts
opts.update(client_config(path, defaults=DEFAULT_MASTER_OPTS))
# Let's grab a copy of salt's master opts
opts = client_config(path, defaults=DEFAULT_MASTER_OPTS)
# Let's override them with salt-api's required defaults
api_opts = DEFAULT_API_OPTS
api_opts.update({
'pidfile': opts.get('api_pidfile', DEFAULT_API_OPTS['api_pidfile']),
'log_file': opts.get('api_logfile', DEFAULT_API_OPTS['api_logfile']),
})
opts.update(api_opts)
prepend_root_dir(opts, [
'api_pidfile',
'api_logfile',

View File

@ -34,10 +34,10 @@ prefaced with a ``!``.
# Import python libraries
from __future__ import absolute_import
import datetime
import json
import logging
import time
import re
import json
import yaml
try:
@ -231,5 +231,6 @@ def start(token,
else:
# Fire event to event bus
fire('{0}/{1}'.format(tag, _m['type']), _m)
time.sleep(1)
else:
raise UserWarning("Could not connect to slack")

View File

@ -713,6 +713,9 @@ class Client(object):
else:
netloc = url_data.netloc
# Strip user:pass from URLs
netloc = netloc.split('@')[-1]
if cachedir is None:
cachedir = self.opts['cachedir']
elif not os.path.isabs(cachedir):

View File

@ -370,7 +370,7 @@ def cli(*commands):
# in case of errors, they'll be catched in the proxy
def traceroute(destination, source='', ttl=0, timeout=0):
def traceroute(destination, source=None, ttl=None, timeout=None):
'''
Calls the method traceroute from the NAPALM driver object and returns a dictionary with the result of the traceroute
@ -400,7 +400,7 @@ def traceroute(destination, source='', ttl=0, timeout=0):
)
def ping(destination, source='', ttl=0, timeout=0, size=0, count=0):
def ping(destination, source=None, ttl=None, timeout=None, size=None, count=None):
'''
Executes a ping on the network device and returns a dictionary as a result.

View File

@ -68,7 +68,7 @@ def __virtual__():
# ----------------------------------------------------------------------------------------------------------------------
def show(destination, protocol):
def show(destination, protocol=None):
'''
Displays all details for a certain route learned via a specific protocol.

View File

@ -869,6 +869,7 @@ def extracted(name,
else:
source_sum = {}
concurrent = bool(__opts__.get('sudo_user'))
if not source_is_local and not os.path.isfile(cached_source):
if __opts__['test']:
ret['result'] = None
@ -885,9 +886,19 @@ def extracted(name,
source_hash_name=source_hash_name,
makedirs=True,
skip_verify=skip_verify,
saltenv=__env__)
saltenv=__env__,
concurrent=concurrent)
log.debug('file.managed: {0}'.format(file_result))
# Prevent a traceback if errors prevented the above state from getting
# off the ground.
if isinstance(file_result, list):
try:
ret['comment'] = '\n'.join(file_result)
except TypeError:
ret['comment'] = '\n'.join([str(x) for x in file_result])
return ret
# Get actual state result. The state.single return is a single-element
# dictionary with the state's unique ID at the top level, and its value
# being the state's return dictionary. next(iter(dict_name)) will give
@ -1324,7 +1335,8 @@ def extracted(name,
user=user,
group=group,
recurse=recurse,
test=__opts__['test'])
test=__opts__['test'],
concurrent=concurrent)
try:
dir_result = dir_result[next(iter(dir_result))]
except AttributeError:

View File

@ -378,7 +378,6 @@ class SerializerExtension(Extension, object):
super(SerializerExtension, self).__init__(environment)
self.environment.filters.update({
'yaml': self.format_yaml,
'yaml_safe': self.format_yaml_safe,
'json': self.format_json,
'python': self.format_python,
'load_yaml': self.load_yaml,
@ -422,13 +421,6 @@ class SerializerExtension(Extension, object):
yaml_txt = yaml_txt[:len(yaml_txt)-4]
return Markup(yaml_txt)
def format_yaml_safe(self, value, flow_style=True):
yaml_txt = yaml.safe_dump(value, default_flow_style=flow_style,
Dumper=OrderedDictDumper).strip()
if yaml_txt.endswith('\n...\n'):
yaml_txt = yaml_txt[:len(yaml_txt-5)]
return Markup(yaml_txt)
def format_python(self, value):
return Markup(pprint.pformat(value).strip())

View File

@ -45,6 +45,9 @@ class SaltYamlSafeLoader(yaml.SafeLoader, object):
self.add_constructor(
u'tag:yaml.org,2002:omap',
type(self).construct_yaml_map)
self.add_constructor(
u'tag:yaml.org,2002:python/unicode',
type(self).construct_unicode)
self.dictclass = dictclass
def construct_yaml_map(self, node):
@ -53,6 +56,9 @@ class SaltYamlSafeLoader(yaml.SafeLoader, object):
value = self.construct_mapping(node)
data.update(value)
def construct_unicode(self, node):
return node.value
def construct_mapping(self, node, deep=False):
'''
Build the mapping for YAML

View File

@ -22,6 +22,8 @@ ensure_in_syspath('../../../')
# Import Third-Party Libs
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
TIMEOUT = 500
def _random_name(size=6):
'''
@ -92,18 +94,18 @@ class GCETest(integration.ShellCase):
'''
# create the instance
instance = self.run_cloud('-p gce-test {0}'.format(self.INSTANCE_NAME), timeout=500)
instance = self.run_cloud('-p gce-test {0}'.format(self.INSTANCE_NAME), timeout=TIMEOUT)
ret_str = '{0}:'.format(self.INSTANCE_NAME)
# check if instance returned with salt installed
try:
self.assertIn(ret_str, instance)
except AssertionError:
self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=500)
self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=TIMEOUT)
raise
# delete the instance
delete = self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=500)
delete = self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=TIMEOUT)
# example response: ['gce-config:', '----------', ' gce:', '----------', 'cloud-test-dq4e6c:', 'True', '']
delete_str = ''.join(delete)
@ -120,18 +122,20 @@ class GCETest(integration.ShellCase):
'''
# create the instance
instance = self.run_cloud('-p gce-test-extra {0}'.format(self.INSTANCE_NAME))
instance = self.run_cloud('-p gce-test-extra \
{0}'.format(self.INSTANCE_NAME),
timeout=TIMEOUT)
ret_str = '{0}:'.format(self.INSTANCE_NAME)
# check if instance returned with salt installed
try:
self.assertIn(ret_str, instance)
except AssertionError:
self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=500)
self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=TIMEOUT)
raise
# delete the instance
delete = self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=500)
delete = self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=TIMEOUT)
# example response: ['gce-config:', '----------', ' gce:', '----------', 'cloud-test-dq4e6c:', 'True', '']
delete_str = ''.join(delete)
@ -152,7 +156,7 @@ class GCETest(integration.ShellCase):
# if test instance is still present, delete it
if ret_str in query:
self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=500)
self.run_cloud('-d {0} --assume-yes'.format(self.INSTANCE_NAME), timeout=TIMEOUT)
if __name__ == '__main__':

View File

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Import Python Libs
from __future__ import absolute_import
# Import Salt Testing libs
from salttesting import TestCase
from salttesting.helpers import ensure_in_syspath
ensure_in_syspath('../../')
# Import Salt libs
from salt.renderers import yaml
yaml.__salt__ = {}
yaml.__opts__ = {}
class YAMLRendererTestCase(TestCase):
def test_yaml_render_string(self):
data = "string"
result = yaml.render(data)
self.assertEqual(result, data)
def test_yaml_render_unicode(self):
data = "!!python/unicode python unicode string"
result = yaml.render(data)
self.assertEqual(result, u"python unicode string")

View File

@ -504,7 +504,14 @@ class TestCustomExtensions(TestCase):
"foo": True,
"bar": 42,
"baz": [1, 2, 3],
"qux": 2.0
"qux": 2.0,
"spam": OrderedDict([
('foo', OrderedDict([
('bar', 'baz'),
('qux', 42)
])
)
])
}
env = Environment(extensions=[SerializerExtension])
rendered = env.from_string('{{ dataset|yaml }}').render(dataset=dataset)
@ -516,6 +523,12 @@ class TestCustomExtensions(TestCase):
rendered = env.from_string('{{ dataset|yaml }}').render(dataset=dataset)
self.assertEqual(dataset, rendered)
def test_serialize_yaml_unicode(self):
dataset = u"str value"
env = Environment(extensions=[SerializerExtension])
rendered = env.from_string('{{ dataset|yaml }}').render(dataset=dataset)
self.assertEqual("!!python/unicode str value", rendered)
def test_serialize_python(self):
dataset = {
"foo": True,