Gentoo Archives: gentoo-commits

From: Sebastian Pipping <sping@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: app-admin/salt/, app-admin/salt/files/
Date: Mon, 30 Jan 2023 04:55:30
Message-Id: 1675054403.4880642564e0285f7670d186aa254c3f9202f86d.sping@gentoo
1 commit: 4880642564e0285f7670d186aa254c3f9202f86d
2 Author: Sebastian Pipping <sping <AT> gentoo <DOT> org>
3 AuthorDate: Mon Jan 30 04:48:57 2023 +0000
4 Commit: Sebastian Pipping <sping <AT> gentoo <DOT> org>
5 CommitDate: Mon Jan 30 04:53:23 2023 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=48806425
7
8 app-admin/salt: Fix importlib-metadata usage + fix salt-ssh for py3.11 hosts
9
10 The Python 3.11 issue upstream:
11 - https://github.com/saltstack/salt/issues/62676
12 - https://github.com/saltstack/salt/pull/62677
13
14 The importlib-metadata issue:
15 - https://github.com/saltstack/salt/issues/62851
16 - https://github.com/saltstack/salt/pull/62854
17
18 Patches have been extracted from pull requests as following:
19 - git clone https://github.com/saltstack/salt
20 - cd salt
21 - git diff b676e6338a7c094cb3335d11f851ac0e12222017^ 45b924bad865a00116d2e045fe71229f2dc3376e -- salt/utils/entrypoints.py > salt-3005.1-importlib-metadata-5-r1.patch
22 - git diff 00352ae6e0ed0b80a75ec65cb925dd31a625010d^ 91efaea4975f37de97a88687d40e54e774151a8b -- salt/modules/file.py | head -n 123 > salt-3005.1-modules-file-python-3.11-host.patch
23
24 Be sure to call salt-ssh with "--regen-thin" the first time
25 after updating, to not end up running unpatched 3005.1(-r0) code.
26
27 Closes: https://bugs.gentoo.org/875389
28 Closes: https://bugs.gentoo.org/883671
29 Signed-off-by: Sebastian Pipping <sping <AT> gentoo.org>
30
31 .../salt-3005.1-importlib-metadata-5-r1.patch | 29 +++
32 ...salt-3005.1-modules-file-python-3.11-host.patch | 123 ++++++++++++
33 app-admin/salt/salt-3005.1-r1.ebuild | 220 +++++++++++++++++++++
34 3 files changed, 372 insertions(+)
35
36 diff --git a/app-admin/salt/files/salt-3005.1-importlib-metadata-5-r1.patch b/app-admin/salt/files/salt-3005.1-importlib-metadata-5-r1.patch
37 new file mode 100644
38 index 000000000000..c4c8056c1a6a
39 --- /dev/null
40 +++ b/app-admin/salt/files/salt-3005.1-importlib-metadata-5-r1.patch
41 @@ -0,0 +1,29 @@
42 +diff --git a/salt/utils/entrypoints.py b/salt/utils/entrypoints.py
43 +index 3effa0b494..9452878ade 100644
44 +--- a/salt/utils/entrypoints.py
45 ++++ b/salt/utils/entrypoints.py
46 +@@ -38,13 +38,20 @@ def iter_entry_points(group, name=None):
47 + entry_points_listing = []
48 + entry_points = importlib_metadata.entry_points()
49 +
50 +- for entry_point_group, entry_points_list in entry_points.items():
51 +- if entry_point_group != group:
52 +- continue
53 +- for entry_point in entry_points_list:
54 ++ try:
55 ++ for entry_point in entry_points.select(group=group):
56 + if name is not None and entry_point.name != name:
57 + continue
58 + entry_points_listing.append(entry_point)
59 ++ except AttributeError:
60 ++ # importlib-metadata<5.0.0
61 ++ for entry_point_group, entry_points_list in entry_points.items():
62 ++ if entry_point_group != group:
63 ++ continue
64 ++ for entry_point in entry_points_list:
65 ++ if name is not None and entry_point.name != name:
66 ++ continue
67 ++ entry_points_listing.append(entry_point)
68 +
69 + return entry_points_listing
70 +
71
72 diff --git a/app-admin/salt/files/salt-3005.1-modules-file-python-3.11-host.patch b/app-admin/salt/files/salt-3005.1-modules-file-python-3.11-host.patch
73 new file mode 100644
74 index 000000000000..2e9be8db18c0
75 --- /dev/null
76 +++ b/app-admin/salt/files/salt-3005.1-modules-file-python-3.11-host.patch
77 @@ -0,0 +1,123 @@
78 +diff --git a/salt/modules/file.py b/salt/modules/file.py
79 +index f39d618203..93eeaf312e 100644
80 +--- a/salt/modules/file.py
81 ++++ b/salt/modules/file.py
82 +@@ -16,7 +16,6 @@ import hashlib
83 + import itertools
84 + import logging
85 + import mmap
86 +-import operator
87 + import os
88 + import re
89 + import shutil
90 +@@ -28,7 +27,6 @@ import time
91 + import urllib.parse
92 + from collections import namedtuple
93 + from collections.abc import Iterable, Mapping
94 +-from functools import reduce
95 +
96 + import salt.utils.args
97 + import salt.utils.atomicfile
98 +@@ -1622,38 +1620,38 @@ def comment_line(path, regex, char="#", cmnt=True, backup=".bak"):
99 +
100 + def _get_flags(flags):
101 + """
102 +- Return an integer appropriate for use as a flag for the re module from a
103 +- list of human-readable strings
104 ++ Return the names of the Regex flags that correspond to flags
105 +
106 + .. code-block:: python
107 +
108 +- >>> _get_flags(['MULTILINE', 'IGNORECASE'])
109 +- 10
110 ++ >>> _get_flags(['IGNORECASE', 'MULTILINE'])
111 ++ re.IGNORECASE|re.MULTILINE
112 + >>> _get_flags('MULTILINE')
113 +- 8
114 +- >>> _get_flags(2)
115 +- 2
116 ++ re.MULTILINE
117 ++ >>> _get_flags(8)
118 ++ re.MULTILINE
119 ++ >>> _get_flags(re.IGNORECASE)
120 ++ re.IGNORECASE
121 + """
122 +- if isinstance(flags, str):
123 ++ if isinstance(flags, re.RegexFlag):
124 ++ return flags
125 ++ elif isinstance(flags, int):
126 ++ return re.RegexFlag(flags)
127 ++ elif isinstance(flags, str):
128 + flags = [flags]
129 +
130 + if isinstance(flags, Iterable) and not isinstance(flags, Mapping):
131 +- _flags_acc = [0] # An initial 0 avoids resucing on empty list, an error
132 ++ _flags = re.RegexFlag(0)
133 + for flag in flags:
134 +- _flag = getattr(re, str(flag).upper())
135 +-
136 +- if not isinstance(_flag, int):
137 +- raise SaltInvocationError("Invalid re flag given: {}".format(flag))
138 +-
139 +- _flags_acc.append(_flag)
140 +-
141 +- return reduce(operator.__or__, _flags_acc)
142 +- elif isinstance(flags, int):
143 +- return flags
144 ++ _flag = getattr(re.RegexFlag, str(flag).upper(), None)
145 ++ if not _flag:
146 ++ raise CommandExecutionError(f"Invalid re flag given: {flag}")
147 ++ _flags |= _flag
148 ++ return _flags
149 + else:
150 +- raise SaltInvocationError(
151 +- 'Invalid re flags: "{}", must be given either as a single flag '
152 +- "string, a list of strings, or as an integer".format(flags)
153 ++ raise CommandExecutionError(
154 ++ f'Invalid re flags: "{flags}", must be given either as a single flag '
155 ++ "string, a list of strings, as an integer, or as an re flag"
156 + )
157 +
158 +
159 +@@ -2513,8 +2511,8 @@ def replace(
160 + "Only one of append and prepend_if_not_found is permitted"
161 + )
162 +
163 +- flags_num = _get_flags(flags)
164 +- cpattern = re.compile(salt.utils.stringutils.to_bytes(pattern), flags_num)
165 ++ re_flags = _get_flags(flags)
166 ++ cpattern = re.compile(salt.utils.stringutils.to_bytes(pattern), re_flags)
167 + filesize = os.path.getsize(path)
168 + if bufsize == "file":
169 + bufsize = filesize
170 +@@ -2582,7 +2580,7 @@ def replace(
171 + "^{}($|(?=\r\n))".format(re.escape(content))
172 + ),
173 + r_data,
174 +- flags=flags_num,
175 ++ flags=re_flags,
176 + ):
177 + # Content was found, so set found.
178 + found = True
179 +@@ -3132,7 +3130,11 @@ def search(path, pattern, flags=8, bufsize=1, ignore_if_missing=False, multiline
180 + salt '*' file.search /etc/crontab 'mymaintenance.sh'
181 + """
182 + if multiline:
183 +- flags = _add_flags(flags, "MULTILINE")
184 ++ re_flags = _add_flags(flags, "MULTILINE")
185 ++ else:
186 ++ re_flags = _get_flags(flags)
187 ++
188 ++ if re.RegexFlag.MULTILINE in re_flags:
189 + bufsize = "file"
190 +
191 + # This function wraps file.replace on purpose in order to enforce
192 +@@ -3142,7 +3144,7 @@ def search(path, pattern, flags=8, bufsize=1, ignore_if_missing=False, multiline
193 + path,
194 + pattern,
195 + "",
196 +- flags=flags,
197 ++ flags=re_flags,
198 + bufsize=bufsize,
199 + dry_run=True,
200 + search_only=True,
201
202 diff --git a/app-admin/salt/salt-3005.1-r1.ebuild b/app-admin/salt/salt-3005.1-r1.ebuild
203 new file mode 100644
204 index 000000000000..d0056bab8f71
205 --- /dev/null
206 +++ b/app-admin/salt/salt-3005.1-r1.ebuild
207 @@ -0,0 +1,220 @@
208 +# Copyright 1999-2023 Gentoo Authors
209 +# Distributed under the terms of the GNU General Public License v2
210 +
211 +EAPI=8
212 +PYTHON_COMPAT=( python3_10 )
213 +
214 +DISTUTILS_USE_PEP517=setuptools
215 +inherit systemd distutils-r1
216 +
217 +DESCRIPTION="Salt is a remote execution and configuration manager"
218 +HOMEPAGE="https://www.saltstack.com/resources/community/
219 + https://github.com/saltstack"
220 +
221 +if [[ ${PV} == 9999* ]]; then
222 + inherit git-r3
223 + EGIT_REPO_URI="https://github.com/${PN}stack/${PN}.git"
224 + EGIT_BRANCH="develop"
225 + SRC_URI=""
226 +else
227 + SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.tar.gz"
228 + KEYWORDS="~amd64 ~arm ~arm64 ~riscv ~x86"
229 +fi
230 +
231 +LICENSE="Apache-2.0"
232 +SLOT="0"
233 +IUSE="
234 + cheetah cherrypy ldap libcloud libvirt genshi gnupg keyring mako
235 + mongodb neutron nova openssl portage profile redis selinux test raet
236 + +zeromq vim-syntax
237 +"
238 +
239 +RDEPEND="
240 + sys-apps/pciutils
241 + >=dev-python/distro-1.5[${PYTHON_USEDEP}]
242 + >=dev-python/jinja-3.0.3[${PYTHON_USEDEP}]
243 + dev-python/jmespath[${PYTHON_USEDEP}]
244 + dev-python/libnacl[${PYTHON_USEDEP}]
245 + >=dev-python/msgpack-1.0.0[${PYTHON_USEDEP}]
246 + >=dev-python/psutil-5.0.0[${PYTHON_USEDEP}]
247 + >=dev-python/pycryptodome-3.9.8[${PYTHON_USEDEP}]
248 + dev-python/pyyaml[${PYTHON_USEDEP}]
249 + >=dev-python/markupsafe-2.0.1[${PYTHON_USEDEP}]
250 + >=dev-python/requests-1.0.0[${PYTHON_USEDEP}]
251 + dev-python/setuptools[${PYTHON_USEDEP}]
252 + dev-python/tomli[${PYTHON_USEDEP}]
253 + dev-python/watchdog[${PYTHON_USEDEP}]
254 + libcloud? (
255 + dev-python/aiohttp[${PYTHON_USEDEP}]
256 + dev-python/aiosignal[${PYTHON_USEDEP}]
257 + dev-python/async-timeout[${PYTHON_USEDEP}]
258 + >=dev-python/libcloud-2.5.0[${PYTHON_USEDEP}]
259 + )
260 + mako? ( dev-python/mako[${PYTHON_USEDEP}] )
261 + ldap? ( dev-python/python-ldap[${PYTHON_USEDEP}] )
262 + libvirt? (
263 + dev-python/libvirt-python[${PYTHON_USEDEP}]
264 + )
265 + openssl? (
266 + dev-libs/openssl:0=[-bindist(-)]
267 + dev-python/pyopenssl[${PYTHON_USEDEP}]
268 + )
269 + raet? (
270 + >=dev-python/libnacl-1.0.0[${PYTHON_USEDEP}]
271 + >=dev-python/ioflo-1.1.7[${PYTHON_USEDEP}]
272 + >=dev-python/raet-0.6.0[${PYTHON_USEDEP}]
273 + )
274 + cherrypy? ( >=dev-python/cherrypy-3.2.2[${PYTHON_USEDEP}] )
275 + cheetah? ( >=dev-python/cheetah3-3.2.2[${PYTHON_USEDEP}] )
276 + genshi? ( dev-python/genshi[${PYTHON_USEDEP}] )
277 + mongodb? ( dev-python/pymongo[${PYTHON_USEDEP}] )
278 + portage? ( sys-apps/portage[${PYTHON_USEDEP}] )
279 + keyring? ( dev-python/keyring[${PYTHON_USEDEP}] )
280 + redis? ( dev-python/redis-py[${PYTHON_USEDEP}] )
281 + selinux? ( sec-policy/selinux-salt )
282 + nova? (
283 + >=dev-python/python-novaclient-2.17.0[${PYTHON_USEDEP}]
284 + )
285 + neutron? (
286 + >=dev-python/python-neutronclient-2.3.6[${PYTHON_USEDEP}]
287 + )
288 + gnupg? ( dev-python/python-gnupg[${PYTHON_USEDEP}] )
289 + profile? ( dev-python/yappi[${PYTHON_USEDEP}] )
290 + vim-syntax? ( app-vim/salt-vim )
291 + zeromq? ( >=dev-python/pyzmq-19.0.0[${PYTHON_USEDEP}] )
292 +"
293 +BDEPEND="
294 + test? (
295 + ${RDEPEND}
296 + >=dev-python/boto-2.32.1[${PYTHON_USEDEP}]
297 + dev-python/certifi[${PYTHON_USEDEP}]
298 + dev-python/cherrypy[${PYTHON_USEDEP}]
299 + >=dev-python/jsonschema-3.0[${PYTHON_USEDEP}]
300 + dev-python/mako[${PYTHON_USEDEP}]
301 + >=dev-python/mock-2.0.0[${PYTHON_USEDEP}]
302 + >=dev-python/moto-2.0.0[${PYTHON_USEDEP}]
303 + dev-python/passlib
304 + dev-python/pip[${PYTHON_USEDEP}]
305 + dev-python/pyopenssl[${PYTHON_USEDEP}]
306 + >=dev-python/pytest-7.0.1[${PYTHON_USEDEP}]
307 + >=dev-python/pytest-salt-factories-1.0.0_rc17[${PYTHON_USEDEP}]
308 + dev-python/pytest-tempdir[${PYTHON_USEDEP}]
309 + dev-python/pytest-helpers-namespace[${PYTHON_USEDEP}]
310 + dev-python/pytest-subtests[${PYTHON_USEDEP}]
311 + dev-python/pytest-shell-utilities[${PYTHON_USEDEP}]
312 + dev-python/pytest-skip-markers[${PYTHON_USEDEP}]
313 + dev-python/pytest-system-statistics[${PYTHON_USEDEP}]
314 + dev-python/flaky[${PYTHON_USEDEP}]
315 + dev-python/libcloud[${PYTHON_USEDEP}]
316 + net-dns/bind-tools
317 + >=dev-python/virtualenv-20.3.0[${PYTHON_USEDEP}]
318 + dev-util/yamllint[${PYTHON_USEDEP}]
319 + !x86? ( >=dev-python/boto3-1.17.67[${PYTHON_USEDEP}] )
320 + )
321 +"
322 +
323 +DOCS=( README.rst AUTHORS )
324 +
325 +REQUIRED_USE="|| ( raet zeromq )
326 + test? ( cheetah genshi )"
327 +RESTRICT="!test? ( test ) x86? ( test )"
328 +
329 +PATCHES=(
330 + "${FILESDIR}/salt-3003-skip-tests-that-oom-machine.patch"
331 + "${FILESDIR}/salt-3003-gentoolkit-revdep.patch"
332 + "${FILESDIR}/salt-3002-tests.patch"
333 + "${FILESDIR}/salt-3003.1-tests.patch"
334 + "${FILESDIR}/salt-3005-relax-pyzmq-dep.patch"
335 + "${FILESDIR}/salt-3005-tests.patch"
336 + "${FILESDIR}/salt-3005.1-no-entry-points.patch"
337 + "${FILESDIR}/salt-3005.1-importlib-metadata-5-r1.patch"
338 + "${FILESDIR}/salt-3005.1-tests.patch"
339 + "${FILESDIR}/salt-3005.1-modules-file-python-3.11-host.patch"
340 +)
341 +
342 +python_prepare_all() {
343 + # remove tests with external dependencies that may not be available, and
344 + # tests that don't work in sandbox
345 + rm tests/unit/{test_{zypp_plugins,module_names},utils/test_extend}.py || die
346 + rm tests/unit/modules/test_boto_{vpc,secgroup,elb}.py || die
347 + rm tests/unit/states/test_boto_vpc.py || die
348 + rm tests/support/gitfs.py tests/unit/runners/test_git_pillar.py || die
349 + rm tests/pytests/functional/transport/server/test_req_channel.py || die
350 + rm tests/pytests/functional/utils/test_async_event_publisher.py || die
351 + rm tests/pytests/functional/runners/test_winrepo.py || die
352 +
353 + # tests that require network access
354 + rm tests/unit/{states,modules}/test_zcbuildout.py || die
355 + rm -r tests/integration/cloud || die
356 + rm -r tests/kitchen/tests/wordpress/tests || die
357 + rm tests/kitchen/test_kitchen.py || die
358 + rm tests/unit/modules/test_network.py || die
359 + rm tests/pytests/functional/modules/test_pip.py || die
360 + rm tests/pytests/unit/client/ssh/test_ssh.py || die
361 + rm -r tests/pytests/{integration,functional}/netapi tests/integration/netapi || die
362 +
363 + # tests require root access
364 + rm tests/integration/pillar/test_git_pillar.py || die
365 + rm tests/integration/states/test_supervisord.py || die
366 +
367 + # removes contextvars, see bug: https://bugs.gentoo.org/799431
368 + sed -i '/^contextvars/d' requirements/base.txt || die
369 +
370 + # make sure pkg_resources doesn't bomb because pycrypto isn't installed
371 + find "${S}" -name '*.txt' -print0 | xargs -0 sed -e '/pycrypto>/ d ; /pycryptodomex/ d' -i || die
372 + # pycryptodome rather than pycryptodomex
373 + find "${S}" -name '*.py' -print0 | xargs -0 -- sed -i -e 's:Cryptodome:Crypto:g' -- || die
374 +
375 + distutils-r1_python_prepare_all
376 +}
377 +
378 +python_install_all() {
379 + local svc
380 + USE_SETUPTOOLS=1 distutils-r1_python_install_all
381 +
382 + for svc in minion master syndic api; do
383 + newinitd "${FILESDIR}"/${svc}-initd-5 salt-${svc}
384 + newconfd "${FILESDIR}"/${svc}-confd-1 salt-${svc}
385 + systemd_dounit "${FILESDIR}"/salt-${svc}.service
386 + done
387 +
388 + insinto /etc/${PN}
389 + doins -r conf/*
390 +}
391 +
392 +python_test() {
393 + # testsuite likes lots of files
394 + ulimit -n 4096 || die
395 +
396 + local -a disable_tests=(
397 + # doesn't like the distutils warning
398 + batch_retcode
399 + multiple_modules_in_batch
400 + # hangs indefinitely
401 + master_type_disable
402 + # needs root
403 + runas_env_sudo_group
404 + # don't like sandbox
405 + split_multibyte_characters_{shiftjis,unicode}
406 + # doesn't like sandbox env
407 + log_sanitize
408 + )
409 + local textexpr
410 + testexpr=$(printf 'not %s and ' "${disable_tests[@]}")
411 +
412 + # ${T} is too long a path for the tests to work
413 + local TMPDIR
414 + TMPDIR="$(mktemp --directory --tmpdir=/tmp ${PN}-XXXX)" || die
415 + (
416 + export TMPDIR
417 + cleanup() { rm -rf "${TMPDIR}" || die; }
418 +
419 + trap cleanup EXIT
420 +
421 + addwrite "${TMPDIR}"
422 +
423 + USE_SETUPTOOLS=1 NO_INTERNET=1 SHELL="/bin/bash" \
424 + "${EPYTHON}" -m pytest -vv -k "${testexpr%and }" \
425 + || die "testing failed with ${EPYTHON}"
426 + )
427 +}