mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch '2016.11' into '2017.7'
Conflicts: - salt/auth/pam.py - salt/master.py - tests/unit/test_target.py
This commit is contained in:
commit
430c913c8c
5 changed files with 57 additions and 21 deletions
|
@ -48,7 +48,6 @@ from salt.ext.six.moves import range # pylint: disable=import-error,redefined-b
|
|||
# Import 3rd-party libs
|
||||
import salt.ext.six as six
|
||||
|
||||
LIBPAM = CDLL(find_library('pam'))
|
||||
LIBC = CDLL(find_library('c'))
|
||||
|
||||
CALLOC = LIBC.calloc
|
||||
|
@ -121,6 +120,7 @@ class PamConv(Structure):
|
|||
|
||||
|
||||
try:
|
||||
LIBPAM = CDLL(find_library('pam'))
|
||||
PAM_START = LIBPAM.pam_start
|
||||
PAM_START.restype = c_int
|
||||
PAM_START.argtypes = [c_char_p, c_char_p, POINTER(PamConv),
|
||||
|
|
|
@ -234,13 +234,13 @@ def list_keys(hive, key=None, use_32bit_registry=False):
|
|||
for i in range(win32api.RegQueryInfoKey(handle)[0]):
|
||||
subkey = win32api.RegEnumKey(handle, i)
|
||||
if PY2:
|
||||
subkeys.append(_to_unicode(subkey))
|
||||
subkeys.append(_to_mbcs(subkey))
|
||||
else:
|
||||
subkeys.append(subkey)
|
||||
|
||||
handle.Close()
|
||||
|
||||
except WindowsError as exc: # pylint: disable=E0602
|
||||
except pywintypes.error as exc: # pylint: disable=E0602
|
||||
log.debug(exc)
|
||||
log.debug('Cannot find key: {0}\\{1}'.format(hive, key))
|
||||
return False, 'Cannot find key: {0}\\{1}'.format(hive, key)
|
||||
|
@ -300,7 +300,7 @@ def list_values(hive, key=None, use_32bit_registry=False, include_default=True):
|
|||
'vtype': registry.vtype_reverse[vtype],
|
||||
'success': True}
|
||||
values.append(value)
|
||||
except WindowsError as exc: # pylint: disable=E0602
|
||||
except pywintypes.error as exc: # pylint: disable=E0602
|
||||
log.debug(exc)
|
||||
log.debug(r'Cannot find key: {0}\{1}'.format(hive, key))
|
||||
return False, r'Cannot find key: {0}\{1}'.format(hive, key)
|
||||
|
|
|
@ -155,9 +155,9 @@ def latest_version(*names, **kwargs):
|
|||
|
||||
# check, whether latest available version
|
||||
# is newer than latest installed version
|
||||
if compare_versions(ver1=str(latest_available),
|
||||
oper='>',
|
||||
ver2=str(latest_installed)):
|
||||
if compare_versions(ver1=six.text_type(latest_available),
|
||||
oper=six.text_type('>'),
|
||||
ver2=six.text_type(latest_installed)):
|
||||
log.debug('Upgrade of {0} from {1} to {2} '
|
||||
'is available'.format(name,
|
||||
latest_installed,
|
||||
|
@ -467,7 +467,7 @@ def _get_reg_software():
|
|||
if d_name not in ignore_list:
|
||||
# some MS Office updates don't register a product name which means
|
||||
# their information is useless
|
||||
reg_software.update({d_name: str(d_vers)})
|
||||
reg_software.update({d_name: six.text_type(d_vers)})
|
||||
|
||||
for reg_key in __salt__['reg.list_keys'](hive, key):
|
||||
update(hive, key, reg_key, False)
|
||||
|
@ -876,7 +876,7 @@ def _get_source_sum(source_hash, file_path, saltenv):
|
|||
schemes = ('salt', 'http', 'https', 'ftp', 'swift', 's3', 'file')
|
||||
invalid_hash_msg = ("Source hash '{0}' format is invalid. It must be in "
|
||||
"the format <hash type>=<hash>").format(source_hash)
|
||||
source_hash = str(source_hash)
|
||||
source_hash = six.text_type(source_hash)
|
||||
source_hash_scheme = _urlparse(source_hash).scheme
|
||||
|
||||
if source_hash_scheme in schemes:
|
||||
|
@ -1128,7 +1128,7 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
|
|||
# as a float it must be converted to a string in order for
|
||||
# string matching to work.
|
||||
if not isinstance(version_num, six.string_types) and version_num is not None:
|
||||
version_num = str(version_num)
|
||||
version_num = six.text_type(version_num)
|
||||
|
||||
if not version_num:
|
||||
# following can be version number or latest
|
||||
|
@ -1347,6 +1347,10 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
|
|||
__salt__['system.set_reboot_required_witnessed']()
|
||||
ret[pkg_name] = {'install status': 'success, reboot required'}
|
||||
changed.append(pkg_name)
|
||||
elif result['retcode'] == 1641:
|
||||
# 1641 is ERROR_SUCCESS_REBOOT_INITIATED
|
||||
ret[pkg_name] = {'install status': 'success, reboot initiated'}
|
||||
changed.append(pkg_name)
|
||||
else:
|
||||
log.error('Failed to install {0}'.format(pkg_name))
|
||||
log.error('retcode {0}'.format(result['retcode']))
|
||||
|
@ -1485,7 +1489,7 @@ def remove(name=None, pkgs=None, version=None, **kwargs):
|
|||
# as a float it must be converted to a string in order for
|
||||
# string matching to work.
|
||||
if not isinstance(version_num, six.string_types) and version_num is not None:
|
||||
version_num = str(version_num)
|
||||
version_num = six.text_type(version_num)
|
||||
if version_num not in pkginfo and 'latest' in pkginfo:
|
||||
version_num = 'latest'
|
||||
elif 'latest' in pkginfo:
|
||||
|
@ -1639,6 +1643,18 @@ def remove(name=None, pkgs=None, version=None, **kwargs):
|
|||
if not result['retcode']:
|
||||
ret[pkgname] = {'uninstall status': 'success'}
|
||||
changed.append(pkgname)
|
||||
elif result['retcode'] == 3010:
|
||||
# 3010 is ERROR_SUCCESS_REBOOT_REQUIRED
|
||||
report_reboot_exit_codes = kwargs.pop(
|
||||
'report_reboot_exit_codes', True)
|
||||
if report_reboot_exit_codes:
|
||||
__salt__['system.set_reboot_required_witnessed']()
|
||||
ret[pkgname] = {'uninstall status': 'success, reboot required'}
|
||||
changed.append(pkgname)
|
||||
elif result['retcode'] == 1641:
|
||||
# 1641 is ERROR_SUCCESS_REBOOT_INITIATED
|
||||
ret[pkgname] = {'uninstall status': 'success, reboot initiated'}
|
||||
changed.append(pkgname)
|
||||
else:
|
||||
log.error('Failed to remove %s', pkgname)
|
||||
log.error('retcode %s', result['retcode'])
|
||||
|
@ -1826,9 +1842,9 @@ def compare_versions(ver1='', oper='==', ver2=''):
|
|||
|
||||
# Support version being the special meaning of 'latest'
|
||||
if ver1 == 'latest':
|
||||
ver1 = str(sys.maxsize)
|
||||
ver1 = six.text_type(sys.maxsize)
|
||||
if ver2 == 'latest':
|
||||
ver2 = str(sys.maxsize)
|
||||
ver2 = six.text_type(sys.maxsize)
|
||||
# Support version being the special meaning of 'Not Found'
|
||||
if ver1 == 'Not Found':
|
||||
ver1 = '0.0.0.0.0'
|
||||
|
|
|
@ -148,15 +148,25 @@ def nodegroup_comp(nodegroup, nodegroups, skip=None, first_call=True):
|
|||
# No compound operators found in nodegroup definition. Check for
|
||||
# group type specifiers
|
||||
group_type_re = re.compile('^[A-Z]@')
|
||||
regex_chars = ['(', '[', '{', '\\', '?''}])']
|
||||
if not [x for x in ret if '*' in x or group_type_re.match(x)]:
|
||||
# No group type specifiers and no wildcards. Treat this as a
|
||||
# list of nodenames.
|
||||
joined = 'L@' + ','.join(ret)
|
||||
log.debug(
|
||||
'Nodegroup \'%s\' (%s) detected as list of nodenames. '
|
||||
'Assuming compound matching syntax of \'%s\'',
|
||||
nodegroup, ret, joined
|
||||
)
|
||||
# No group type specifiers and no wildcards.
|
||||
# Treat this as an expression.
|
||||
if [x for x in ret if x in [x for y in regex_chars if y in x]]:
|
||||
joined = 'E@' + ','.join(ret)
|
||||
log.debug(
|
||||
'Nodegroup \'%s\' (%s) detected as an expression. '
|
||||
'Assuming compound matching syntax of \'%s\'',
|
||||
nodegroup, ret, joined
|
||||
)
|
||||
else:
|
||||
# Treat this as a list of nodenames.
|
||||
joined = 'L@' + ','.join(ret)
|
||||
log.debug(
|
||||
'Nodegroup \'%s\' (%s) detected as list of nodenames. '
|
||||
'Assuming compound matching syntax of \'%s\'',
|
||||
nodegroup, ret, joined
|
||||
)
|
||||
# Return data must be a list of compound matching components
|
||||
# to be fed into compound matcher. Enclose return data in list.
|
||||
return [joined]
|
||||
|
|
|
@ -127,6 +127,16 @@ class NodegroupCompTest(TestCase):
|
|||
expected_ret = ['L@foo.domain.com,bar.domain.com,baz.domain.com', 'or', 'bl*.domain.com']
|
||||
self.assertListEqual(ret, expected_ret)
|
||||
|
||||
def test_simple_expression_nodegroup(self):
|
||||
'''
|
||||
Smoke test a nodegroup with a simple expression. No recursion.
|
||||
'''
|
||||
simple_nodegroup = {'group1': '[foo,bar,baz].domain.com'}
|
||||
|
||||
ret = salt.utils.minions.nodegroup_comp('group1', simple_nodegroup)
|
||||
expected_ret = ['E@[foo,bar,baz].domain.com']
|
||||
self.assertListEqual(ret, expected_ret)
|
||||
|
||||
def test_simple_recurse(self):
|
||||
'''
|
||||
Test a case where one nodegroup contains a second nodegroup
|
||||
|
|
Loading…
Add table
Reference in a new issue