Merge remote-tracking branch 'upstream/2016.11' into merge-2017.7

Conflicts:
- doc/_themes/saltstack2/layout.html
- salt/auth/__init__.py
- salt/utils/schedule.py
This commit is contained in:
Erik Johnson 2017-06-28 20:27:32 -05:00
commit f13ddeb394
11 changed files with 66 additions and 22 deletions

View file

@ -255,8 +255,8 @@
<div class="col-sm-6">
<a href="https://saltstack.com/support" target="_blank"><img class="nolightbox footer-banner center" src="{{ pathto('_static/images/footer-support.png', 1) }}"/></a>
<a href="https://saltstack.com/saltstack-enterprise/" target="_blank"><img class="nolightbox footer-banner center" src="{{ pathto('_static/images/enterprise_ad.jpg', 1) }}"/></a>
<a href="http://saltconf.com" target="_blank"><img class="nolightbox footer-banner center" src="{{ pathto('_static/images/DOCBANNER.jpg', 1) }}"/></a>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 790 KiB

View file

@ -31,6 +31,7 @@ import salt.config
import salt.loader
import salt.transport.client
import salt.utils
import salt.utils.files
import salt.utils.minions
import salt.payload
@ -227,8 +228,9 @@ class LoadAuth(object):
tdata['groups'] = load['groups']
try:
with salt.utils.fopen(t_path, 'w+b') as fp_:
fp_.write(self.serial.dumps(tdata))
with salt.utils.files.set_umask(0o177):
with salt.utils.fopen(t_path, 'w+b') as fp_:
fp_.write(self.serial.dumps(tdata))
except (IOError, OSError):
log.warning('Authentication failure: can not write token file "{0}".'.format(t_path))
return {}
@ -666,14 +668,12 @@ class Resolver(object):
tdata = self._send_token_request(load)
if 'token' not in tdata:
return tdata
oldmask = os.umask(0o177)
try:
with salt.utils.fopen(self.opts['token_file'], 'w+') as fp_:
fp_.write(tdata['token'])
with salt.utils.files.set_umask(0o177):
with salt.utils.fopen(self.opts['token_file'], 'w+') as fp_:
fp_.write(tdata['token'])
except (IOError, OSError):
pass
finally:
os.umask(oldmask)
return tdata
def mk_token(self, load):

View file

@ -2534,8 +2534,9 @@ def del_repo(repo, basedir=None, **kwargs): # pylint: disable=W0613
if stanza == repo:
continue
comments = ''
if 'comments' in filerepos[stanza]:
comments = '\n'.join(filerepos[stanza]['comments'])
if 'comments' in six.iterkeys(filerepos[stanza]):
comments = salt.utils.pkg.rpm.combine_comments(
filerepos[stanza]['comments'])
del filerepos[stanza]['comments']
content += '\n[{0}]'.format(stanza)
for line in filerepos[stanza]:
@ -2670,7 +2671,8 @@ def mod_repo(repo, basedir=None, **kwargs):
for stanza in six.iterkeys(filerepos):
comments = ''
if 'comments' in six.iterkeys(filerepos[stanza]):
comments = '\n'.join(filerepos[stanza]['comments'])
comments = salt.utils.pkg.rpm.combine_comments(
filerepos[stanza]['comments'])
del filerepos[stanza]['comments']
content += '\n[{0}]'.format(stanza)
for line in six.iterkeys(filerepos[stanza]):

View file

@ -761,7 +761,7 @@ class State(object):
agg_opt = low['aggregate']
if agg_opt is True:
agg_opt = [low['state']]
else:
elif not isinstance(agg_opt, list):
return low
if low['state'] in agg_opt and not low.get('__agg__'):
agg_fun = '{0}.mod_aggregate'.format(low['state'])

View file

@ -96,6 +96,7 @@ from salt.modules.aptpkg import _strip_uri
from salt.state import STATE_INTERNAL_KEYWORDS as _STATE_INTERNAL_KEYWORDS
import salt.utils
import salt.utils.pkg.deb
import salt.utils.pkg.rpm
def __virtual__():
@ -403,6 +404,12 @@ def managed(name, ppa=None, **kwargs):
salt.utils.pkg.deb.combine_comments(kwargs['comments'])
if pre_comments != post_comments:
break
elif kwarg == 'comments' and os_family == 'redhat':
precomments = salt.utils.pkg.rpm.combine_comments(pre[kwarg])
kwargcomments = salt.utils.pkg.rpm.combine_comments(
sanitizedkwargs[kwarg])
if precomments != kwargcomments:
break
else:
if os_family in ('redhat', 'suse') \
and any(isinstance(x, bool) for x in

View file

@ -253,3 +253,19 @@ def wait_lock(path, lock_fn=None, timeout=5, sleep=0.1, time_start=None):
if obtained_lock:
os.remove(lock_fn)
log.trace('Write lock for %s (%s) released', path, lock_fn)
@contextlib.contextmanager
def set_umask(mask):
'''
Temporarily set the umask and restore once the contextmanager exits
'''
if salt.utils.is_windows():
# Don't attempt on Windows
yield
else:
try:
orig_mask = os.umask(mask)
yield
finally:
os.umask(orig_mask)

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
'''
Common functions for working with RPM packages
Common functions for working with deb packages
'''
# Import python libs

View file

@ -9,6 +9,10 @@ import collections
import logging
import subprocess
# Import 3rd-party libs
from salt.ext import six
from salt.ext.six.moves import range # pylint: disable=redefined-builtin
log = logging.getLogger(__name__)
# These arches compiled from the rpmUtils.arch python module source
@ -98,3 +102,20 @@ def parse_pkginfo(line, osarch=None):
version = ':'.join((epoch, version))
return pkginfo(name, version, arch, repoid)
def combine_comments(comments):
'''
Given a list of comments, strings, a single comment or a single string,
return a single string of text containing all of the comments, prepending
the '#' and joining with newlines as necessary.
'''
if not isinstance(comments, list):
comments = [comments]
for idx in range(len(comments)):
if not isinstance(comments[idx], six.string_types):
comments[idx] = str(comments[idx])
comments[idx] = comments[idx].strip()
if not comments[idx].startswith('#'):
comments[idx] = '#' + comments[idx]
return '\n'.join(comments)

View file

@ -295,14 +295,7 @@ def render_jinja_tmpl(tmplstr, context, tmplpath=None):
if not saltenv:
if tmplpath:
# i.e., the template is from a file outside the state tree
#
# XXX: FileSystemLoader is not being properly instantiated here is
# it? At least it ain't according to:
#
# http://jinja.pocoo.org/docs/api/#jinja2.FileSystemLoader
loader = jinja2.FileSystemLoader(
context, os.path.dirname(tmplpath))
loader = jinja2.FileSystemLoader(os.path.dirname(tmplpath))
else:
loader = salt.utils.jinja.SaltCacheLoader(opts, saltenv, pillar_rend=context.get('_pillar_rend', False))

View file

@ -104,8 +104,13 @@ class NetworkTestCase(TestCase):
self.assertEqual(ret, '10.1.2.3')
def test_host_to_ips(self):
'''
NOTE: When this test fails it's usually because the IP address has
changed. In these cases, we just need to update the IP address in the
assertion.
'''
ret = network.host_to_ips('www.saltstack.com')
self.assertEqual(ret, ['104.199.122.13'])
self.assertEqual(ret, ['104.197.168.128'])
def test_generate_minion_id(self):
self.assertTrue(network.generate_minion_id())