diff --git a/sysutils/salt/Makefile b/sysutils/salt/Makefile index c8fd7af0e11..3b4b9f9d774 100644 --- a/sysutils/salt/Makefile +++ b/sysutils/salt/Makefile @@ -15,9 +15,8 @@ COMMENT = remote execution and configuration management system -MODPY_DISTV = 3007.8 +MODPY_DISTV = 3007.9 DISTNAME = salt-${MODPY_DISTV} -REVISION = 0 CATEGORIES = sysutils net devel diff --git a/sysutils/salt/distinfo b/sysutils/salt/distinfo index 6b854fff612..f71018b8d46 100644 --- a/sysutils/salt/distinfo +++ b/sysutils/salt/distinfo @@ -1,2 +1,2 @@ -SHA256 (salt-3007.8.tar.gz) = WfK1pIf9gyOeMaeNsAgrElCDOTEx2uENO5Cjs0h2meI= -SIZE (salt-3007.8.tar.gz) = 19520648 +SHA256 (salt-3007.9.tar.gz) = H3cNa5ylVo+SbZjt/NJtznHAT2CUJD25EoV5U+PUpW0= +SIZE (salt-3007.9.tar.gz) = 19549730 diff --git a/sysutils/salt/patches/patch-salt___init___py b/sysutils/salt/patches/patch-salt___init___py new file mode 100644 index 00000000000..400acb114ae --- /dev/null +++ b/sysutils/salt/patches/patch-salt___init___py @@ -0,0 +1,15 @@ +Index: salt/__init__.py +--- salt/__init__.py.orig ++++ salt/__init__.py +@@ -110,6 +110,11 @@ warnings.filterwarnings( + category=DeprecationWarning, + ) + ++warnings.filterwarnings( ++ "ignore", ++ "datetime.datetime.utcnow().*", ++ category=DeprecationWarning, ++) + + def __define_global_system_encoding_variable__(): + import builtins diff --git a/sysutils/salt/patches/patch-salt_channel_client_py b/sysutils/salt/patches/patch-salt_channel_client_py new file mode 100644 index 00000000000..35859225bcb --- /dev/null +++ b/sysutils/salt/patches/patch-salt_channel_client_py @@ -0,0 +1,15 @@ +https://github.com/saltstack/salt/issues/66568 +https://github.com/saltstack/salt/pull/68277 +Index: salt/channel/client.py +--- salt/channel/client.py.orig ++++ salt/channel/client.py +@@ -556,7 +556,8 @@ class AsyncPubChannel: + # may have been restarted + yield self.send_id(self.token, self._reconnected) + self.connected = True +- self.event.fire_event({"master": self.opts["master"]}, "__master_connected") ++ if self.event: ++ self.event.fire_event({"master": self.opts["master"]}, "__master_connected") + if self._reconnected: + # On reconnects, fire a master event to notify that the minion is + # available. diff --git a/sysutils/salt/patches/patch-salt_transport_tcp_py b/sysutils/salt/patches/patch-salt_transport_tcp_py new file mode 100644 index 00000000000..cfe8069a5dc --- /dev/null +++ b/sysutils/salt/patches/patch-salt_transport_tcp_py @@ -0,0 +1,60 @@ +https://github.com/saltstack/salt/issues/66568 +https://github.com/saltstack/salt/pull/68277 +Index: salt/transport/tcp.py +--- salt/transport/tcp.py.orig ++++ salt/transport/tcp.py +@@ -235,7 +235,6 @@ class PublishClient(salt.transport.base.PublishClient) + self.connected = False + self._closing = False + self._stream = None +- self._closing = False + self._closed = False + self.backoff = opts.get("tcp_reconnect_backoff", 1) + self.resolver = kwargs.get("resolver") +@@ -1769,6 +1768,7 @@ class RequestClient(salt.transport.base.RequestClient) + self._closed = False + self._stream_return_running = False + self._stream = None ++ self.task = None + self.disconnect_callback = _null_callback + self.connect_callback = _null_callback + self.backoff = opts.get("tcp_reconnect_backoff", 1) +@@ -1837,7 +1837,7 @@ class RequestClient(salt.transport.base.RequestClient) + message_id, + ) + except tornado.iostream.StreamClosedError as e: +- log.error( ++ log.debug( + "tcp stream to %s:%s closed, unable to recv", + self.host, + self.port, +@@ -1879,6 +1879,8 @@ class RequestClient(salt.transport.base.RequestClient) + stream.close() + unpacker = salt.utils.msgpack.Unpacker() + await self.connect() ++ except asyncio.CancelledError: ++ log.debug("Stream return cancelled") + self._stream_return_running = False + + def _message_id(self): +@@ -1927,9 +1929,20 @@ class RequestClient(salt.transport.base.RequestClient) + def close(self): + if self._closing: + return ++ self._closing = True + if self._stream is not None: + self._stream.close() + self._stream = None ++ if self.task is not None: ++ self.task.cancel() ++ # Wait for the task to finish via asyncio ++ group = asyncio.gather(self.task) ++ try: ++ self.task.get_loop().run_until_complete(group) ++ except RuntimeError: ++ # Ignore event loop was already running message ++ pass ++ self.task = None + + def __enter__(self): + return self diff --git a/sysutils/salt/patches/patch-salt_utils_pycrypto_py b/sysutils/salt/patches/patch-salt_utils_pycrypto_py new file mode 100644 index 00000000000..41dde820fe3 --- /dev/null +++ b/sysutils/salt/patches/patch-salt_utils_pycrypto_py @@ -0,0 +1,73 @@ +crypt has been deprecated since version 3.11, removed in version 3.13 + +PEP 594 + +Index: salt/utils/pycrypto.py +--- salt/utils/pycrypto.py.orig ++++ salt/utils/pycrypto.py +@@ -24,11 +24,11 @@ except ImportError: + HAS_RANDOM = False + + try: +- import crypt ++ import hashlib + +- HAS_CRYPT = True ++ HAS_HASHLIB = True + except (ImportError, PermissionError): +- HAS_CRYPT = False ++ HAS_HASHLIB = False + + try: + import passlib.context +@@ -101,8 +101,8 @@ def secure_password( + raise CommandExecutionError(str(exc)) + + +-if HAS_CRYPT: +- methods = {m.name.lower(): m for m in crypt.methods} ++if HAS_HASHLIB: ++ methods = {m.lower(): m for m in hashlib.algorithms_guaranteed} + else: + methods = {} + known_methods = ["sha512", "sha256", "blowfish", "md5", "crypt"] +@@ -130,9 +130,9 @@ def _gen_hash_passlib(crypt_salt=None, password=None, + return ctx.hash(**kwargs) + + +-def _gen_hash_crypt(crypt_salt=None, password=None, algorithm=None): ++def _gen_hash_hashlib(crypt_salt=None, password=None, algorithm=None): + """ +- Generate /etc/shadow hash using the native crypt module ++ Generate /etc/shadow hash using the native hashlib module + """ + if crypt_salt is None: + # setting crypt_salt to the algorithm makes crypt generate +@@ -144,7 +144,9 @@ def _gen_hash_crypt(crypt_salt=None, password=None, al + crypt_salt = f"${methods[algorithm].ident}${crypt_salt}" + + try: +- ret = crypt.crypt(password, crypt_salt) ++ h = hashlib.new(crypt_salt) ++ h.update(password.encode("utf-8")) ++ ret = h.hexdigest() + except OSError: + ret = None + return ret +@@ -159,13 +161,13 @@ def gen_hash(crypt_salt=None, password=None, algorithm + + if algorithm is None: + # prefer the most secure natively supported method +- algorithm = crypt.methods[0].name.lower() if HAS_CRYPT else known_methods[0] ++ algorithm = crypt.methods[0].name.lower() if HAS_HASHLIB else known_methods[0] + + if algorithm == "crypt" and crypt_salt and len(crypt_salt) != 2: + log.warning("Hash salt is too long for 'crypt' hash.") + +- if HAS_CRYPT and algorithm in methods: +- return _gen_hash_crypt( ++ if HAS_HASHLIB and algorithm in methods: ++ return _gen_hash_hashlib( + crypt_salt=crypt_salt, password=password, algorithm=algorithm + ) + elif HAS_PASSLIB and algorithm in known_methods: diff --git a/sysutils/salt/patches/patch-salt_utils_url_py b/sysutils/salt/patches/patch-salt_utils_url_py new file mode 100644 index 00000000000..21e2e83f4ec --- /dev/null +++ b/sysutils/salt/patches/patch-salt_utils_url_py @@ -0,0 +1,26 @@ +https://github.com/saltstack/salt/issues/66898 + +Index: salt/utils/url.py +--- salt/utils/url.py.orig ++++ salt/utils/url.py +@@ -4,8 +4,9 @@ URL utils + + import re + import sys +-from urllib.parse import urlparse, urlunparse ++from urllib.parse import urlparse, urlunparse, urlunsplit + ++# Import salt libs + import salt.utils.data + import salt.utils.path + import salt.utils.platform +@@ -46,8 +47,7 @@ def create(path, saltenv=None): + path = salt.utils.data.decode(path) + + query = f"saltenv={saltenv}" if saltenv else "" +- url = salt.utils.data.decode(urlunparse(("file", "", path, "", query, ""))) +- return "salt://{}".format(url[len("file:///") :]) ++ return f"salt://{salt.utils.data.decode(urlunsplit(("", "", path, query, "")))}" + + + def is_escaped(url): diff --git a/sysutils/salt/pkg/PLIST b/sysutils/salt/pkg/PLIST index 78ddaabe8d6..4b8089f0927 100644 --- a/sysutils/salt/pkg/PLIST +++ b/sysutils/salt/pkg/PLIST @@ -4588,6 +4588,8 @@ lib/python${MODPY_VERSION}/site-packages/salt/utils/${MODPY_PYCACHE}ctx.${MODPY_ lib/python${MODPY_VERSION}/site-packages/salt/utils/${MODPY_PYCACHE}ctx.${MODPY_PYC_MAGIC_TAG}pyc lib/python${MODPY_VERSION}/site-packages/salt/utils/${MODPY_PYCACHE}data.${MODPY_PYC_MAGIC_TAG}${MODPY_PYOEXTENSION} lib/python${MODPY_VERSION}/site-packages/salt/utils/${MODPY_PYCACHE}data.${MODPY_PYC_MAGIC_TAG}pyc +lib/python${MODPY_VERSION}/site-packages/salt/utils/${MODPY_PYCACHE}datastructures.${MODPY_PYC_MAGIC_TAG}${MODPY_PYOEXTENSION} +lib/python${MODPY_VERSION}/site-packages/salt/utils/${MODPY_PYCACHE}datastructures.${MODPY_PYC_MAGIC_TAG}pyc lib/python${MODPY_VERSION}/site-packages/salt/utils/${MODPY_PYCACHE}dateutils.${MODPY_PYC_MAGIC_TAG}${MODPY_PYOEXTENSION} lib/python${MODPY_VERSION}/site-packages/salt/utils/${MODPY_PYCACHE}dateutils.${MODPY_PYC_MAGIC_TAG}pyc lib/python${MODPY_VERSION}/site-packages/salt/utils/${MODPY_PYCACHE}debug.${MODPY_PYC_MAGIC_TAG}${MODPY_PYOEXTENSION} @@ -4885,6 +4887,7 @@ lib/python${MODPY_VERSION}/site-packages/salt/utils/context.py lib/python${MODPY_VERSION}/site-packages/salt/utils/crypt.py lib/python${MODPY_VERSION}/site-packages/salt/utils/ctx.py lib/python${MODPY_VERSION}/site-packages/salt/utils/data.py +lib/python${MODPY_VERSION}/site-packages/salt/utils/datastructures.py lib/python${MODPY_VERSION}/site-packages/salt/utils/dateutils.py lib/python${MODPY_VERSION}/site-packages/salt/utils/debug.py lib/python${MODPY_VERSION}/site-packages/salt/utils/decorators/