mirror of
https://github.com/valitydev/salt.git
synced 2024-11-06 08:35:21 +00:00
Merge branch '2015.2' into develop
This commit is contained in:
commit
62f868a076
@ -152,7 +152,8 @@ additional-builtins=__opts__,
|
||||
__active_provider_name__,
|
||||
__master_opts__,
|
||||
__jid_event__,
|
||||
__instance_id__
|
||||
__instance_id__,
|
||||
__salt_system_encoding__
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
|
@ -209,7 +209,9 @@ additional-builtins=__opts__,
|
||||
__active_provider_name__,
|
||||
__master_opts__,
|
||||
__jid_event__,
|
||||
__instance_id__
|
||||
__instance_id__,
|
||||
__salt_system_encoding__
|
||||
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
|
@ -51,3 +51,10 @@ Deprecations
|
||||
- Removed ``parameter`` argument from ``eselect.set_`` state. Please migrate to
|
||||
``module_parameter`` or ``action_parameter``.
|
||||
|
||||
- The ``salt_events`` table schema has changed to include an additional field
|
||||
called ``master_id`` to distinguish between events flowing into a database
|
||||
from multiple masters. If ``event_return`` is enabled in the master config,
|
||||
the database schema must first be updated to add the ``master_id`` field.
|
||||
This alteration can be accomplished as follows:
|
||||
|
||||
``ALTER TABLE salt_events ADD master_id VARCHAR(255) NOT NULL;``
|
||||
|
@ -9,22 +9,65 @@ import warnings
|
||||
|
||||
# All salt related deprecation warnings should be shown once each!
|
||||
warnings.filterwarnings(
|
||||
'once', # Show once
|
||||
'', # No deprecation message match
|
||||
DeprecationWarning, # This filter is for DeprecationWarnings
|
||||
r'^(salt|salt\.(.*))$' # Match module(s) 'salt' and 'salt.<whatever>'
|
||||
'once', # Show once
|
||||
'', # No deprecation message match
|
||||
DeprecationWarning, # This filter is for DeprecationWarnings
|
||||
r'^(salt|salt\.(.*))$' # Match module(s) 'salt' and 'salt.<whatever>'
|
||||
)
|
||||
|
||||
# While we are supporting Python2.6, hide nested with-statements warnings
|
||||
warnings.filterwarnings(
|
||||
'ignore',
|
||||
'With-statements now directly support multiple context managers',
|
||||
DeprecationWarning
|
||||
'ignore',
|
||||
'With-statements now directly support multiple context managers',
|
||||
DeprecationWarning
|
||||
)
|
||||
|
||||
# Filter the backports package UserWarning about being re-imported
|
||||
warnings.filterwarnings(
|
||||
'ignore',
|
||||
'^Module backports was already imported from (.*), but (.*) is being added to sys.path$',
|
||||
UserWarning
|
||||
'ignore',
|
||||
'^Module backports was already imported from (.*), but (.*) is being added to sys.path$',
|
||||
UserWarning
|
||||
)
|
||||
|
||||
|
||||
def __define_global_system_encoding_variable__():
|
||||
import sys
|
||||
# This is the most trustworthy source of the system encoding, though, if
|
||||
# salt is being imported after being daemonized, this information is lost
|
||||
# and reset to None
|
||||
encoding = sys.stdin.encoding
|
||||
if not encoding:
|
||||
# If the system is properly codfigured this should return a valid
|
||||
# encoding. MS Windows has problems with this and reports the wrong
|
||||
# encoding
|
||||
import locale
|
||||
encoding = locale.getdefaultlocale()[-1]
|
||||
|
||||
# This is now garbage collectable
|
||||
del locale
|
||||
if not encoding:
|
||||
# This is most likely asccii which is not the best but we were
|
||||
# unable to find a better encoding
|
||||
encoding = sys.getdefaultencoding()
|
||||
|
||||
# We can't use six.moves.builtins because these builtins get deleted sooner
|
||||
# than expected. See:
|
||||
# https://github.com/saltstack/salt/issues/21036
|
||||
if sys.version_info[0] < 3:
|
||||
import __builtin__ as builtins
|
||||
else:
|
||||
import builtins # pylint: disable=import-error
|
||||
|
||||
# Define the detected encoding as a built-in variable for ease of use
|
||||
setattr(builtins, '__salt_system_encoding__', encoding)
|
||||
|
||||
# This is now garbage collectable
|
||||
del sys
|
||||
del builtins
|
||||
del encoding
|
||||
|
||||
|
||||
__define_global_system_encoding_variable__()
|
||||
|
||||
# This is now garbage collectable
|
||||
del __define_global_system_encoding_variable__
|
||||
|
@ -442,7 +442,7 @@ class SSH(object):
|
||||
# Save the invocation information
|
||||
argv = self.opts['argv']
|
||||
|
||||
if self.opts['raw_shell']:
|
||||
if self.opts.get('raw_shell', False):
|
||||
fun = 'ssh._raw'
|
||||
args = argv
|
||||
else:
|
||||
|
@ -17,7 +17,7 @@
|
||||
# CREATED: 10/15/2012 09:49:37 PM WEST
|
||||
#======================================================================================================================
|
||||
set -o nounset # Treat unset variables as an error
|
||||
__ScriptVersion="2015.01.12"
|
||||
__ScriptVersion="2015.02.27"
|
||||
__ScriptName="bootstrap-salt.sh"
|
||||
|
||||
#======================================================================================================================
|
||||
@ -1957,8 +1957,6 @@ install_debian_deps() {
|
||||
# Additionally install procps and pciutils which allows for Docker boostraps. See 366#issuecomment-39666813
|
||||
__PACKAGES="${__PACKAGES} python-pip"
|
||||
__PIP_PACKAGES="${__PIP_PACKAGES} requests"
|
||||
else
|
||||
__PACKAGES="${__PACKAGES} python-requests"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
@ -2109,49 +2107,18 @@ install_debian_7_deps() {
|
||||
# shellcheck disable=SC2086
|
||||
wget $_WGET_ARGS -q http://debian.saltstack.com/debian-salt-team-joehealy.gpg.key -O - | apt-key add - || return 1
|
||||
|
||||
if [ "$_PIP_ALLOWED" -eq $BS_TRUE ]; then
|
||||
echowarn "PyZMQ will be installed from PyPI in order to compile it against ZMQ3"
|
||||
echowarn "This is required for long term stable minion connections to the master."
|
||||
echowarn "YOU WILL END UP WITH QUITE A FEW PACKAGES FROM DEBIAN UNSTABLE"
|
||||
echowarn "Sleeping for 5 seconds so you can cancel..."
|
||||
sleep 5
|
||||
|
||||
if [ ! -f /etc/apt/sources.list.d/debian-unstable.list ]; then
|
||||
cat <<_eof > /etc/apt/sources.list.d/debian-unstable.list
|
||||
deb http://ftp.debian.org/debian unstable main
|
||||
deb-src http://ftp.debian.org/debian unstable main
|
||||
_eof
|
||||
|
||||
cat <<_eof > /etc/apt/preferences.d/libzmq3-debian-unstable.pref
|
||||
Package: libzmq3
|
||||
Pin: release a=unstable
|
||||
Pin-Priority: 800
|
||||
|
||||
Package: libzmq3-dev
|
||||
Pin: release a=unstable
|
||||
Pin-Priority: 800
|
||||
_eof
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
__apt_get_install_noinput -t unstable libzmq3 libzmq3-dev || return 1
|
||||
__PACKAGES="build-essential python-dev python-pip python-requests python-apt"
|
||||
# Additionally install procps and pciutils which allows for Docker boostraps. See 366#issuecomment-39666813
|
||||
__PACKAGES="${__PACKAGES} procps pciutils"
|
||||
# shellcheck disable=SC2086
|
||||
__apt_get_install_noinput ${__PACKAGES} || return 1
|
||||
else
|
||||
apt-get update || return 1
|
||||
__PACKAGES="python-zmq python-requests python-apt"
|
||||
# Additionally install procps and pciutils which allows for Docker boostraps. See 366#issuecomment-39666813
|
||||
__PACKAGES="${__PACKAGES} procps pciutils"
|
||||
# shellcheck disable=SC2086
|
||||
__apt_get_install_noinput ${__PACKAGES} || return 1
|
||||
|
||||
fi
|
||||
apt-get update || return 1
|
||||
__apt_get_install_noinput -t wheezy-backports libzmq3 libzmq3-dev python-zmq python-requests python-apt || return 1
|
||||
# Additionally install procps and pciutils which allows for Docker boostraps. See 366#issuecomment-39666813
|
||||
__PACKAGES="procps pciutils"
|
||||
# shellcheck disable=SC2086
|
||||
__apt_get_install_noinput ${__PACKAGES} || return 1
|
||||
|
||||
if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then
|
||||
check_pip_allowed "You need to allow pip based installations (-P) in order to install apache-libcloud"
|
||||
__PACKAGES="build-essential python-dev python-pip"
|
||||
# shellcheck disable=SC2086
|
||||
__apt_get_install_noinput ${__PACKAGES} || return 1
|
||||
pip install -U "apache-libcloud>=$_LIBCLOUD_MIN_VERSION"
|
||||
fi
|
||||
|
||||
@ -2567,23 +2534,33 @@ __install_epel_repository() {
|
||||
|
||||
__install_saltstack_copr_zeromq_repository() {
|
||||
echoinfo "Installing Zeromq >=4 and PyZMQ>=14 from SaltStack's COPR repository"
|
||||
if [ ! -f /etc/yum.repos.d/saltstack-zeromq4.repo ]; then
|
||||
if [ ! -s /etc/yum.repos.d/saltstack-zeromq4.repo ]; then
|
||||
if [ "${DISTRO_NAME_L}" = "fedora" ]; then
|
||||
__REPOTYPE="${DISTRO_NAME_L}"
|
||||
else
|
||||
__REPOTYPE="epel"
|
||||
fi
|
||||
wget -O /etc/yum.repos.d/saltstack-zeromq4.repo \
|
||||
__fetch_url /etc/yum.repos.d/saltstack-zeromq4.repo \
|
||||
"http://copr.fedoraproject.org/coprs/saltstack/zeromq4/repo/${__REPOTYPE}-${DISTRO_MAJOR_VERSION}/saltstack-zeromq4-${__REPOTYPE}-${DISTRO_MAJOR_VERSION}.repo" || return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
__install_saltstack_copr_salt_el5_repository() {
|
||||
if [ ! -s /etc/yum.repos.d/saltstack-salt-el5-epel-5.repo ]; then
|
||||
__fetch_url /etc/yum.repos.d/saltstack-salt-el5-epel-5.repo \
|
||||
"http://copr.fedoraproject.org/coprs/saltstack/salt-el5/repo/epel-5/saltstack-salt-el5-epel-5.repo" || return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
install_centos_stable_deps() {
|
||||
__install_epel_repository || return 1
|
||||
if [ "$DISTRO_MAJOR_VERSION" -eq 5 ]; then
|
||||
__install_saltstack_copr_salt_el5_repository || return 1
|
||||
fi
|
||||
|
||||
if [ "$_ENABLE_EXTERNAL_ZMQ_REPOS" -eq $BS_TRUE ]; then
|
||||
if [ "$_ENABLE_EXTERNAL_ZMQ_REPOS" -eq $BS_TRUE ] && [ "$DISTRO_MAJOR_VERSION" -gt 5 ]; then
|
||||
yum -y install python-hashlib || return 1
|
||||
__install_saltstack_copr_zeromq_repository || return 1
|
||||
fi
|
||||
@ -2625,7 +2602,7 @@ install_centos_stable_deps() {
|
||||
if [ "$DISTRO_MAJOR_VERSION" -eq 5 ]; then
|
||||
easy_install-2.6 "apache-libcloud>=$_LIBCLOUD_MIN_VERSION"
|
||||
else
|
||||
pip-python install "apache-libcloud>=$_LIBCLOUD_MIN_VERSION"
|
||||
pip install "apache-libcloud>=$_LIBCLOUD_MIN_VERSION"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -2651,9 +2628,13 @@ install_centos_stable() {
|
||||
if [ "$_INSTALL_MINION" -eq $BS_TRUE ]; then
|
||||
__PACKAGES="${__PACKAGES} salt-minion"
|
||||
fi
|
||||
if [ "$_INSTALL_MASTER" -eq $BS_TRUE ] || [ "$_INSTALL_SYNDIC" -eq $BS_TRUE ]; then
|
||||
if [ "$_INSTALL_MASTER" -eq $BS_TRUE ];then
|
||||
__PACKAGES="${__PACKAGES} salt-master"
|
||||
fi
|
||||
if [ "$_INSTALL_SYNDIC" -eq $BS_TRUE ];then
|
||||
__PACKAGES="${__PACKAGES} salt-syndic"
|
||||
fi
|
||||
|
||||
if [ "$DISTRO_NAME_L" = "oracle_linux" ]; then
|
||||
# We need to install one package at a time because --enablerepo=X disables ALL OTHER REPOS!!!!
|
||||
for package in ${__PACKAGES}; do
|
||||
@ -2868,6 +2849,10 @@ install_centos_check_services() {
|
||||
__test_rhel_optionals_packages() {
|
||||
__install_epel_repository || return 1
|
||||
|
||||
if [ "$DISTRO_MAJOR_VERSION" -ge 7 ]; then
|
||||
yum-config-manager --enable \*server-optional || return 1
|
||||
fi
|
||||
|
||||
if [ "$DISTRO_MAJOR_VERSION" -ge 6 ]; then
|
||||
# Let's enable package installation testing, kind of, --dry-run
|
||||
echoinfo "Testing if packages usually on the optionals repository are available:"
|
||||
|
@ -4,10 +4,8 @@ The crypt module manages all of the cryptography functions for minions and
|
||||
masters, encrypting and decrypting payloads, preparing messages, and
|
||||
authenticating peers
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import, print_function
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
@ -16,7 +14,7 @@ import hashlib
|
||||
import logging
|
||||
import traceback
|
||||
import binascii
|
||||
from salt.ext.six.moves import zip
|
||||
from salt.ext.six.moves import zip # pylint: disable=import-error,redefined-builtin
|
||||
|
||||
# Import third party libs
|
||||
try:
|
||||
@ -499,7 +497,8 @@ class SAuth(object):
|
||||
'from master {0}'.format(self.opts['master']))
|
||||
m_pub_fn = os.path.join(self.opts['pki_dir'], self.mpub)
|
||||
uid = salt.utils.get_uid(self.opts.get('user', None))
|
||||
salt.utils.fopen(m_pub_fn, 'w+', uid=uid).write(payload['pub_key'])
|
||||
with salt.utils.fpopen(m_pub_fn, 'w+', uid=uid) as wfh:
|
||||
wfh.write(payload['pub_key'])
|
||||
return True
|
||||
else:
|
||||
log.error('Received signed public-key from master {0} '
|
||||
|
@ -1250,6 +1250,7 @@ def locale_info():
|
||||
# might do, per #2205
|
||||
grains['locale_info']['defaultlanguage'] = 'unknown'
|
||||
grains['locale_info']['defaultencoding'] = 'unknown'
|
||||
grains['locale_info']['detectedencoding'] = __salt_system_encoding__
|
||||
return grains
|
||||
|
||||
|
||||
|
@ -1186,9 +1186,8 @@ class AESFuncs(object):
|
||||
load['grains'],
|
||||
load['id'],
|
||||
load.get('saltenv', load.get('env')),
|
||||
load.get('ext'),
|
||||
self.mminion.functions,
|
||||
load.get('pillar_override', {}))
|
||||
ext=load.get('ext'),
|
||||
pillar=load.get('pillar_override', {}))
|
||||
data = pillar.compile_pillar(pillar_dirs=pillar_dirs)
|
||||
if self.opts.get('minion_data_cache', False):
|
||||
cdir = os.path.join(self.opts['cachedir'], 'minions', load['id'])
|
||||
@ -1204,8 +1203,6 @@ class AESFuncs(object):
|
||||
'pillar': data})
|
||||
)
|
||||
os.rename(tmpfname, datap)
|
||||
for mod in mods:
|
||||
sys.modules[mod].__grains__ = self.opts['grains']
|
||||
return data
|
||||
|
||||
def _minion_event(self, load):
|
||||
|
@ -304,7 +304,7 @@ def _netstat_route_linux():
|
||||
'''
|
||||
ret = []
|
||||
cmd = 'netstat -A inet -rn | tail -n+3'
|
||||
out = __salt__['cmd.run'](cmd)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=True)
|
||||
for line in out.splitlines():
|
||||
comps = line.split()
|
||||
ret.append({
|
||||
@ -315,7 +315,7 @@ def _netstat_route_linux():
|
||||
'flags': comps[3],
|
||||
'interface': comps[7]})
|
||||
cmd = 'netstat -A inet6 -rn | tail -n+3'
|
||||
out = __salt__['cmd.run'](cmd)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=True)
|
||||
for line in out.splitlines():
|
||||
comps = line.split()
|
||||
if len(comps) == 6:
|
||||
@ -345,7 +345,7 @@ def _netstat_route_freebsd():
|
||||
'''
|
||||
ret = []
|
||||
cmd = 'netstat -f inet -rn | tail -n+5'
|
||||
out = __salt__['cmd.run'](cmd)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=True)
|
||||
for line in out.splitlines():
|
||||
comps = line.split()
|
||||
ret.append({
|
||||
@ -356,7 +356,7 @@ def _netstat_route_freebsd():
|
||||
'flags': comps[3],
|
||||
'interface': comps[5]})
|
||||
cmd = 'netstat -f inet6 -rn | tail -n+5'
|
||||
out = __salt__['cmd.run'](cmd)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=True)
|
||||
for line in out.splitlines():
|
||||
comps = line.split()
|
||||
ret.append({
|
||||
@ -375,7 +375,7 @@ def _netstat_route_netbsd():
|
||||
'''
|
||||
ret = []
|
||||
cmd = 'netstat -f inet -rn | tail -n+5'
|
||||
out = __salt__['cmd.run'](cmd)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=True)
|
||||
for line in out.splitlines():
|
||||
comps = line.split()
|
||||
ret.append({
|
||||
@ -386,7 +386,7 @@ def _netstat_route_netbsd():
|
||||
'flags': comps[3],
|
||||
'interface': comps[6]})
|
||||
cmd = 'netstat -f inet6 -rn | tail -n+5'
|
||||
out = __salt__['cmd.run'](cmd)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=True)
|
||||
for line in out.splitlines():
|
||||
comps = line.split()
|
||||
ret.append({
|
||||
@ -405,7 +405,7 @@ def _netstat_route_openbsd():
|
||||
'''
|
||||
ret = []
|
||||
cmd = 'netstat -f inet -rn | tail -n+5'
|
||||
out = __salt__['cmd.run'](cmd)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=True)
|
||||
for line in out.splitlines():
|
||||
comps = line.split()
|
||||
ret.append({
|
||||
@ -416,7 +416,7 @@ def _netstat_route_openbsd():
|
||||
'flags': comps[2],
|
||||
'interface': comps[7]})
|
||||
cmd = 'netstat -f inet6 -rn | tail -n+5'
|
||||
out = __salt__['cmd.run'](cmd)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=True)
|
||||
for line in out.splitlines():
|
||||
comps = line.split()
|
||||
ret.append({
|
||||
|
@ -113,6 +113,8 @@ def _get_all_legacy_init_scripts():
|
||||
otherwise.
|
||||
'''
|
||||
ret = {}
|
||||
if not os.path.isdir(LEGACY_INIT_SCRIPT_PATH):
|
||||
return ret
|
||||
for fn in os.listdir(LEGACY_INIT_SCRIPT_PATH):
|
||||
if not os.path.isfile(os.path.join(LEGACY_INIT_SCRIPT_PATH, fn)) or fn.startswith('rc'):
|
||||
continue
|
||||
|
@ -5,18 +5,22 @@ from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
import hashlib
|
||||
import logging
|
||||
import distutils.version
|
||||
|
||||
__virtualname__ = 'rest_tornado'
|
||||
|
||||
logger = logging.getLogger(__virtualname__)
|
||||
|
||||
# we require at least 4.0, as that includes all the Future's stuff we use
|
||||
min_tornado_version = '4.0'
|
||||
has_tornado = False
|
||||
try:
|
||||
import tornado.httpserver
|
||||
import tornado.ioloop
|
||||
import tornado.web
|
||||
import tornado.gen
|
||||
|
||||
has_tornado = True
|
||||
import tornado
|
||||
if distutils.version.StrictVersion(tornado.version) >= \
|
||||
distutils.version.StrictVersion(min_tornado_version):
|
||||
has_tornado = True
|
||||
else:
|
||||
logger.error('rest_tornado requires at least tornado {0}'.format(min_tornado_version))
|
||||
except ImportError as err:
|
||||
has_tornado = False
|
||||
logger.error('ImportError! {0}'.format(str(err)))
|
||||
|
@ -61,6 +61,7 @@ Example output:
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
import pprint
|
||||
import textwrap
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
@ -255,9 +256,24 @@ def _format_host(host, data):
|
||||
hstrs.append((u'{0}{1}{2[ENDC]}'
|
||||
.format(tcolor, changes, colors)))
|
||||
|
||||
if 'warnings' in ret:
|
||||
rcounts.setdefault('warnings', 0)
|
||||
rcounts['warnings'] += 1
|
||||
wrapper = textwrap.TextWrapper(
|
||||
width=80,
|
||||
initial_indent=u' ' * 14,
|
||||
subsequent_indent=u' ' * 14
|
||||
)
|
||||
hstrs.append(
|
||||
u' {colors[YELLOW]} Warnings: {0}{colors[ENDC]}'.format(
|
||||
wrapper.fill('\n'.join(ret['warnings'])).lstrip(),
|
||||
colors=colors
|
||||
)
|
||||
)
|
||||
|
||||
# Append result counts to end of output
|
||||
colorfmt = u'{0}{1}{2[ENDC]}'
|
||||
rlabel = {True: u'Succeeded', False: u'Failed', None: u'Not Run'}
|
||||
rlabel = {True: u'Succeeded', False: u'Failed', None: u'Not Run', 'warnings': u'Warnings'}
|
||||
count_max_len = max([len(str(x)) for x in six.itervalues(rcounts)] or [0])
|
||||
label_max_len = max([len(x) for x in six.itervalues(rlabel)] or [0])
|
||||
line_max_len = label_max_len + count_max_len + 2 # +2 for ': '
|
||||
@ -320,8 +336,18 @@ def _format_host(host, data):
|
||||
)
|
||||
)
|
||||
|
||||
num_warnings = rcounts.get('warnings', 0)
|
||||
if num_warnings:
|
||||
hstrs.append(
|
||||
colorfmt.format(
|
||||
colors['YELLOW'],
|
||||
_counts(rlabel['warnings'], num_warnings),
|
||||
colors
|
||||
)
|
||||
)
|
||||
|
||||
totals = u'{0}\nTotal states run: {1:>{2}}'.format('-' * line_max_len,
|
||||
sum(six.itervalues(rcounts)),
|
||||
sum(six.itervalues(rcounts)) - rcounts.get('warnings', 0),
|
||||
line_max_len - 7)
|
||||
hstrs.append(colorfmt.format(colors['CYAN'], totals, colors))
|
||||
|
||||
|
@ -74,6 +74,7 @@ Use the following mysql database schema::
|
||||
`tag` varchar(255) NOT NULL,
|
||||
`data` varchar(1024) NOT NULL,
|
||||
`alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
`master_id` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tag` (`tag`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
@ -220,9 +221,9 @@ def event_return(events):
|
||||
for event in events:
|
||||
tag = event.get('tag', '')
|
||||
data = event.get('data', '')
|
||||
sql = '''INSERT INTO `salt_events` (`tag`, `data` )
|
||||
VALUES (%s, %s)'''
|
||||
cur.execute(sql, (tag, json.dumps(data)))
|
||||
sql = '''INSERT INTO `salt_events` (`tag`, `data`, `master_id` )
|
||||
VALUES (%s, %s, %s)'''
|
||||
cur.execute(sql, (tag, json.dumps(data), __opts__['id']))
|
||||
|
||||
|
||||
def save_load(jid, load):
|
||||
|
@ -45,18 +45,28 @@ from salt.ext.six.moves import range
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
STATE_INTERNAL_KEYWORDS = frozenset([
|
||||
# These are keywords passed to state module functions which are to be used
|
||||
# by salt in this state module and not on the actual state module function
|
||||
# These are keywords passed to state module functions which are to be used
|
||||
# by salt in this state module and not on the actual state module function
|
||||
STATE_REQUISITE_KEYWORDS = frozenset([
|
||||
'onchanges',
|
||||
'onfail',
|
||||
'prereq',
|
||||
'prerequired',
|
||||
'watch',
|
||||
'require',
|
||||
'listen',
|
||||
])
|
||||
STATE_REQUISITE_IN_KEYWORDS = frozenset([
|
||||
'onchanges_in',
|
||||
'onfail_in',
|
||||
'prereq_in',
|
||||
'watch_in',
|
||||
'require_in',
|
||||
'listen_in',
|
||||
])
|
||||
STATE_RUNTIME_KEYWORDS = frozenset([
|
||||
'check_cmd',
|
||||
'fail_hard',
|
||||
'fun',
|
||||
'listen',
|
||||
'listen_in',
|
||||
'onchanges',
|
||||
'onchanges_in',
|
||||
'onfail',
|
||||
'onfail_in',
|
||||
'onlyif',
|
||||
'order',
|
||||
'prereq',
|
||||
@ -65,27 +75,24 @@ STATE_INTERNAL_KEYWORDS = frozenset([
|
||||
'reload_modules',
|
||||
'reload_grains',
|
||||
'reload_pillar',
|
||||
'require',
|
||||
'require_in',
|
||||
'saltenv',
|
||||
'state',
|
||||
'unless',
|
||||
'use',
|
||||
'use_in',
|
||||
'watch',
|
||||
'watch_in',
|
||||
'__id__',
|
||||
'__sls__',
|
||||
'__env__',
|
||||
'__sls__',
|
||||
'__id__',
|
||||
'__pub_user',
|
||||
'__pub_arg',
|
||||
'__pub_jid',
|
||||
'__pub_fun',
|
||||
'__pub_tgt',
|
||||
'__pub_ret',
|
||||
'__pub_pid',
|
||||
'__pub_tgt_type',
|
||||
'__prereq__',
|
||||
])
|
||||
])
|
||||
|
||||
STATE_INTERNAL_KEYWORDS = STATE_REQUISITE_KEYWORDS.union(STATE_REQUISITE_IN_KEYWORDS).union(STATE_RUNTIME_KEYWORDS)
|
||||
|
||||
|
||||
def _odict_hashable(self):
|
||||
@ -1953,7 +1960,7 @@ class State(object):
|
||||
|
||||
def call_listen(self, chunks, running):
|
||||
'''
|
||||
Find all of the listen routines and call the associated mod_match runs
|
||||
Find all of the listen routines and call the associated mod_watch runs
|
||||
'''
|
||||
listeners = []
|
||||
crefs = {}
|
||||
@ -2001,6 +2008,9 @@ class State(object):
|
||||
low['sfun'] = chunk['fun']
|
||||
low['fun'] = 'mod_watch'
|
||||
low['__id__'] = 'listener_{0}'.format(low['__id__'])
|
||||
for req in STATE_REQUISITE_KEYWORDS:
|
||||
if req in low:
|
||||
low.pop(req)
|
||||
mod_watchers.append(low)
|
||||
ret = self.call_chunks(mod_watchers)
|
||||
running.update(ret)
|
||||
|
@ -193,6 +193,7 @@ def mounted(name,
|
||||
'defaults',
|
||||
'delay_connect',
|
||||
'intr',
|
||||
'loop',
|
||||
'nointr',
|
||||
'nobootwait',
|
||||
'nofail',
|
||||
|
@ -31,12 +31,12 @@ import types
|
||||
import warnings
|
||||
import string
|
||||
import locale
|
||||
from calendar import month_abbr as months
|
||||
|
||||
# Import 3rd-party libs
|
||||
import salt.ext.six as six
|
||||
# pylint: disable=import-error,redefined-builtin
|
||||
# pylint: disable=import-error
|
||||
from salt.ext.six.moves.urllib.parse import urlparse # pylint: disable=no-name-in-module
|
||||
# pylint: disable=redefined-builtin
|
||||
from salt.ext.six.moves import range
|
||||
from salt.ext.six.moves import zip
|
||||
from salt.ext.six.moves import map
|
||||
@ -844,6 +844,17 @@ def format_call(fun,
|
||||
continue
|
||||
extra[key] = copy.deepcopy(value)
|
||||
|
||||
# We'll be showing errors to the users until Salt Carbon comes out, after
|
||||
# which, errors will be raised instead.
|
||||
warn_until(
|
||||
'Carbon',
|
||||
'It\'s time to start raising `SaltInvocationError` instead of '
|
||||
'returning warnings',
|
||||
# Let's not show the deprecation warning on the console, there's no
|
||||
# need.
|
||||
_dont_call_warnings=True
|
||||
)
|
||||
|
||||
if extra:
|
||||
# Found unexpected keyword arguments, raise an error to the user
|
||||
if len(extra) == 1:
|
||||
@ -857,7 +868,7 @@ def format_call(fun,
|
||||
)
|
||||
)
|
||||
else:
|
||||
msg = '{0} and {1!r} are invalid keyword arguments for {2}'.format(
|
||||
msg = '{0} and {1!r} are invalid keyword arguments for {2!r}'.format(
|
||||
', '.join(['{0!r}'.format(e) for e in extra][:-1]),
|
||||
list(extra.keys())[-1],
|
||||
ret.get(
|
||||
@ -867,14 +878,20 @@ def format_call(fun,
|
||||
'{0}.{1}'.format(fun.__module__, fun.__name__)
|
||||
)
|
||||
)
|
||||
log.critical(
|
||||
|
||||
# Return a warning to the user explaining what's going on
|
||||
ret.setdefault('warnings', []).append(
|
||||
'{0}. If you were trying to pass additional data to be used '
|
||||
'in a template context, please populate \'context\' with '
|
||||
'\'key: value\' pairs.{1}'.format(
|
||||
'\'key: value\' pairs. Your approach will work until Salt '
|
||||
'Carbon is out.{1}'.format(
|
||||
msg,
|
||||
'' if 'full' not in ret else ' Please update your state files.'
|
||||
)
|
||||
)
|
||||
|
||||
# Lets pack the current extra kwargs as template context
|
||||
ret.setdefault('context', {}).update(extra)
|
||||
return ret
|
||||
|
||||
|
||||
@ -1002,9 +1019,55 @@ def fopen(*args, **kwargs):
|
||||
|
||||
NB! We still have small race condition between open and fcntl.
|
||||
|
||||
Supported optional Keyword Arguments:
|
||||
'''
|
||||
# Remove lock, uid, gid and mode from kwargs if present
|
||||
lock = kwargs.pop('lock', False)
|
||||
|
||||
lock: lock the file with fcntl
|
||||
if lock is True:
|
||||
warn_until(
|
||||
'Beryllium',
|
||||
'The \'lock\' keyword argument is deprecated and will be '
|
||||
'removed in Salt Beryllium. Please use '
|
||||
'\'salt.utils.flopen()\' for file locking while calling '
|
||||
'\'salt.utils.fopen()\'.'
|
||||
)
|
||||
return flopen(*args, **kwargs)
|
||||
|
||||
fhandle = open(*args, **kwargs)
|
||||
if is_fcntl_available():
|
||||
# modify the file descriptor on systems with fcntl
|
||||
# unix and unix-like systems only
|
||||
try:
|
||||
FD_CLOEXEC = fcntl.FD_CLOEXEC # pylint: disable=C0103
|
||||
except AttributeError:
|
||||
FD_CLOEXEC = 1 # pylint: disable=C0103
|
||||
old_flags = fcntl.fcntl(fhandle.fileno(), fcntl.F_GETFD)
|
||||
fcntl.fcntl(fhandle.fileno(), fcntl.F_SETFD, old_flags | FD_CLOEXEC)
|
||||
|
||||
return fhandle
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def flopen(*args, **kwargs):
|
||||
'''
|
||||
Shortcut for fopen with lock and context manager
|
||||
'''
|
||||
with fopen(*args, **kwargs) as fhandle:
|
||||
try:
|
||||
if is_fcntl_available(check_sunos=True):
|
||||
fcntl.flock(fhandle.fileno(), fcntl.LOCK_SH)
|
||||
yield fhandle
|
||||
finally:
|
||||
if is_fcntl_available(check_sunos=True):
|
||||
fcntl.flock(fhandle.fileno(), fcntl.LOCK_UN)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def fpopen(*args, **kwargs):
|
||||
'''
|
||||
Shortcut for fopen with extra uid, gid and mode options.
|
||||
|
||||
Supported optional Keyword Arguments:
|
||||
|
||||
mode: explicit mode to set. Mode is anything os.chmod
|
||||
would accept as input for mode. Works only on unix/unix
|
||||
@ -1019,53 +1082,26 @@ def fopen(*args, **kwargs):
|
||||
gid. Must be int. Works only on unix/unix like systems.
|
||||
|
||||
'''
|
||||
# Remove lock, uid, gid and mode from kwargs if present
|
||||
lock = kwargs.pop('lock', False)
|
||||
# Remove uid, gid and mode from kwargs if present
|
||||
uid = kwargs.pop('uid', -1) # -1 means no change to current uid
|
||||
gid = kwargs.pop('gid', -1) # -1 means no change to current gid
|
||||
mode = kwargs.pop('mode', None)
|
||||
with fopen(*args, **kwargs) as fhandle:
|
||||
path = args[0]
|
||||
d_stat = os.stat(path)
|
||||
|
||||
fhandle = open(*args, **kwargs)
|
||||
if is_fcntl_available():
|
||||
# modify the file descriptor on systems with fcntl
|
||||
# unix and unix-like systems only
|
||||
try:
|
||||
FD_CLOEXEC = fcntl.FD_CLOEXEC # pylint: disable=C0103
|
||||
except AttributeError:
|
||||
FD_CLOEXEC = 1 # pylint: disable=C0103
|
||||
old_flags = fcntl.fcntl(fhandle.fileno(), fcntl.F_GETFD)
|
||||
if lock and is_fcntl_available(check_sunos=True):
|
||||
fcntl.flock(fhandle.fileno(), fcntl.LOCK_SH)
|
||||
fcntl.fcntl(fhandle.fileno(), fcntl.F_SETFD, old_flags | FD_CLOEXEC)
|
||||
if hasattr(os, 'chown'):
|
||||
# if uid and gid are both -1 then go ahead with
|
||||
# no changes at all
|
||||
if (d_stat.st_uid != uid or d_stat.st_gid != gid) and \
|
||||
[i for i in (uid, gid) if i != -1]:
|
||||
os.chown(path, uid, gid)
|
||||
|
||||
path = args[0]
|
||||
d_stat = os.stat(path)
|
||||
if mode is not None:
|
||||
if d_stat.st_mode | mode != d_stat.st_mode:
|
||||
os.chmod(path, d_stat.st_mode | mode)
|
||||
|
||||
if hasattr(os, 'chown'):
|
||||
# if uid and gid are both -1 then go ahead with
|
||||
# no changes at all
|
||||
if (d_stat.st_uid != uid or d_stat.st_gid != gid) and \
|
||||
[i for i in (uid, gid) if i != -1]:
|
||||
os.chown(path, uid, gid)
|
||||
|
||||
if mode is not None:
|
||||
if d_stat.st_mode | mode != d_stat.st_mode:
|
||||
os.chmod(path, d_stat.st_mode | mode)
|
||||
|
||||
return fhandle
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def flopen(*args, **kwargs):
|
||||
'''
|
||||
Shortcut for fopen with lock and context manager
|
||||
'''
|
||||
with fopen(*args, lock=True, **kwargs) as fp_:
|
||||
try:
|
||||
yield fp_
|
||||
finally:
|
||||
if is_fcntl_available(check_sunos=True):
|
||||
fcntl.flock(fp_.fileno(), fcntl.LOCK_UN)
|
||||
yield fhandle
|
||||
|
||||
|
||||
def expr_match(line, expr):
|
||||
|
@ -52,7 +52,8 @@ class SaltCacheLoader(BaseLoader):
|
||||
Templates are cached like regular salt states
|
||||
and only loaded once per loader instance.
|
||||
'''
|
||||
def __init__(self, opts, saltenv='base', encoding='utf-8', env=None, pillar_rend=False):
|
||||
def __init__(self, opts, saltenv='base', encoding='utf-8', env=None,
|
||||
pillar_rend=False):
|
||||
if env is not None:
|
||||
salt.utils.warn_until(
|
||||
'Boron',
|
||||
@ -80,8 +81,7 @@ class SaltCacheLoader(BaseLoader):
|
||||
'''
|
||||
if not self._file_client:
|
||||
self._file_client = salt.fileclient.get_file_client(
|
||||
self.opts,
|
||||
self.pillar_rend)
|
||||
self.opts, self.pillar_rend)
|
||||
return self._file_client
|
||||
|
||||
def cache_file(self, template):
|
||||
@ -330,7 +330,7 @@ class SerializerExtension(Extension, object):
|
||||
'''
|
||||
|
||||
tags = set(['load_yaml', 'load_json', 'import_yaml', 'import_json',
|
||||
'load_text', 'import_text'])
|
||||
'load_text', 'import_text'])
|
||||
|
||||
def __init__(self, environment):
|
||||
super(SerializerExtension, self).__init__(environment)
|
||||
@ -359,7 +359,9 @@ class SerializerExtension(Extension, object):
|
||||
'''
|
||||
def explore(data):
|
||||
if isinstance(data, (dict, OrderedDict)):
|
||||
return PrintableDict([(key, explore(value)) for key, value in six.iteritems(data)])
|
||||
return PrintableDict(
|
||||
[(key, explore(value)) for key, value in six.iteritems(data)]
|
||||
)
|
||||
elif isinstance(data, (list, tuple, set)):
|
||||
return data.__class__([explore(value) for value in data])
|
||||
return data
|
||||
@ -382,7 +384,7 @@ class SerializerExtension(Extension, object):
|
||||
return yaml.safe_load(value)
|
||||
except AttributeError:
|
||||
raise TemplateRuntimeError(
|
||||
'Unable to load yaml from {0}'.format(value))
|
||||
'Unable to load yaml from {0}'.format(value))
|
||||
|
||||
def load_json(self, value):
|
||||
if isinstance(value, TemplateModule):
|
||||
@ -391,7 +393,7 @@ class SerializerExtension(Extension, object):
|
||||
return json.loads(value)
|
||||
except (ValueError, TypeError, AttributeError):
|
||||
raise TemplateRuntimeError(
|
||||
'Unable to load json from {0}'.format(value))
|
||||
'Unable to load json from {0}'.format(value))
|
||||
|
||||
def load_text(self, value):
|
||||
if isinstance(value, TemplateModule):
|
||||
@ -399,6 +401,8 @@ class SerializerExtension(Extension, object):
|
||||
|
||||
return value
|
||||
|
||||
_load_parsers = set(['load_yaml', 'load_json', 'load_text'])
|
||||
|
||||
def parse(self, parser):
|
||||
if parser.stream.current.value == 'import_yaml':
|
||||
return self.parse_yaml(parser)
|
||||
@ -406,7 +410,7 @@ class SerializerExtension(Extension, object):
|
||||
return self.parse_json(parser)
|
||||
elif parser.stream.current.value == 'import_text':
|
||||
return self.parse_text(parser)
|
||||
elif parser.stream.current.value in ('load_yaml', 'load_json', 'load_text'):
|
||||
elif parser.stream.current.value in self._load_parsers:
|
||||
return self.parse_load(parser)
|
||||
|
||||
parser.fail('Unknown format ' + parser.stream.current.value,
|
||||
@ -422,8 +426,8 @@ class SerializerExtension(Extension, object):
|
||||
parser.stream.expect('name:as')
|
||||
target = parser.parse_assign_target()
|
||||
macro_name = '_' + parser.free_identifier().name
|
||||
macro_body = parser.parse_statements(('name:endload',),
|
||||
drop_needle=True)
|
||||
macro_body = parser.parse_statements(
|
||||
('name:endload',), drop_needle=True)
|
||||
|
||||
return [
|
||||
nodes.Macro(
|
||||
|
@ -84,7 +84,7 @@ class SaltStackVersion(object):
|
||||
'Lithium' : (2015, 2),
|
||||
'Beryllium' : (MAX_SIZE - 105, 0),
|
||||
'Boron' : (MAX_SIZE - 104, 0),
|
||||
#'Carbon' : (MAX_SIZE - 103, 0),
|
||||
'Carbon' : (MAX_SIZE - 103, 0),
|
||||
#'Nitrogen' : (MAX_SIZE - 102, 0),
|
||||
#'Oxygen' : (MAX_SIZE - 101, 0),
|
||||
#'Fluorine' : (MAX_SIZE - 100, 0),
|
||||
|
@ -14,6 +14,7 @@ import integration
|
||||
from salt.config import cloud_providers_config
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import skipIf
|
||||
from salttesting.helpers import ensure_in_syspath, expensiveTest
|
||||
|
||||
ensure_in_syspath('../../../')
|
||||
@ -35,6 +36,7 @@ def __random_name(size=6):
|
||||
INSTANCE_NAME = __random_name()
|
||||
|
||||
|
||||
@skipIf(True, 'Skipping until we can figure out why the testrunner bails.')
|
||||
class EC2Test(integration.ShellCase):
|
||||
'''
|
||||
Integration tests for the EC2 cloud provider in Salt-Cloud
|
||||
|
@ -14,8 +14,8 @@ from salttesting.helpers import ensure_in_syspath
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt libs
|
||||
from salt.output import display_output
|
||||
import integration
|
||||
from salt.output import display_output
|
||||
|
||||
|
||||
class OutputReturnTest(integration.ShellCase):
|
||||
|
@ -159,6 +159,10 @@ class UtilsTestCase(TestCase):
|
||||
# Make sure we raise an error if we don't pass in the requisite number of arguments
|
||||
self.assertRaises(SaltInvocationError, utils.format_call, dummy_func, {'1': 2})
|
||||
|
||||
# Make sure we warn on invalid kwargs
|
||||
ret = utils.format_call(dummy_func, {'first': 2, 'second': 2, 'third': 3})
|
||||
self.assertGreaterEqual(len(ret['warnings']), 1)
|
||||
|
||||
ret = utils.format_call(dummy_func, {'first': 2, 'second': 2, 'third': 3},
|
||||
expected_extra_kws=('first', 'second', 'third'))
|
||||
self.assertDictEqual(ret, {'args': [], 'kwargs': {}})
|
||||
|
Loading…
Reference in New Issue
Block a user