summaryrefslogtreecommitdiff
path: root/app-admin/salt/files
diff options
context:
space:
mode:
authorV3n3RiX <venerix@redcorelinux.org>2020-05-14 11:09:11 +0100
committerV3n3RiX <venerix@redcorelinux.org>2020-05-14 11:09:11 +0100
commitdeba8115d2c2af26df42966b91ef04ff4dd79cde (patch)
tree9a48f42594e1a9e6b2020d5535a784314434d7a7 /app-admin/salt/files
parent38423c67c8a23f6a1bc42038193182e2da3116eb (diff)
gentoo resync : 14.05.2020
Diffstat (limited to 'app-admin/salt/files')
-rw-r--r--app-admin/salt/files/salt-2018.3.2-skip-zeromq-test-that-hangs.patch79
-rw-r--r--app-admin/salt/files/salt-2018.3.4-tests.patch76
-rw-r--r--app-admin/salt/files/salt-2019.2.0-newer-deps.patch210
-rw-r--r--app-admin/salt/files/salt-3000.1-tests.patch58
-rw-r--r--app-admin/salt/files/salt-3000.2-py38-abc.patch79
-rw-r--r--app-admin/salt/files/salt-3000.2-py38-logwarn.patch116
-rw-r--r--app-admin/salt/files/salt-3000.2-py38.patch60
-rw-r--r--app-admin/salt/files/salt-3000.2-tests.patch18
8 files changed, 331 insertions, 365 deletions
diff --git a/app-admin/salt/files/salt-2018.3.2-skip-zeromq-test-that-hangs.patch b/app-admin/salt/files/salt-2018.3.2-skip-zeromq-test-that-hangs.patch
deleted file mode 100644
index 7b94fafd447d..000000000000
--- a/app-admin/salt/files/salt-2018.3.2-skip-zeromq-test-that-hangs.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-diff --git a/tests/unit/transport/test_zeromq.py b/tests/unit/transport/test_zeromq.py
-index ccb337462e..97d2962e5e 100644
---- a/tests/unit/transport/test_zeromq.py
-+++ b/tests/unit/transport/test_zeromq.py
-@@ -45,6 +45,10 @@ ON_SUSE = False
- if 'SuSE' in linux_distribution(full_distribution_name=False):
- ON_SUSE = True
-
-+ON_GENTOO = False
-+if 'Gentoo' in linux_distribution(full_distribution_name=False):
-+ ON_GENTOO = True
-+
-
- class BaseZMQReqCase(TestCase, AdaptedConfigurationTestCaseMixin):
- '''
-@@ -122,63 +126,6 @@ class BaseZMQReqCase(TestCase, AdaptedConfigurationTestCaseMixin):
- return payload, {'fun': 'send_clear'}
-
-
--class ClearReqTestCases(BaseZMQReqCase, ReqChannelMixin):
-- '''
-- Test all of the clear msg stuff
-- '''
-- def setUp(self):
-- self.channel = salt.transport.client.ReqChannel.factory(self.minion_config, crypt='clear')
--
-- def tearDown(self):
-- del self.channel
--
-- @classmethod
-- @tornado.gen.coroutine
-- def _handle_payload(cls, payload):
-- '''
-- TODO: something besides echo
-- '''
-- raise tornado.gen.Return((payload, {'fun': 'send_clear'}))
--
--
--@flaky
--@skipIf(ON_SUSE, 'Skipping until https://github.com/saltstack/salt/issues/32902 gets fixed')
--class AESReqTestCases(BaseZMQReqCase, ReqChannelMixin):
-- def setUp(self):
-- self.channel = salt.transport.client.ReqChannel.factory(self.minion_config)
--
-- def tearDown(self):
-- del self.channel
--
-- @classmethod
-- @tornado.gen.coroutine
-- def _handle_payload(cls, payload):
-- '''
-- TODO: something besides echo
-- '''
-- raise tornado.gen.Return((payload, {'fun': 'send'}))
--
-- # TODO: make failed returns have a specific framing so we can raise the same exception
-- # on encrypted channels
-- #
-- #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-- #
-- # WARNING: This test will fail randomly on any system with > 1 CPU core!!!
-- #
-- #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-- def test_badload(self):
-- '''
-- Test a variety of bad requests, make sure that we get some sort of error
-- '''
-- # TODO: This test should be re-enabled when Jenkins moves to C7.
-- # Once the version of salt-testing is increased to something newer than the September
-- # release of salt-testing, the @flaky decorator should be applied to this test.
-- msgs = ['', [], tuple()]
-- for msg in msgs:
-- with self.assertRaises(salt.exceptions.AuthenticationError):
-- ret = self.channel.send(msg, timeout=5)
--
--
- class BaseZMQPubCase(AsyncTestCase, AdaptedConfigurationTestCaseMixin):
- '''
- Test the req server/client pair
diff --git a/app-admin/salt/files/salt-2018.3.4-tests.patch b/app-admin/salt/files/salt-2018.3.4-tests.patch
deleted file mode 100644
index ac3dbb845348..000000000000
--- a/app-admin/salt/files/salt-2018.3.4-tests.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-diff --git a/tests/unit/grains/test_core.py b/tests/unit/grains/test_core.py
-index 3874b0001c..40304075eb 100644
---- a/tests/unit/grains/test_core.py
-+++ b/tests/unit/grains/test_core.py
-@@ -685,22 +685,6 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
- 'Docker'
- )
-
-- @skipIf(salt.utils.platform.is_windows(), 'System is Windows')
-- def test_xen_virtual(self):
-- '''
-- Test if OS grains are parsed correctly in Ubuntu Xenial Xerus
-- '''
-- with patch.object(os.path, 'isfile', MagicMock(return_value=False)):
-- with patch.dict(core.__salt__, {'cmd.run': MagicMock(return_value='')}), \
-- patch.object(os.path,
-- 'isfile',
-- MagicMock(side_effect=lambda x: True if x == '/sys/bus/xen/drivers/xenconsole' else False)):
-- log.debug('Testing Xen')
-- self.assertEqual(
-- core._virtual({'kernel': 'Linux'}).get('virtual_subtype'),
-- 'Xen PV DomU'
-- )
--
- def _check_ipaddress(self, value, ip_v):
- '''
- check if ip address in a list is valid
-diff --git a/tests/unit/utils/test_asynchronous.py b/tests/unit/utils/test_asynchronous.py
-index 694a7aebfe..9e22c278e9 100644
---- a/tests/unit/utils/test_asynchronous.py
-+++ b/tests/unit/utils/test_asynchronous.py
-@@ -35,19 +35,6 @@ class HelperB(object):
-
-
- class TestSyncWrapper(AsyncTestCase):
-- @tornado.testing.gen_test
-- def test_helpers(self):
-- '''
-- Test that the helper classes do what we expect within a regular asynchronous env
-- '''
-- ha = HelperA()
-- ret = yield ha.sleep()
-- self.assertTrue(ret)
--
-- hb = HelperB()
-- ret = yield hb.sleep()
-- self.assertFalse(ret)
--
- def test_basic_wrap(self):
- '''
- Test that we can wrap an asynchronous caller.
-@@ -55,24 +42,3 @@ class TestSyncWrapper(AsyncTestCase):
- sync = asynchronous.SyncWrapper(HelperA)
- ret = sync.sleep()
- self.assertTrue(ret)
--
-- def test_double(self):
-- '''
-- Test when the asynchronous wrapper object itself creates a wrap of another thing
--
-- This works fine since the second wrap is based on the first's IOLoop so we
-- don't have to worry about complex start/stop mechanics
-- '''
-- sync = asynchronous.SyncWrapper(HelperB)
-- ret = sync.sleep()
-- self.assertFalse(ret)
--
-- def test_double_sameloop(self):
-- '''
-- Test asynchronous wrappers initiated from the same IOLoop, to ensure that
-- we don't wire up both to the same IOLoop (since it causes MANY problems).
-- '''
-- a = asynchronous.SyncWrapper(HelperA)
-- sync = asynchronous.SyncWrapper(HelperB, (a,))
-- ret = sync.sleep()
-- self.assertFalse(ret)
diff --git a/app-admin/salt/files/salt-2019.2.0-newer-deps.patch b/app-admin/salt/files/salt-2019.2.0-newer-deps.patch
deleted file mode 100644
index bdf95e210897..000000000000
--- a/app-admin/salt/files/salt-2019.2.0-newer-deps.patch
+++ /dev/null
@@ -1,210 +0,0 @@
-diff --git a/salt/modules/dockercompose.py b/salt/modules/dockercompose.py
-index 61e937536c..0f37e0d43a 100644
---- a/salt/modules/dockercompose.py
-+++ b/salt/modules/dockercompose.py
-@@ -241,7 +241,7 @@ def __load_docker_compose(path):
- None, None)
- try:
- with salt.utils.files.fopen(file_path, 'r') as fl:
-- loaded = yaml.load(fl)
-+ loaded = yaml.safe_load(fl)
- except EnvironmentError:
- return None, __standardize_result(False,
- 'Could not read {0}'.format(file_path),
-@@ -371,7 +371,7 @@ def __load_compose_definitions(path, definition):
- None, None)
- else:
- try:
-- loaded_definition = yaml.load(definition)
-+ loaded_definition = yaml.safe_load(definition)
- except yaml.YAMLError as yerr:
- msg = 'Could not parse {0} {1}'.format(definition, yerr)
- return None, None, __standardize_result(False, msg,
-diff --git a/salt/serializers/yaml.py b/salt/serializers/yaml.py
-index c95b40e48f..2154e5dcab 100644
---- a/salt/serializers/yaml.py
-+++ b/salt/serializers/yaml.py
-@@ -72,6 +72,7 @@ def serialize(obj, **options):
- '''
-
- options.setdefault('Dumper', Dumper)
-+ options.setdefault('default_flow_style', None)
- try:
- response = yaml.dump(obj, **options)
- if response.endswith('\n...\n'):
-diff --git a/salt/serializers/yamlex.py b/salt/serializers/yamlex.py
-index 2e4ba6fb2b..e42634f580 100644
---- a/salt/serializers/yamlex.py
-+++ b/salt/serializers/yamlex.py
-@@ -182,6 +182,7 @@ def serialize(obj, **options):
- '''
-
- options.setdefault('Dumper', Dumper)
-+ options.setdefault('default_flow_style', None)
- try:
- response = yaml.dump(obj, **options)
- if response.endswith('\n...\n'):
-diff --git a/salt/utils/yamldumper.py b/salt/utils/yamldumper.py
-index 9892c87d23..3692ea324a 100644
---- a/salt/utils/yamldumper.py
-+++ b/salt/utils/yamldumper.py
-@@ -115,6 +115,7 @@ def dump(data, stream=None, **kwargs):
- '''
- if 'allow_unicode' not in kwargs:
- kwargs['allow_unicode'] = True
-+ kwargs.setdefault('default_flow_style', None)
- return yaml.dump(data, stream, **kwargs)
-
-
-@@ -126,4 +127,5 @@ def safe_dump(data, stream=None, **kwargs):
- '''
- if 'allow_unicode' not in kwargs:
- kwargs['allow_unicode'] = True
-+ kwargs.setdefault('default_flow_style', None)
- return yaml.dump(data, stream, Dumper=SafeOrderedDumper, **kwargs)
-diff --git a/tests/integration/utils/test_win_runas.py b/tests/integration/utils/test_win_runas.py
-index 3042a77991..d4057a4d03 100644
---- a/tests/integration/utils/test_win_runas.py
-+++ b/tests/integration/utils/test_win_runas.py
-@@ -539,7 +539,7 @@ class RunAsTest(ModuleCase):
- win32serviceutil.StartService('test service')
- wait_for_service('test service')
- with salt.utils.files.fopen(RUNAS_OUT, 'r') as fp:
-- ret = yaml.load(fp)
-+ ret = yaml.safe_load(fp)
- assert ret['retcode'] == 1, ret
-
- @with_system_user('test-runas', on_existing='delete', delete=True,
-@@ -560,7 +560,7 @@ class RunAsTest(ModuleCase):
- win32serviceutil.StartService('test service')
- wait_for_service('test service')
- with salt.utils.files.fopen(RUNAS_OUT, 'r') as fp:
-- ret = yaml.load(fp)
-+ ret = yaml.safe_load(fp)
- assert ret['retcode'] == 1, ret
-
- @with_system_user('test-runas-admin', on_existing='delete', delete=True,
-@@ -581,7 +581,7 @@ class RunAsTest(ModuleCase):
- win32serviceutil.StartService('test service')
- wait_for_service('test service')
- with salt.utils.files.fopen(RUNAS_OUT, 'r') as fp:
-- ret = yaml.load(fp)
-+ ret = yaml.safe_load(fp)
- assert ret['retcode'] == 0, ret
-
- @with_system_user('test-runas-admin', on_existing='delete', delete=True,
-@@ -602,7 +602,7 @@ class RunAsTest(ModuleCase):
- win32serviceutil.StartService('test service')
- wait_for_service('test service')
- with salt.utils.files.fopen(RUNAS_OUT, 'r') as fp:
-- ret = yaml.load(fp)
-+ ret = yaml.safe_load(fp)
- assert ret['retcode'] == 0, ret
-
- def test_runas_service_system_user(self):
-@@ -621,5 +621,5 @@ class RunAsTest(ModuleCase):
- win32serviceutil.StartService('test service')
- wait_for_service('test service')
- with salt.utils.files.fopen(RUNAS_OUT, 'r') as fp:
-- ret = yaml.load(fp)
-+ ret = yaml.safe_load(fp)
- assert ret['retcode'] == 0, ret
-diff --git a/tests/unit/serializers/test_serializers.py b/tests/unit/serializers/test_serializers.py
-index 3bf42b67d7..ea42d617d7 100644
---- a/tests/unit/serializers/test_serializers.py
-+++ b/tests/unit/serializers/test_serializers.py
-@@ -68,9 +68,24 @@ class TestSerializers(TestCase):
- serialized = yamlex.serialize(data)
- assert serialized == '{foo: bar}', serialized
-
-+ serialized = yamlex.serialize(data, default_flow_style=False)
-+ assert serialized == 'foo: bar', serialized
-+
- deserialized = yamlex.deserialize(serialized)
- assert deserialized == data, deserialized
-
-+ serialized = yaml.serialize(data)
-+ assert serialized == '{foo: bar}', serialized
-+
-+ deserialized = yaml.deserialize(serialized)
-+ assert deserialized == data, deserialized
-+
-+ serialized = yaml.serialize(data, default_flow_style=False)
-+ assert serialized == 'foo: bar', serialized
-+
-+ deserialized = yaml.deserialize(serialized)
-+ assert deserialized == data, deserialized
-+
- @skipIf(not yamlex.available, SKIP_MESSAGE % 'sls')
- def test_serialize_complex_sls(self):
- data = OrderedDict([
-@@ -84,6 +99,12 @@ class TestSerializers(TestCase):
- deserialized = yamlex.deserialize(serialized)
- assert deserialized == data, deserialized
-
-+ serialized = yaml.serialize(data)
-+ assert serialized == '{bar: 2, baz: true, foo: 1}', serialized
-+
-+ deserialized = yaml.deserialize(serialized)
-+ assert deserialized == data, deserialized
-+
- @skipIf(not yaml.available, SKIP_MESSAGE % 'yaml')
- @skipIf(not yamlex.available, SKIP_MESSAGE % 'sls')
- def test_compare_sls_vs_yaml(self):
-diff --git a/tests/unit/utils/test_schema.py b/tests/unit/utils/test_schema.py
-index 677cd0778b..5c2f1fd8fd 100644
---- a/tests/unit/utils/test_schema.py
-+++ b/tests/unit/utils/test_schema.py
-@@ -5,6 +5,7 @@
-
- # Import python libs
- from __future__ import absolute_import, print_function, unicode_literals
-+import sys
- import copy
-
- # Import Salt Testing Libs
-@@ -506,7 +507,7 @@ class ConfigTestCase(TestCase):
- {'personal_access_token': 'foo'},
- Requirements.serialize()
- )
-- self.assertIn('is not valid under any of the given schemas', excinfo.exception.message)
-+ self.assertIn("'ssh_key_file' is a required property", excinfo.exception.message)
-
- def test_boolean_config(self):
- item = schema.BooleanItem(title='Hungry', description='Are you hungry?')
-@@ -1730,7 +1731,10 @@ class ConfigTestCase(TestCase):
-
- with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo:
- jsonschema.validate({'item': {'sides': '4', 'color': 'blue'}}, TestConf.serialize())
-- self.assertIn('is not valid under any of the given schemas', excinfo.exception.message)
-+ if sys.hexversion >= 0x03000000:
-+ self.assertIn("'4' is not of type 'boolean'", excinfo.exception.message)
-+ else:
-+ self.assertIn("u'4' is not of type u'boolean'", excinfo.exception.message)
-
- class TestConf(schema.Schema):
- item = schema.DictItem(
-@@ -1833,7 +1837,10 @@ class ConfigTestCase(TestCase):
-
- with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo:
- jsonschema.validate({'item': ['maybe']}, TestConf.serialize())
-- self.assertIn('is not valid under any of the given schemas', excinfo.exception.message)
-+ if sys.hexversion >= 0x03000000:
-+ self.assertIn("'maybe' is not one of ['yes']", excinfo.exception.message)
-+ else:
-+ self.assertIn("u'maybe' is not one of [u'yes']", excinfo.exception.message)
-
- with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo:
- jsonschema.validate({'item': 2}, TestConf.serialize())
-@@ -1885,7 +1892,10 @@ class ConfigTestCase(TestCase):
-
- with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo:
- jsonschema.validate({'item': ['maybe']}, TestConf.serialize())
-- self.assertIn('is not valid under any of the given schemas', excinfo.exception.message)
-+ if sys.hexversion >= 0x03000000:
-+ self.assertIn("'maybe' is not one of ['yes']", excinfo.exception.message)
-+ else:
-+ self.assertIn("u'maybe' is not one of [u'yes']", excinfo.exception.message)
-
- with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo:
- jsonschema.validate({'item': 2}, TestConf.serialize())
diff --git a/app-admin/salt/files/salt-3000.1-tests.patch b/app-admin/salt/files/salt-3000.1-tests.patch
new file mode 100644
index 000000000000..12a2e7822b94
--- /dev/null
+++ b/app-admin/salt/files/salt-3000.1-tests.patch
@@ -0,0 +1,58 @@
+diff --git a/tests/unit/fileserver/test_roots.py b/tests/unit/fileserver/test_roots.py
+index e0d939a086..33a9b6dc35 100644
+--- a/tests/unit/fileserver/test_roots.py
++++ b/tests/unit/fileserver/test_roots.py
+@@ -11,7 +11,7 @@ import tempfile
+
+ # Import Salt Testing libs
+ from tests.support.mixins import AdaptedConfigurationTestCaseMixin, LoaderModuleMockMixin
+-from tests.support.unit import TestCase
++from tests.support.unit import TestCase, skipIf
+ from tests.support.mock import patch
+ from tests.support.runtests import RUNTIME_VARS
+
+@@ -165,6 +165,7 @@ class RootsTest(TestCase, AdaptedConfigurationTestCaseMixin, LoaderModuleMockMix
+ self.assertIn('empty_dir', ret)
+ self.assertIn(UNICODE_DIRNAME, ret)
+
++ @skipIf(True, "doesn't like sandbox")
+ def test_symlink_list(self):
+ orig_file_roots = self.opts['file_roots']
+ try:
+diff --git a/tests/unit/modules/test_dockermod.py b/tests/unit/modules/test_dockermod.py
+index 191bfc123f..1956127f0b 100644
+--- a/tests/unit/modules/test_dockermod.py
++++ b/tests/unit/modules/test_dockermod.py
+@@ -793,6 +793,7 @@ class DockerTestCase(TestCase, LoaderModuleMockMixin):
+ },
+ ret)
+
++ @skipIf(True, "Doesn't work with sandbox")
+ def test_call_success(self):
+ '''
+ test module calling inside containers
+diff --git a/tests/unit/states/test_pip_state.py b/tests/unit/states/test_pip_state.py
+index 13c158b309..27e10e6161 100644
+--- a/tests/unit/states/test_pip_state.py
++++ b/tests/unit/states/test_pip_state.py
+@@ -384,6 +384,7 @@ class PipStateUtilsTest(TestCase):
+
+
+ @skipIf(salt.utils.path.which_bin(KNOWN_BINARY_NAMES) is None, 'virtualenv not installed')
++@skipIf(True, "Needs network access")
+ class PipStateInstallationErrorTest(TestCase):
+
+ def test_importable_installation_error(self):
+diff --git a/tests/unit/utils/test_jinja.py b/tests/unit/utils/test_jinja.py
+index f48fa9d42c..bb57929cfa 100644
+--- a/tests/unit/utils/test_jinja.py
++++ b/tests/unit/utils/test_jinja.py
+@@ -1268,7 +1268,7 @@ class TestCustomExtensions(TestCase):
+ dict(opts=self.local_opts, saltenv='test', salt=self.local_salt))
+ self.assertEqual(rendered, '16777216')
+
+- @flaky
++ @skipIf("True", "Needs network access")
+ def test_http_query(self):
+ '''
+ Test the `http_query` Jinja filter.
diff --git a/app-admin/salt/files/salt-3000.2-py38-abc.patch b/app-admin/salt/files/salt-3000.2-py38-abc.patch
new file mode 100644
index 000000000000..e9f64b664178
--- /dev/null
+++ b/app-admin/salt/files/salt-3000.2-py38-abc.patch
@@ -0,0 +1,79 @@
+From 11c23a526ae926ca082ee7ad92246e085c51b8e6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=A9bastien=20Blaisot?= <sebastien@blaisot.org>
+Date: Fri, 17 Jan 2020 17:06:42 +0100
+Subject: [PATCH] Import abstract base classes from collection.abc in python
+ 3.3+
+
+---
+ salt/modules/file.py | 6 +++++-
+ salt/modules/win_file.py | 5 ++++-
+ salt/states/file.py | 6 +++++-
+ salt/utils/dictdiffer.py | 5 ++++-
+ 4 files changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/salt/modules/file.py b/salt/modules/file.py
+index 771b204d63fe..d1ec5e4c295d 100644
+--- a/salt/modules/file.py
++++ b/salt/modules/file.py
+@@ -29,7 +29,11 @@
+ import glob
+ import hashlib
+ import mmap
+-from collections import Iterable, Mapping, namedtuple
++try:
++ from collections.abc import Iterable, Mapping
++except ImportError:
++ from collections import Iterable, Mapping
++from collections import namedtuple
+ from functools import reduce # pylint: disable=redefined-builtin
+
+ # pylint: disable=import-error,no-name-in-module,redefined-builtin
+diff --git a/salt/modules/win_file.py b/salt/modules/win_file.py
+index 4fd3eebcdd81..5bc983786a98 100644
+--- a/salt/modules/win_file.py
++++ b/salt/modules/win_file.py
+@@ -17,7 +17,10 @@
+ import logging
+ # pylint: disable=W0611
+ import operator # do not remove
+-from collections import Iterable, Mapping # do not remove
++try:
++ from collections.abc import Iterable, Mapping # do not remove
++except ImportError:
++ from collections import Iterable, Mapping # do not remove
+ from functools import reduce # do not remove
+ import datetime # do not remove.
+ import tempfile # do not remove. Used in salt.modules.file.__clean_tmp
+diff --git a/salt/states/file.py b/salt/states/file.py
+index 23c3d3c53955..36231c69cff6 100644
+--- a/salt/states/file.py
++++ b/salt/states/file.py
+@@ -291,7 +291,11 @@ def run():
+ import sys
+ import time
+ import traceback
+-from collections import Iterable, Mapping, defaultdict
++try:
++ from collections.abc import Iterable, Mapping
++except ImportError:
++ from collections import Iterable, Mapping
++from collections import defaultdict
+ from datetime import datetime, date # python3 problem in the making?
+
+ # Import salt libs
+diff --git a/salt/utils/dictdiffer.py b/salt/utils/dictdiffer.py
+index 30e87e885436..da6bd5ed944c 100644
+--- a/salt/utils/dictdiffer.py
++++ b/salt/utils/dictdiffer.py
+@@ -13,7 +13,10 @@
+ '''
+ from __future__ import absolute_import, print_function, unicode_literals
+ import copy
+-from collections import Mapping
++try:
++ from collections.abc import Mapping
++except ImportError:
++ from collections import Mapping
+ from salt.ext import six
+
+
diff --git a/app-admin/salt/files/salt-3000.2-py38-logwarn.patch b/app-admin/salt/files/salt-3000.2-py38-logwarn.patch
new file mode 100644
index 000000000000..e77d2376ce1b
--- /dev/null
+++ b/app-admin/salt/files/salt-3000.2-py38-logwarn.patch
@@ -0,0 +1,116 @@
+diff --git a/salt/cloud/clouds/ec2.py b/salt/cloud/clouds/ec2.py
+index 68f752cb2d..fa2b96499d 100644
+--- a/salt/cloud/clouds/ec2.py
++++ b/salt/cloud/clouds/ec2.py
+@@ -4901,7 +4901,7 @@ def get_password_data(
+
+ if not HAS_M2 and not HAS_PYCRYPTO:
+ if 'key' in kwargs or 'key_file' in kwargs:
+- log.warn("No crypto library is installed, can not decrypt password")
++ log.warning("No crypto library is installed, can not decrypt password")
+ return ret
+
+ if 'key' not in kwargs:
+diff --git a/salt/modules/gpg.py b/salt/modules/gpg.py
+index 9dd1007c1b..47c82a7141 100644
+--- a/salt/modules/gpg.py
++++ b/salt/modules/gpg.py
+@@ -1083,7 +1083,7 @@ def verify(text=None,
+
+ if trustmodel and trustmodel not in trustmodels:
+ msg = 'Invalid trustmodel defined: {}. Use one of: {}'.format(trustmodel, ', '.join(trustmodels))
+- log.warn(msg)
++ log.warning(msg)
+ return {'res': False, 'message': msg}
+
+ extra_args = []
+diff --git a/salt/modules/network.py b/salt/modules/network.py
+index 38e2bc326e..f3a8a714cd 100644
+--- a/salt/modules/network.py
++++ b/salt/modules/network.py
+@@ -958,7 +958,7 @@ def traceroute(host):
+
+ ret.append(result)
+ if not result:
+- log.warn('Cannot parse traceroute output line: %s', line)
++ log.warning('Cannot parse traceroute output line: %s', line)
+ return ret
+
+
+diff --git a/salt/modules/saltutil.py b/salt/modules/saltutil.py
+index 138a0fcf51..5f026b0f36 100644
+--- a/salt/modules/saltutil.py
++++ b/salt/modules/saltutil.py
+@@ -1096,7 +1096,7 @@ def refresh_pillar(wait=False, timeout=30):
+ tag='/salt/minion/minion_pillar_refresh_complete',
+ wait=timeout)
+ if not event_ret or event_ret['complete'] is False:
+- log.warn("Pillar refresh did not complete within timeout %s", timeout)
++ log.warning("Pillar refresh did not complete within timeout %s", timeout)
+ return ret
+
+
+diff --git a/salt/transport/tcp.py b/salt/transport/tcp.py
+index 12ef24e86f..e83d1c927f 100644
+--- a/salt/transport/tcp.py
++++ b/salt/transport/tcp.py
+@@ -1073,7 +1073,7 @@ class SaltMessageClient(object):
+ self._connecting_future.set_result(True)
+ break
+ except Exception as exc: # pylint: disable=broad-except
+- log.warn('TCP Message Client encountered an exception %r', exc)
++ log.warning('TCP Message Client encountered an exception %r', exc)
+ yield salt.ext.tornado.gen.sleep(1) # TODO: backoff
+ #self._connecting_future.set_exception(e)
+
+diff --git a/salt/utils/process.py b/salt/utils/process.py
+index 9626ac0cb2..18697ccf7c 100644
+--- a/salt/utils/process.py
++++ b/salt/utils/process.py
+@@ -124,7 +124,7 @@ def dup2(file1, file2):
+ try:
+ fno1 = file1.fileno()
+ except io.UnsupportedOperation:
+- log.warn('Unsupported operation on file: %r', file1)
++ log.warning('Unsupported operation on file: %r', file1)
+ return
+ if isinstance(file2, int):
+ fno2 = file2
+@@ -132,7 +132,7 @@ def dup2(file1, file2):
+ try:
+ fno2 = file2.fileno()
+ except io.UnsupportedOperation:
+- log.warn('Unsupported operation on file: %r', file2)
++ log.warning('Unsupported operation on file: %r', file2)
+ return
+ os.dup2(fno1, fno2)
+
+@@ -829,13 +829,13 @@ class SignalHandlingProcess(Process):
+ if child.is_running():
+ child.terminate()
+ except psutil.NoSuchProcess:
+- log.warn(
++ log.warning(
+ 'Unable to kill child of process %d, it does '
+ 'not exist. My pid is %d',
+ self.pid, os.getpid()
+ )
+ except psutil.NoSuchProcess:
+- log.warn(
++ log.warning(
+ 'Unable to kill children of process %d, it does not exist.'
+ 'My pid is %d',
+ self.pid, os.getpid()
+diff --git a/tests/integration/modules/test_state.py b/tests/integration/modules/test_state.py
+index 81b3b677b9..2f3bcaa613 100644
+--- a/tests/integration/modules/test_state.py
++++ b/tests/integration/modules/test_state.py
+@@ -2282,7 +2282,7 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
+ try:
+ os.remove(path)
+ except OSError:
+- log.warn("Path not found: %s", path)
++ log.warning("Path not found: %s", path)
+
+ with salt.utils.files.fopen(module_path, 'w') as fp:
+ fp.write('raise ImportError("No module named pip")')
diff --git a/app-admin/salt/files/salt-3000.2-py38.patch b/app-admin/salt/files/salt-3000.2-py38.patch
new file mode 100644
index 000000000000..1c543a085b10
--- /dev/null
+++ b/app-admin/salt/files/salt-3000.2-py38.patch
@@ -0,0 +1,60 @@
+From 5259ba8ef6e5949815641edc563deab67ba68582 Mon Sep 17 00:00:00 2001
+From: Mathias Fussenegger <f.mathias@zignar.net>
+Date: Fri, 22 Nov 2019 17:05:27 +0100
+Subject: [PATCH] Remove _supported_dists import for python-3.8 support
+
+`_supported_dists` has been removed from platform in Python 3.8:
+
+ https://github.com/python/cpython/commit/8b94b41ab7b12f745dea744e8940631318816935#diff-47c8e5750258a08a6dd9de3e9c3774acL267-L271
+
+This instead inlines all the values that have been there.
+
+Without this change running `salt-ssh` with Python 3.8 run into an
+import error.
+---
+ salt/grains/core.py | 31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/salt/grains/core.py b/salt/grains/core.py
+index 04c1ae91b5f5..77694abe84f9 100644
+--- a/salt/grains/core.py
++++ b/salt/grains/core.py
+@@ -35,11 +35,34 @@
+ __proxyenabled__ = ['*']
+ __FQDN__ = None
+
+-# Extend the default list of supported distros. This will be used for the
++# Default list of supported distros. This will be used for the
+ # /etc/DISTRO-release checking that is part of linux_distribution()
+-from platform import _supported_dists
+-_supported_dists += ('arch', 'mageia', 'meego', 'vmware', 'bluewhite64',
+- 'slamd64', 'ovs', 'system', 'mint', 'oracle', 'void')
++_supported_dists = (
++ 'SuSE',
++ 'UnitedLinux',
++ 'arch',
++ 'bluewhite64',
++ 'centos',
++ 'debian',
++ 'fedora',
++ 'gentoo',
++ 'mageia',
++ 'mandrake',
++ 'mandriva',
++ 'meego',
++ 'mint',
++ 'oracle',
++ 'ovs',
++ 'redhat',
++ 'rocks',
++ 'slackware',
++ 'slamd64',
++ 'system',
++ 'turbolinux',
++ 'vmware',
++ 'void',
++ 'yellowdog',
++)
+
+ # linux_distribution deprecated in py3.7
+ try:
diff --git a/app-admin/salt/files/salt-3000.2-tests.patch b/app-admin/salt/files/salt-3000.2-tests.patch
new file mode 100644
index 000000000000..a562dee5bf94
--- /dev/null
+++ b/app-admin/salt/files/salt-3000.2-tests.patch
@@ -0,0 +1,18 @@
+--- salt-3000.2.orig/tests/unit/utils/test_verify.py 2020-04-29 16:57:02.775635698 -0700
++++ salt-3000.2/tests/unit/utils/test_verify.py 2020-04-29 16:57:58.042282147 -0700
+@@ -324,6 +324,7 @@
+ self.assertTrue(os.path.exists(path))
+
+
++@skipIf(True, "breaks under sandbox")
+ class TestCleanPath(TestCase):
+ '''
+ salt.utils.clean_path works as expected
+@@ -366,6 +367,7 @@
+ raise ctypes.WinError()
+
+
++@skipIf(True, "breaks under sandbox")
+ @skipIf(six.PY2 and salt.utils.platform.is_windows(), 'Skipped on windows py2')
+ class TestCleanPathLink(TestCase):
+ '''