Merge pull request #37102 from rallytime/merge-develop

[develop] Merge forward from carbon to develop
This commit is contained in:
Mike Place 2016-10-20 14:39:15 +09:00 committed by GitHub
commit 7dbee2d599
7 changed files with 109 additions and 80 deletions

View File

@ -14,9 +14,6 @@ init-hook="
aXIsICdTY3JpcHRzJyksICdhY3RpdmF0ZV90aGlzLnB5JykKCiAgICBleGVjZmlsZShhY3RpdmF0 \
ZV90aGlzLCBkaWN0KF9fZmlsZV9fPWFjdGl2YXRlX3RoaXMpKQo='.decode('base64')"
# Profiled execution.
profile=no
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
@ -208,10 +205,6 @@ reports=no
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Add a comment according to your evaluation note. This is used by the global
# evaluation report (RP0004).
comment=no
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
@ -307,10 +300,6 @@ ignored-modules=
# (useful for classes with attributes dynamically set).
ignored-classes=SQLObject
# When zope mode is activated, add a predefined set of Zope acquired attributes
# to generated-members.
zope=no
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E0201 when accessed. Python regular
# expressions are accepted.
@ -337,9 +326,6 @@ ignore-imports=no
[BASIC]
# Required attributes for module, separated by a comma
required-attributes=
# List of builtins function names that should not be used, separated by a comma
bad-functions=map,filter,apply,input
@ -442,10 +428,6 @@ spelling-store-unknown-words=no
[CLASSES]
# List of interface methods to ignore, separated by a comma. This is used for
# instance to not check methods defines in Zope's Interface base class.
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp

View File

