mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge branch '2016.3' into '2016.11'
Conflicts: - salt/modules/win_pkg.py - tests/unit/daemons_test.py - tests/unit/states/file_test.py
This commit is contained in:
commit
fec9dec23a
@ -39,8 +39,7 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
# pylint: disable=import-error,no-name-in-module
|
from distutils.version import LooseVersion # pylint: disable=import-error,no-name-in-module
|
||||||
from distutils.version import LooseVersion
|
|
||||||
|
|
||||||
# Import third party libs
|
# Import third party libs
|
||||||
import salt.ext.six as six
|
import salt.ext.six as six
|
||||||
|
@ -413,28 +413,6 @@ def latest_version(*names, **kwargs):
|
|||||||
if len(names) == 0:
|
if len(names) == 0:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
# Initialize the return dict with empty strings, and populate namearch_map.
|
|
||||||
# namearch_map will provide a means of distinguishing between multiple
|
|
||||||
# matches for the same package name, for example a target of 'glibc' on an
|
|
||||||
# x86_64 arch would return both x86_64 and i686 versions.
|
|
||||||
#
|
|
||||||
# Note that the logic in the for loop below would place the osarch into the
|
|
||||||
# map for noarch packages, but those cases are accounted for when iterating
|
|
||||||
# through the 'yum list' results later on. If the match for that package is
|
|
||||||
# a noarch, then the package is assumed to be noarch, and the namearch_map
|
|
||||||
# is ignored.
|
|
||||||
ret = {}
|
|
||||||
namearch_map = {}
|
|
||||||
for name in names:
|
|
||||||
ret[name] = ''
|
|
||||||
try:
|
|
||||||
arch = name.rsplit('.', 1)[-1]
|
|
||||||
if arch not in salt.utils.pkg.rpm.ARCHES:
|
|
||||||
arch = __grains__['osarch']
|
|
||||||
except ValueError:
|
|
||||||
arch = __grains__['osarch']
|
|
||||||
namearch_map[name] = arch
|
|
||||||
|
|
||||||
repo_arg = _get_repo_options(**kwargs)
|
repo_arg = _get_repo_options(**kwargs)
|
||||||
exclude_arg = _get_excludes_option(**kwargs)
|
exclude_arg = _get_excludes_option(**kwargs)
|
||||||
|
|
||||||
@ -442,6 +420,8 @@ def latest_version(*names, **kwargs):
|
|||||||
if refresh:
|
if refresh:
|
||||||
refresh_db(**kwargs)
|
refresh_db(**kwargs)
|
||||||
|
|
||||||
|
cur_pkgs = list_pkgs(versions_as_list=True)
|
||||||
|
|
||||||
# Get available versions for specified package(s)
|
# Get available versions for specified package(s)
|
||||||
cmd = [_yum(), '--quiet']
|
cmd = [_yum(), '--quiet']
|
||||||
cmd.extend(repo_arg)
|
cmd.extend(repo_arg)
|
||||||
@ -456,7 +436,6 @@ def latest_version(*names, **kwargs):
|
|||||||
if out['stderr']:
|
if out['stderr']:
|
||||||
# Check first if this is just a matter of the packages being
|
# Check first if this is just a matter of the packages being
|
||||||
# up-to-date.
|
# up-to-date.
|
||||||
cur_pkgs = list_pkgs()
|
|
||||||
if not all([x in cur_pkgs for x in names]):
|
if not all([x in cur_pkgs for x in names]):
|
||||||
log.error(
|
log.error(
|
||||||
'Problem encountered getting latest version for the '
|
'Problem encountered getting latest version for the '
|
||||||
@ -473,13 +452,54 @@ def latest_version(*names, **kwargs):
|
|||||||
reverse=True
|
reverse=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _check_cur(pkg):
|
||||||
|
if pkg.name in cur_pkgs:
|
||||||
|
for installed_version in cur_pkgs[pkg.name]:
|
||||||
|
# If any installed version is greater than the one found by
|
||||||
|
# yum/dnf list available, then it is not an upgrade.
|
||||||
|
if salt.utils.compare_versions(ver1=installed_version,
|
||||||
|
oper='>',
|
||||||
|
ver2=pkg.version,
|
||||||
|
cmp_func=version_cmp):
|
||||||
|
return False
|
||||||
|
# pkg.version is greater than all installed versions
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
# Package is not installed
|
||||||
|
return True
|
||||||
|
|
||||||
|
ret = {}
|
||||||
for name in names:
|
for name in names:
|
||||||
|
# Derive desired pkg arch (for arch-specific packages) based on the
|
||||||
|
# package name(s) passed to the function. On a 64-bit OS, "pkgame"
|
||||||
|
# would be assumed to match the osarch, while "pkgname.i686" would
|
||||||
|
# have an arch of "i686". This desired arch is then compared against
|
||||||
|
# the updates derived from _yum_pkginfo() above, so that we can
|
||||||
|
# distinguish an update for a 32-bit version of a package from its
|
||||||
|
# 64-bit counterpart.
|
||||||
|
try:
|
||||||
|
arch = name.rsplit('.', 1)[-1]
|
||||||
|
if arch not in salt.utils.pkg.rpm.ARCHES:
|
||||||
|
arch = __grains__['osarch']
|
||||||
|
except ValueError:
|
||||||
|
arch = __grains__['osarch']
|
||||||
|
|
||||||
|
# This loop will iterate over the updates derived by _yum_pkginfo()
|
||||||
|
# above, which have been sorted descendingly by version number,
|
||||||
|
# ensuring that the latest available version for the named package is
|
||||||
|
# examined first. The call to _check_cur() will ensure that a package
|
||||||
|
# seen by yum as "available" will only be detected as an upgrade if it
|
||||||
|
# has a version higher than all currently-installed versions of the
|
||||||
|
# package.
|
||||||
for pkg in (x for x in updates if x.name == name):
|
for pkg in (x for x in updates if x.name == name):
|
||||||
if pkg.arch == 'noarch' or pkg.arch == namearch_map[name] \
|
# This if/or statement makes sure that we account for noarch
|
||||||
|
# packages as well as arch-specific packages.
|
||||||
|
if pkg.arch == 'noarch' or pkg.arch == arch \
|
||||||
or salt.utils.pkg.rpm.check_32(pkg.arch):
|
or salt.utils.pkg.rpm.check_32(pkg.arch):
|
||||||
ret[name] = pkg.version
|
if _check_cur(pkg):
|
||||||
# no need to check another match, if there was one
|
ret[name] = pkg.version
|
||||||
break
|
# no need to check another match, if there was one
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
ret[name] = ''
|
ret[name] = ''
|
||||||
|
|
||||||
|
@ -3718,9 +3718,16 @@ def comment(name, regex, char='#', backup='.bak'):
|
|||||||
return _error(ret, check_msg)
|
return _error(ret, check_msg)
|
||||||
|
|
||||||
unanchor_regex = regex.lstrip('^').rstrip('$')
|
unanchor_regex = regex.lstrip('^').rstrip('$')
|
||||||
|
comment_regex = char + unanchor_regex
|
||||||
|
|
||||||
|
# Check if the line is already commented
|
||||||
|
if __salt__['file.search'](name, comment_regex, multiline=True):
|
||||||
|
commented = True
|
||||||
|
else:
|
||||||
|
commented = False
|
||||||
|
|
||||||
# Make sure the pattern appears in the file before continuing
|
# Make sure the pattern appears in the file before continuing
|
||||||
if not __salt__['file.search'](name, regex, multiline=True):
|
if commented or not __salt__['file.search'](name, regex, multiline=True):
|
||||||
if __salt__['file.search'](name, unanchor_regex, multiline=True):
|
if __salt__['file.search'](name, unanchor_regex, multiline=True):
|
||||||
ret['comment'] = 'Pattern already commented'
|
ret['comment'] = 'Pattern already commented'
|
||||||
ret['result'] = True
|
ret['result'] = True
|
||||||
|
@ -1463,6 +1463,11 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
|
|||||||
# write a line to file
|
# write a line to file
|
||||||
with salt.utils.fopen(name, 'w+') as fp_:
|
with salt.utils.fopen(name, 'w+') as fp_:
|
||||||
fp_.write('comment_me')
|
fp_.write('comment_me')
|
||||||
|
|
||||||
|
# Look for changes with test=True: return should be "None" at the first run
|
||||||
|
ret = self.run_state('file.comment', test=True, name=name, regex='^comment')
|
||||||
|
self.assertSaltNoneReturn(ret)
|
||||||
|
|
||||||
# comment once
|
# comment once
|
||||||
ret = self.run_state('file.comment', name=name, regex='^comment')
|
ret = self.run_state('file.comment', name=name, regex='^comment')
|
||||||
# result is positive
|
# result is positive
|
||||||
@ -1479,6 +1484,11 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
|
|||||||
# line is still commented
|
# line is still commented
|
||||||
with salt.utils.fopen(name, 'r') as fp_:
|
with salt.utils.fopen(name, 'r') as fp_:
|
||||||
self.assertTrue(fp_.read().startswith('#comment'))
|
self.assertTrue(fp_.read().startswith('#comment'))
|
||||||
|
|
||||||
|
# Test previously commented file returns "True" now and not "None" with test=True
|
||||||
|
ret = self.run_state('file.comment', test=True, name=name, regex='^comment')
|
||||||
|
self.assertSaltTrueReturn(ret)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
os.remove(name)
|
os.remove(name)
|
||||||
|
|
||||||
|
@ -1005,14 +1005,14 @@ class FileTestCase(TestCase):
|
|||||||
|
|
||||||
mock_t = MagicMock(return_value=True)
|
mock_t = MagicMock(return_value=True)
|
||||||
mock_f = MagicMock(return_value=False)
|
mock_f = MagicMock(return_value=False)
|
||||||
mock = MagicMock(side_effect=[False, True, False, False])
|
|
||||||
with patch.object(os.path, 'isabs', mock_f):
|
with patch.object(os.path, 'isabs', mock_f):
|
||||||
comt = ('Specified file {0} is not an absolute path'.format(name))
|
comt = ('Specified file {0} is not an absolute path'.format(name))
|
||||||
ret.update({'comment': comt, 'name': name})
|
ret.update({'comment': comt, 'name': name})
|
||||||
self.assertDictEqual(filestate.comment(name, regex), ret)
|
self.assertDictEqual(filestate.comment(name, regex), ret)
|
||||||
|
|
||||||
with patch.object(os.path, 'isabs', mock_t):
|
with patch.object(os.path, 'isabs', mock_t):
|
||||||
with patch.dict(filestate.__salt__, {'file.search': mock}):
|
with patch.dict(filestate.__salt__,
|
||||||
|
{'file.search': MagicMock(side_effect=[True, True, True, False, False])}):
|
||||||
comt = ('Pattern already commented')
|
comt = ('Pattern already commented')
|
||||||
ret.update({'comment': comt, 'result': True})
|
ret.update({'comment': comt, 'result': True})
|
||||||
self.assertDictEqual(filestate.comment(name, regex), ret)
|
self.assertDictEqual(filestate.comment(name, regex), ret)
|
||||||
@ -1022,7 +1022,7 @@ class FileTestCase(TestCase):
|
|||||||
self.assertDictEqual(filestate.comment(name, regex), ret)
|
self.assertDictEqual(filestate.comment(name, regex), ret)
|
||||||
|
|
||||||
with patch.dict(filestate.__salt__,
|
with patch.dict(filestate.__salt__,
|
||||||
{'file.search': mock_t,
|
{'file.search': MagicMock(side_effect=[False, True, False, True, True]),
|
||||||
'file.comment': mock_t,
|
'file.comment': mock_t,
|
||||||
'file.comment_line': mock_t}):
|
'file.comment_line': mock_t}):
|
||||||
with patch.dict(filestate.__opts__, {'test': True}):
|
with patch.dict(filestate.__opts__, {'test': True}):
|
||||||
|
Loading…
Reference in New Issue
Block a user