diff --git a/.kitchen.yml b/.kitchen.yml index 6dc1a7faf4..2988e0083b 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -1,6 +1,6 @@ --- <% vagrant = system('gem list -i kitchen-vagrant 2>/dev/null >/dev/null') %> -<% version = '2017.7.6' %> +<% version = '2018.3.3' %> <% platformsfile = ENV['SALT_KITCHEN_PLATFORMS'] || '.kitchen/platforms.yml' %> <% driverfile = ENV['SALT_KITCHEN_DRIVER'] || '.kitchen/driver.yml' %> <% verifierfile = ENV['SALT_KITCHEN_VERIFIER'] || '.kitchen/verifier.yml' %> diff --git a/salt/client/__init__.py b/salt/client/__init__.py index e8eca28b24..d7cd3f18b6 100644 --- a/salt/client/__init__.py +++ b/salt/client/__init__.py @@ -1208,6 +1208,13 @@ class LocalClient(object): if raw['data']['return'] == {}: continue + # if the minion throws an exception containing the word "return" + # the master will try to handle the string as a dict in the next + # step. Check if we have a string, log the issue and continue. + if isinstance(raw['data']['return'], six.string_types): + log.error("unexpected return from minion: %s", raw) + continue + if 'return' in raw['data']['return'] and \ raw['data']['return']['return'] == {}: continue diff --git a/salt/modules/aptpkg.py b/salt/modules/aptpkg.py index b5b3784d90..3a42a909c6 100644 --- a/salt/modules/aptpkg.py +++ b/salt/modules/aptpkg.py @@ -14,7 +14,6 @@ from __future__ import absolute_import, print_function, unicode_literals # Import python libs import copy -import fnmatch import os import re import logging @@ -274,6 +273,7 @@ def latest_version(*names, **kwargs): return ret[names[0]] return ret + # available_version is being deprecated available_version = salt.utils.functools.alias_function(latest_version, 'available_version') @@ -1543,12 +1543,22 @@ def list_repo_pkgs(*args, **kwargs): # pylint: disable=unused-import salt '*' pkg.list_repo_pkgs salt '*' pkg.list_repo_pkgs foo bar baz ''' - out = _call_apt(['apt-cache', 'dump'], scope=False, ignore_retcode=True) + if args: + # Get only information about packages in args + cmd = ['apt-cache', 'show'] + [arg for arg in args] + else: + # Get information about all available packages + cmd = ['apt-cache', 'dump'] + + out = _call_apt(cmd, scope=False, ignore_retcode=True) + ret = {} pkg_name = None skip_pkg = False new_pkg = re.compile('^Package: (.+)') for line in salt.utils.itertools.split(out['stdout'], '\n'): + if not line.strip(): + continue try: cur_pkg = new_pkg.match(line).group(1) except AttributeError: @@ -1556,22 +1566,10 @@ def list_repo_pkgs(*args, **kwargs): # pylint: disable=unused-import else: if cur_pkg != pkg_name: pkg_name = cur_pkg - if args: - for arg in args: - if fnmatch.fnmatch(pkg_name, arg): - skip_pkg = False - break - else: - # Package doesn't match any of the passed args, skip it - skip_pkg = True - else: - # No args passed, we're getting all packages - skip_pkg = False continue - if not skip_pkg: - comps = line.strip().split(None, 1) - if comps[0] == 'Version:': - ret.setdefault(pkg_name, []).append(comps[1]) + comps = line.strip().split(None, 1) + if comps[0] == 'Version:': + ret.setdefault(pkg_name, []).append(comps[1]) return ret diff --git a/salt/modules/localemod.py b/salt/modules/localemod.py index 1b39ca1f54..6c97c26dfe 100644 --- a/salt/modules/localemod.py +++ b/salt/modules/localemod.py @@ -79,6 +79,8 @@ def _localectl_status(): ctl_key = ctl_key.strip().lower().replace(' ', '_') else: ctl_data = line.strip() + if not ctl_data: + continue if ctl_key: if '=' in ctl_data: loc_set = ctl_data.split('=') diff --git a/salt/states/boto_vpc.py b/salt/states/boto_vpc.py index f771e16b35..3e8830c8a0 100644 --- a/salt/states/boto_vpc.py +++ b/salt/states/boto_vpc.py @@ -907,9 +907,9 @@ def route_table_present(name, vpc_name=None, vpc_id=None, routes=None, interface_id: eni-123456 - destination_cidr_block: 10.10.13.0/24 instance_name: mygatewayserver - - subnet_names: - - subnet1 - - subnet2 + - subnet_names: + - subnet1 + - subnet2 name Name of the route table. diff --git a/salt/states/pip_state.py b/salt/states/pip_state.py index 1b17c15156..42454d5f46 100644 --- a/salt/states/pip_state.py +++ b/salt/states/pip_state.py @@ -46,10 +46,15 @@ except ImportError: if HAS_PIP is True: try: from pip.req import InstallRequirement + _from_line = InstallRequirement.from_line except ImportError: # pip 10.0.0 move req module under pip._internal try: - from pip._internal.req import InstallRequirement + try: + from pip._internal.req import InstallRequirement + _from_line = InstallRequirement.from_line + except AttributeError: + from pip._internal.req.constructors import install_req_from_line as _from_line except ImportError: HAS_PIP = False # Remove references to the loaded pip module above so reloading works @@ -137,7 +142,7 @@ def _check_pkg_version_format(pkg): # The next line is meant to trigger an AttributeError and # handle lower pip versions log.debug('Installed pip version: %s', pip.__version__) - install_req = InstallRequirement.from_line(pkg) + install_req = _from_line(pkg) except AttributeError: log.debug('Installed pip version is lower than 1.2') supported_vcs = ('git', 'svn', 'hg', 'bzr') @@ -145,12 +150,12 @@ def _check_pkg_version_format(pkg): for vcs in supported_vcs: if pkg.startswith(vcs): from_vcs = True - install_req = InstallRequirement.from_line( + install_req = _from_line( pkg.split('{0}+'.format(vcs))[-1] ) break else: - install_req = InstallRequirement.from_line(pkg) + install_req = _from_line(pkg) except (ValueError, InstallationError) as exc: ret['result'] = False if not from_vcs and '=' in pkg and '==' not in pkg: diff --git a/tests/integration/cloud/clouds/test_ec2.py b/tests/integration/cloud/clouds/test_ec2.py index e2c0a2ac45..2ee244962c 100644 --- a/tests/integration/cloud/clouds/test_ec2.py +++ b/tests/integration/cloud/clouds/test_ec2.py @@ -21,6 +21,7 @@ from tests.support.helpers import expensiveTest, generate_random_name from tests.support.unit import skipIf from tests.support import win_installer + # Create the cloud instance name to be used throughout the tests INSTANCE_NAME = generate_random_name('CLOUD-TEST-') PROVIDER_NAME = 'ec2' @@ -33,6 +34,7 @@ class EC2Test(ShellCase): Integration tests for the EC2 cloud provider in Salt-Cloud ''' + def _installer_name(self): ''' Determine the downloaded installer name by searching the files diff --git a/tests/integration/files/file/base/_grains/matcher_grain.py b/tests/integration/files/file/base/_grains/matcher_grain.py index 8f4b9523e5..f7d6c8f76f 100644 --- a/tests/integration/files/file/base/_grains/matcher_grain.py +++ b/tests/integration/files/file/base/_grains/matcher_grain.py @@ -3,5 +3,5 @@ def myfunction(): grains = {} - grains['a_custom'] = {'k1': 'v1'} + grains['match'] = 'maker' return grains diff --git a/tests/unit/beacons/test_diskusage.py b/tests/unit/beacons/test_diskusage.py index ed10e67519..c12acf93d4 100644 --- a/tests/unit/beacons/test_diskusage.py +++ b/tests/unit/beacons/test_diskusage.py @@ -74,9 +74,11 @@ class DiskUsageBeaconTestCase(TestCase, LoaderModuleMockMixin): def test_diskusage_match(self): disk_usage_mock = Mock(side_effect=STUB_DISK_USAGE) - with patch('psutil.disk_partitions', - MagicMock(return_value=STUB_DISK_PARTITION)), \ - patch('psutil.disk_usage', disk_usage_mock): + with patch('salt.utils.platform.is_windows', + MagicMock(return_value=False)),\ + patch('psutil.disk_partitions', + MagicMock(return_value=STUB_DISK_PARTITION)), \ + patch('psutil.disk_usage', disk_usage_mock): config = [{'/': '50%'}] ret = diskusage.validate(config) @@ -88,8 +90,10 @@ class DiskUsageBeaconTestCase(TestCase, LoaderModuleMockMixin): def test_diskusage_nomatch(self): disk_usage_mock = Mock(side_effect=STUB_DISK_USAGE) - with patch('psutil.disk_partitions', - MagicMock(return_value=STUB_DISK_PARTITION)), \ + with patch('salt.utils.platform.is_windows', + MagicMock(return_value=False)),\ + patch('psutil.disk_partitions', + MagicMock(return_value=STUB_DISK_PARTITION)), \ patch('psutil.disk_usage', disk_usage_mock): config = [{'/': '70%'}] @@ -102,8 +106,10 @@ class DiskUsageBeaconTestCase(TestCase, LoaderModuleMockMixin): def test_diskusage_match_regex(self): disk_usage_mock = Mock(side_effect=STUB_DISK_USAGE) - with patch('psutil.disk_partitions', - MagicMock(return_value=STUB_DISK_PARTITION)), \ + with patch('salt.utils.platform.is_windows', + MagicMock(return_value=False)),\ + patch('psutil.disk_partitions', + MagicMock(return_value=STUB_DISK_PARTITION)), \ patch('psutil.disk_usage', disk_usage_mock): config = [{r'^\/': '50%'}] diff --git a/tests/unit/modules/test_localemod.py b/tests/unit/modules/test_localemod.py index 8534b649f6..a72613ecd9 100644 --- a/tests/unit/modules/test_localemod.py +++ b/tests/unit/modules/test_localemod.py @@ -41,9 +41,11 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): X11 Model: pc105 ''' locale_ctl_notset = ''' - System Locale: n/a + System Locale: n/a + VC Keymap: n/a X11 Layout: n/a + X11 Model: n/a ''' locale_ctl_out_empty = '' locale_ctl_out_broken = '''