@ -132,36 +132,26 @@ Using Jinja templating, only one match entry needs to be defined.
Writing Grains
==============
Consider adding grains when the information is needed for targeting within
top.sls or salt cli. The grains should only contain the **bare minimum data**
required for targeting. The "name" and "data structure" of the grain should be
design to support many platforms, operating systems or applications. Most of the
time an "execution module" called from within Jinja template will provide the
necessary detail information for a Salt State. Consider if the idea for a grain
should be developed as a execution module rather than a grain or a combination
of both keeping minimum data within the grain.
The grains are derived by executing all of the "public" functions (i.e. those
which do not begin with an underscore) found in the modules located in the
Salt's core grains code, followed by those in any custom grains modules. The
functions in a grains module must return a Python :ref:`dict
<python2:typesmapping>`, where the dictionary keys are the names of grains, and
each key's value is that value for that grain.
The grains interface is derived by executing
all of the "public" functions found in the modules located in the grains
package or the custom grains directory. The functions in the modules of
the grains must return a Python :ref:`dict <python2:typesmapping>`, where the
keys in the :ref:`dict <python2:typesmapping>` are the names of the grains and
the values are the values.
Custom grains should be placed in a ``_grains`` directory located under the
:conf_master:`file_roots` specified by the master config file. The default path
would be ``/srv/salt/_grains``. Custom grains will be
distributed to the minions when :mod:`state.highstate
Custom grains modules should be placed in a subdirectory named ``_grains``
located under the :conf_master:`file_roots` specified by the master config
file. The default path would be ``/srv/salt/_grains``. Custom grains modules
will be distributed to the minions when :mod:`state.highstate
<salt.modules.state.highstate>` is run, or by executing the
:mod:`saltutil.sync_grains <salt.modules.saltutil.sync_grains>` or
:mod:`saltutil.sync_all <salt.modules.saltutil.sync_all>` functions.
Grains are easy to write, and only need to return a dictionary. A common
approach would be code something similar to the following:
Grains modules are easy to write, and (as noted above) only need to return a
dictionary. For example:
.. code-block:: python
#!/usr/bin/env python
def yourfunction():
# initialize a grains dictionary
grains = {}
@ -170,9 +160,37 @@ approach would be code something similar to the following:
grains['anothergrain'] = 'somevalue'
return grains
Before adding a grain to Salt, consider what the grain is and remember that
grains need to be static data. If the data is something that is likely to
change, consider using :doc:`Pillar <../pillar/index>` instead.
The name of the function does not matter and will not factor into the grains
data at all; only the keys/values returned become part of the grains.
When to Use a Custom Grain
--------------------------
Before adding new grains, consider what the data is and remember that grains
should (for the most part) be static data.
If the data is something that is likely to change, consider using :doc:`Pillar
<../pillar/index>` or an execution module instead. If it's a simple set of
key/value pairs, pillar is a good match. If compiling the information requires
that system commands be run, then putting this information in an execution
module is likely a better idea.
Good candidates for grains are data that is useful for targeting minions in the
:ref:`top file <states-top>` or the Salt CLI. The name and data structure of
the grain should be designed to support many platforms, operating systems or
applications. Also, keep in mind that Jinja templating in Salt supports
referencing pillar data as well as invoking functions from execution modules,
so there's no need to place information in grains to make it available to Jinja
templates. For example:
.. code-block:: text
...
...
{{ salt['module.function_name']('argument_1', 'argument_2') }}
{{ pillar['my_pillar_key'] }}
...
...
.. warning::

View File

@ -1,11 +1,21 @@
==================================
======
Fedora
==================================
======
Beginning with version 0.9.4, Salt has been available in the primary Fedora
repositories and `EPEL`_. It is installable using yum. Fedora will have more
up to date versions of Salt than other members of the Red Hat family, which
makes it a great place to help improve Salt!
repositories and `EPEL`_. It is installable using ``yum`` or ``dnf``, depending
on your version of Fedora.
.. note::
Released versions of Salt starting with ``2015.5.2`` through ``2016.3.2``
do not have Fedora packages available though `EPEL`_. To install a version
of Salt within this release array, please use SaltStack's `Bootstrap Script`_
and use the git method of installing Salt using the version's associated
release tag.
Release ``2016.3.3`` and onward will have packaged versions available via
`EPEL`_.
**WARNING**: Fedora 19 comes with systemd 204. Systemd has known bugs fixed in
later revisions that prevent the salt-master from starting reliably or opening
@ -31,8 +41,6 @@ will be one master and multiple minions.
yum install salt-master
yum install salt-minion
.. _`EPEL`: http://fedoraproject.org/wiki/EPEL
Installing from ``updates-testing``
-----------------------------------
@ -63,8 +71,6 @@ will need to provide your own systemd service unit.
Installation from pip:
.. _`PyPI`: https://pypi.python.org/pypi/salt
.. code-block:: bash
pip install salt
@ -111,3 +117,7 @@ To start the Minion:
systemctl start salt-minion.service
Now go to the :doc:`Configuring Salt</ref/configuration/index>` page.
.. _`Bootstrap Script`: https://github.com/saltstack/salt-bootstrap
.. _`EPEL`: http://fedoraproject.org/wiki/EPEL
.. _`PyPI`: https://pypi.python.org/pypi/salt

View File

@ -315,6 +315,10 @@ def _run(cmd,
raise CommandExecutionError('VT not available on windows')
if shell.lower().strip() == 'powershell':
# Strip whitespace
if isinstance(cmd, six.string_types):
cmd = cmd.strip()
# If we were called by script(), then fakeout the Windows
# shell to run a Powershell script.
# Else just run a Powershell command.
@ -324,11 +328,11 @@ def _run(cmd,
# The last item in the list [-1] is the current method.
# The third item[2] in each tuple is the name of that method.
if stack[-2][2] == 'script':
cmd = 'Powershell -NonInteractive -ExecutionPolicy Bypass -File ' + cmd
cmd = 'Powershell -NonInteractive -NoProfile -ExecutionPolicy Bypass -File ' + cmd
elif encoded_cmd:
cmd = 'Powershell -NonInteractive -EncodedCommand {0}'.format(cmd)
else:
cmd = 'Powershell -NonInteractive "{0}"'.format(cmd.replace('"', '\\"'))
cmd = 'Powershell -NonInteractive -NoProfile "{0}"'.format(cmd.replace('"', '\\"'))
# munge the cmd and cwd through the template
(cmd, cwd) = _render_cmd(cmd, cwd, template, saltenv, pillarenv, pillar_override)

View File

@ -1283,7 +1283,7 @@ def _mkstemp_copy(path,
temp_file = None
# Create the temp file
try:
temp_file = salt.utils.files.mkstemp()
temp_file = salt.utils.files.mkstemp(prefix=salt.utils.files.TEMPFILE_PREFIX)
except (OSError, IOError) as exc:
raise CommandExecutionError(
"Unable to create temp file. "
@ -4066,7 +4066,8 @@ def check_file_meta(
if contents is not None:
# Write a tempfile with the static contents
tmp = salt.utils.files.mkstemp(text=True)
tmp = salt.utils.files.mkstemp(prefix=salt.utils.files.TEMPFILE_PREFIX,
text=True)
if salt.utils.is_windows():
contents = os.linesep.join(contents.splitlines())
with salt.utils.fopen(tmp, 'w') as tmp_:
@ -4336,7 +4337,8 @@ def manage_file(name,
if contents is not None:
# Write the static contents to a temporary file
tmp = salt.utils.files.mkstemp(text=True)
tmp = salt.utils.files.mkstemp(prefix=salt.utils.files.TEMPFILE_PREFIX,
text=True)
if salt.utils.is_windows():
contents = os.linesep.join(contents.splitlines())
with salt.utils.fopen(tmp, 'w') as tmp_:
@ -4518,7 +4520,8 @@ def manage_file(name,
if contents is not None:
# Write the static contents to a temporary file
tmp = salt.utils.files.mkstemp(text=True)
tmp = salt.utils.files.mkstemp(prefix=salt.utils.files.TEMPFILE_PREFIX,
text=True)
if salt.utils.is_windows():
contents = os.linesep.join(contents.splitlines())
with salt.utils.fopen(tmp, 'w') as tmp_:

View File

@ -26,9 +26,11 @@ def _check_error(result, success_message):
ret = {}
if 'ERROR' in result:
if 'already started' in result:
ret['comment'] = success_message
elif 'not running' in result:
if any(substring in result for substring in [
'already started',
'not running',
'process group already active'
]):
ret['comment'] = success_message
else:
ret['comment'] = result
@ -154,25 +156,14 @@ def running(name,
changes = []
just_updated = False
if to_add:
comment = 'Adding service: {0}'.format(name)
__salt__['supervisord.reread'](
user=user,
conf_file=conf_file,
bin_env=bin_env
)
result = __salt__['supervisord.add'](
name,
user=user,
conf_file=conf_file,
bin_env=bin_env
)
ret.update(_check_error(result, comment))
changes.append(comment)
log.debug(comment)
elif update:
if update:
# If the state explicitly asks to update, we don't care if the process
# is being added or not, since it'll take care of this for us,
# so give this condition priority in order
#
# That is, unless `to_add` somehow manages to contain processes
# we don't want running, in which case adding them may be a mistake
comment = 'Updating supervisor'
result = __salt__['supervisord.update'](
user=user,
@ -184,6 +175,27 @@ def running(name,
if '{0}: updated'.format(name) in result:
just_updated = True
elif to_add:
# Not sure if this condition is precise enough.
comment = 'Adding service: {0}'.format(name)
__salt__['supervisord.reread'](
user=user,
conf_file=conf_file,
bin_env=bin_env
)
# Causes supervisorctl to throw `ERROR: process group already active`
# if process group exists. At this moment, I'm not sure how to handle
# this outside of grepping out the expected string in `_check_error`.
result = __salt__['supervisord.add'](
name,
user=user,
conf_file=conf_file,
bin_env=bin_env
)
ret.update(_check_error(result, comment))
changes.append(comment)
log.debug(comment)
is_stopped = None

View File

@ -346,7 +346,7 @@ class ReactWrap(object):
Wrap Caller to enable executing :ref:`caller modules <all-salt.caller>`
'''
log.debug("in caller with fun {0} args {1} kwargs {2}".format(fun, args, kwargs))
args = kwargs['args']
args = kwargs.get('args', [])
if 'caller' not in self.client_cache:
self.client_cache['caller'] = salt.client.Caller(self.opts['conf_file'])
try: