ansible-core 2.19.4rc1__py3-none-any.whl → 2.20.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/_internal/__init__.py +1 -4
- ansible/_internal/_ansiballz/_builder.py +1 -3
- ansible/_internal/_collection_proxy.py +7 -9
- ansible/_internal/_json/__init__.py +3 -4
- ansible/_internal/_templating/_engine.py +1 -1
- ansible/_internal/_templating/_jinja_plugins.py +1 -2
- ansible/_internal/_wrapt.py +105 -301
- ansible/cli/__init__.py +11 -10
- ansible/cli/adhoc.py +1 -2
- ansible/cli/arguments/option_helpers.py +1 -1
- ansible/cli/config.py +5 -6
- ansible/cli/doc.py +67 -67
- ansible/cli/galaxy.py +15 -24
- ansible/cli/inventory.py +0 -1
- ansible/cli/playbook.py +0 -1
- ansible/cli/pull.py +0 -1
- ansible/cli/scripts/ansible_connection_cli_stub.py +1 -1
- ansible/config/base.yml +1 -25
- ansible/config/manager.py +0 -2
- ansible/executor/play_iterator.py +42 -20
- ansible/executor/playbook_executor.py +0 -9
- ansible/executor/task_executor.py +26 -18
- ansible/executor/task_queue_manager.py +1 -3
- ansible/galaxy/api.py +33 -80
- ansible/galaxy/collection/__init__.py +11 -21
- ansible/galaxy/dependency_resolution/__init__.py +10 -9
- ansible/galaxy/dependency_resolution/dataclasses.py +86 -70
- ansible/galaxy/dependency_resolution/providers.py +54 -134
- ansible/galaxy/dependency_resolution/versioning.py +2 -4
- ansible/galaxy/role.py +1 -33
- ansible/inventory/manager.py +2 -3
- ansible/keyword_desc.yml +0 -3
- ansible/module_utils/_internal/_datatag/__init__.py +2 -10
- ansible/module_utils/_internal/_no_six.py +86 -0
- ansible/module_utils/_text.py +28 -8
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/basic.py +26 -23
- ansible/module_utils/common/_collections_compat.py +11 -2
- ansible/module_utils/common/collections.py +8 -3
- ansible/module_utils/common/dict_transformations.py +1 -2
- ansible/module_utils/common/network.py +4 -2
- ansible/module_utils/common/parameters.py +32 -41
- ansible/module_utils/common/text/converters.py +109 -23
- ansible/module_utils/common/text/formatters.py +6 -2
- ansible/module_utils/common/validation.py +11 -9
- ansible/module_utils/connection.py +8 -3
- ansible/module_utils/facts/hardware/linux.py +23 -7
- ansible/module_utils/facts/hardware/netbsd.py +1 -1
- ansible/module_utils/facts/hardware/sunos.py +2 -1
- ansible/module_utils/facts/packages.py +6 -2
- ansible/module_utils/facts/system/distribution.py +2 -1
- ansible/module_utils/facts/system/env.py +6 -3
- ansible/module_utils/facts/system/local.py +3 -1
- ansible/module_utils/parsing/convert_bool.py +6 -2
- ansible/module_utils/service.py +2 -3
- ansible/module_utils/six/__init__.py +11 -6
- ansible/module_utils/yumdnf.py +0 -5
- ansible/modules/apt.py +18 -13
- ansible/modules/apt_repository.py +1 -1
- ansible/modules/assemble.py +5 -9
- ansible/modules/blockinfile.py +39 -23
- ansible/modules/cron.py +26 -35
- ansible/modules/deb822_repository.py +83 -12
- ansible/modules/dnf.py +3 -7
- ansible/modules/dnf5.py +4 -6
- ansible/modules/expect.py +0 -3
- ansible/modules/find.py +1 -2
- ansible/modules/get_url.py +1 -1
- ansible/modules/git.py +4 -5
- ansible/modules/include_vars.py +1 -1
- ansible/modules/known_hosts.py +7 -1
- ansible/modules/lineinfile.py +71 -63
- ansible/modules/package_facts.py +1 -1
- ansible/modules/pip.py +8 -2
- ansible/modules/replace.py +6 -6
- ansible/modules/service.py +3 -4
- ansible/modules/stat.py +20 -0
- ansible/modules/uri.py +9 -10
- ansible/modules/user.py +1 -2
- ansible/modules/wait_for.py +2 -2
- ansible/modules/wait_for_connection.py +2 -1
- ansible/modules/yum_repository.py +1 -16
- ansible/parsing/dataloader.py +24 -31
- ansible/parsing/vault/__init__.py +1 -2
- ansible/playbook/base.py +8 -56
- ansible/playbook/block.py +0 -60
- ansible/playbook/collectionsearch.py +1 -2
- ansible/playbook/handler.py +1 -7
- ansible/playbook/helpers.py +0 -7
- ansible/playbook/included_file.py +1 -1
- ansible/playbook/play.py +102 -36
- ansible/playbook/play_context.py +4 -0
- ansible/playbook/role/__init__.py +10 -65
- ansible/playbook/role/definition.py +3 -4
- ansible/playbook/role/include.py +2 -3
- ansible/playbook/role/metadata.py +1 -12
- ansible/playbook/role/requirement.py +1 -2
- ansible/playbook/role_include.py +1 -2
- ansible/playbook/taggable.py +16 -5
- ansible/playbook/task.py +11 -50
- ansible/plugins/action/__init__.py +20 -19
- ansible/plugins/action/add_host.py +1 -2
- ansible/plugins/action/fetch.py +3 -5
- ansible/plugins/action/group_by.py +1 -2
- ansible/plugins/action/include_vars.py +20 -22
- ansible/plugins/action/script.py +1 -3
- ansible/plugins/action/template.py +1 -2
- ansible/plugins/action/uri.py +4 -2
- ansible/plugins/cache/__init__.py +1 -0
- ansible/plugins/callback/__init__.py +13 -6
- ansible/plugins/connection/__init__.py +3 -7
- ansible/plugins/connection/local.py +2 -3
- ansible/plugins/connection/psrp.py +0 -2
- ansible/plugins/connection/ssh.py +2 -7
- ansible/plugins/connection/winrm.py +0 -2
- ansible/plugins/doc_fragments/result_format_callback.py +15 -0
- ansible/plugins/filter/core.py +4 -5
- ansible/plugins/filter/encryption.py +3 -27
- ansible/plugins/filter/mathstuff.py +1 -2
- ansible/plugins/filter/to_nice_yaml.yml +31 -3
- ansible/plugins/filter/to_yaml.yml +29 -12
- ansible/plugins/inventory/__init__.py +1 -2
- ansible/plugins/inventory/toml.py +3 -6
- ansible/plugins/inventory/yaml.py +1 -2
- ansible/plugins/loader.py +3 -4
- ansible/plugins/lookup/password.py +1 -2
- ansible/plugins/lookup/subelements.py +2 -3
- ansible/plugins/lookup/url.py +1 -1
- ansible/plugins/lookup/varnames.py +1 -2
- ansible/plugins/shell/__init__.py +9 -4
- ansible/plugins/shell/powershell.py +8 -24
- ansible/plugins/strategy/__init__.py +5 -2
- ansible/plugins/test/core.py +4 -1
- ansible/plugins/test/falsy.yml +1 -1
- ansible/plugins/test/regex.yml +18 -6
- ansible/plugins/test/truthy.yml +1 -1
- ansible/release.py +2 -2
- ansible/template/__init__.py +3 -7
- ansible/utils/collection_loader/_collection_config.py +5 -0
- ansible/utils/collection_loader/_collection_finder.py +11 -14
- ansible/utils/context_objects.py +7 -4
- ansible/utils/display.py +7 -6
- ansible/utils/encrypt.py +0 -5
- ansible/utils/helpers.py +6 -2
- ansible/utils/jsonrpc.py +7 -3
- ansible/utils/plugin_docs.py +49 -38
- ansible/utils/ssh_functions.py +0 -19
- ansible/utils/unsafe_proxy.py +7 -7
- ansible/vars/clean.py +2 -3
- ansible/vars/manager.py +28 -22
- ansible/vars/plugins.py +1 -31
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/METADATA +4 -4
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/RECORD +213 -214
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/network.txt +0 -1
- ansible_test/_data/completion/remote.txt +4 -4
- ansible_test/_data/requirements/ansible-test.txt +1 -1
- ansible_test/_data/requirements/ansible.txt +1 -1
- ansible_test/_data/requirements/sanity.ansible-doc.txt +2 -2
- ansible_test/_data/requirements/sanity.changelog.txt +2 -2
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.import.txt +1 -1
- ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -1
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +6 -6
- ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -1
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_internal/cache.py +2 -5
- ansible_test/_internal/cli/compat.py +1 -1
- ansible_test/_internal/commands/coverage/combine.py +1 -3
- ansible_test/_internal/commands/integration/__init__.py +3 -7
- ansible_test/_internal/commands/integration/cloud/httptester.py +1 -1
- ansible_test/_internal/commands/integration/coverage.py +1 -3
- ansible_test/_internal/commands/integration/filters.py +5 -10
- ansible_test/_internal/commands/sanity/pylint.py +11 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -5
- ansible_test/_internal/commands/units/__init__.py +1 -13
- ansible_test/_internal/compat/packaging.py +2 -2
- ansible_test/_internal/compat/yaml.py +2 -2
- ansible_test/_internal/completion.py +2 -5
- ansible_test/_internal/config.py +2 -7
- ansible_test/_internal/coverage_util.py +1 -1
- ansible_test/_internal/delegation.py +2 -0
- ansible_test/_internal/docker_util.py +1 -1
- ansible_test/_internal/host_profiles.py +6 -11
- ansible_test/_internal/provider/__init__.py +2 -5
- ansible_test/_internal/provisioning.py +2 -5
- ansible_test/_internal/pypi_proxy.py +1 -1
- ansible_test/_internal/python_requirements.py +1 -1
- ansible_test/_internal/target.py +2 -6
- ansible_test/_internal/thread.py +1 -4
- ansible_test/_internal/util.py +9 -14
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +14 -19
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +48 -45
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +9 -7
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +51 -37
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +31 -18
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +1 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +59 -71
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -2
- ansible_test/_util/target/cli/ansible_test_cli_stub.py +4 -2
- ansible_test/_util/target/common/constants.py +2 -2
- ansible_test/_util/target/setup/bootstrap.sh +0 -6
- ansible/utils/py3compat.py +0 -27
- ansible_test/_data/pytest/config/legacy.ini +0 -4
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/licenses/licenses/BSD-3-Clause.txt +0 -0
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.19.4rc1.dist-info → ansible_core-2.20.0.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
base image=quay.io/ansible/base-test-container:
|
|
2
|
-
default image=quay.io/ansible/default-test-container:
|
|
3
|
-
default image=quay.io/ansible/ansible-core-test-container:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
ubuntu2204 image=quay.io/ansible/
|
|
7
|
-
ubuntu2404 image=quay.io/ansible/
|
|
1
|
+
base image=quay.io/ansible/base-test-container:v2.20-2 python=3.14,3.9,3.10,3.11,3.12,3.13
|
|
2
|
+
default image=quay.io/ansible/default-test-container:v2.20-4 python=3.14,3.9,3.10,3.11,3.12,3.13 context=collection
|
|
3
|
+
default image=quay.io/ansible/ansible-core-test-container:v2.20-4 python=3.14,3.9,3.10,3.11,3.12,3.13 context=ansible-core
|
|
4
|
+
alpine322 image=quay.io/ansible/alpine-test-container:3.22-v2.20-1 python=3.12 cgroup=none audit=none
|
|
5
|
+
fedora42 image=quay.io/ansible/fedora-test-container:42-v2.20-1 python=3.13 cgroup=v2-only
|
|
6
|
+
ubuntu2204 image=quay.io/ansible/ubuntu-test-container:22.04-v2.20-1 python=3.10
|
|
7
|
+
ubuntu2404 image=quay.io/ansible/ubuntu-test-container:24.04-v2.20-1 python=3.12
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ios/csr1000v collection=cisco.ios connection=ansible.netcommon.network_cli provider=aws arch=x86_64
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
alpine/3.
|
|
1
|
+
alpine/3.22 python=3.12 become=doas_sudo provider=aws arch=x86_64
|
|
2
2
|
alpine become=doas_sudo provider=aws arch=x86_64
|
|
3
|
-
fedora/
|
|
3
|
+
fedora/42 python=3.13 become=sudo provider=aws arch=x86_64
|
|
4
4
|
fedora become=sudo provider=aws arch=x86_64
|
|
5
5
|
freebsd/13.5 python=3.11 python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
|
|
6
|
-
freebsd/14.
|
|
6
|
+
freebsd/14.3 python=3.11 python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
|
|
7
7
|
freebsd python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
|
|
8
8
|
macos/15.3 python=3.13 python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64
|
|
9
9
|
macos python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64
|
|
10
|
-
rhel/9.
|
|
10
|
+
rhel/9.6 python=3.9,3.12 become=sudo provider=aws arch=x86_64
|
|
11
11
|
rhel/10.0 python=3.12 become=sudo provider=aws arch=x86_64
|
|
12
12
|
rhel become=sudo provider=aws arch=x86_64
|
|
13
13
|
ubuntu/22.04 python=3.10 become=sudo provider=aws arch=x86_64
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# The test-constraints sanity test verifies this file, but changes must be made manually to keep it in up-to-date.
|
|
2
|
-
coverage == 7.
|
|
2
|
+
coverage == 7.10.7 ; python_version >= '3.9' and python_version <= '3.14'
|
|
@@ -12,4 +12,4 @@ packaging
|
|
|
12
12
|
# NOTE: Ref: https://github.com/sarugaku/resolvelib/issues/69
|
|
13
13
|
# NOTE: When updating the upper bound, also update the latest version used
|
|
14
14
|
# NOTE: in the ansible-galaxy-collection test suite.
|
|
15
|
-
resolvelib >= 0.
|
|
15
|
+
resolvelib >= 0.8.0, < 2.0.0 # dependency resolver used by ansible-galaxy
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# edit "sanity.import.in" and generate with: hacking/update-sanity-requirements.py --test import
|
|
2
|
-
PyYAML==6.0.
|
|
2
|
+
PyYAML==6.0.3
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# edit "sanity.integration-aliases.in" and generate with: hacking/update-sanity-requirements.py --test integration-aliases
|
|
2
|
-
PyYAML==6.0.
|
|
2
|
+
PyYAML==6.0.3
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# edit "sanity.pep8.in" and generate with: hacking/update-sanity-requirements.py --test pep8
|
|
2
|
-
pycodestyle==2.
|
|
2
|
+
pycodestyle==2.14.0
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# edit "sanity.pylint.in" and generate with: hacking/update-sanity-requirements.py --test pylint
|
|
2
|
-
astroid==
|
|
2
|
+
astroid==4.0.1
|
|
3
3
|
dill==0.4.0
|
|
4
|
-
isort==
|
|
4
|
+
isort==7.0.0
|
|
5
5
|
mccabe==0.7.0
|
|
6
|
-
platformdirs==4.
|
|
7
|
-
pylint==
|
|
8
|
-
PyYAML==6.0.
|
|
9
|
-
tomlkit==0.13.
|
|
6
|
+
platformdirs==4.5.0
|
|
7
|
+
pylint==4.0.2
|
|
8
|
+
PyYAML==6.0.3
|
|
9
|
+
tomlkit==0.13.3
|
ansible_test/_internal/cache.py
CHANGED
|
@@ -3,14 +3,11 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import collections.abc as c
|
|
6
|
-
import typing as t
|
|
7
6
|
|
|
8
7
|
from .config import (
|
|
9
8
|
CommonConfig,
|
|
10
9
|
)
|
|
11
10
|
|
|
12
|
-
TValue = t.TypeVar('TValue')
|
|
13
|
-
|
|
14
11
|
|
|
15
12
|
class CommonCache:
|
|
16
13
|
"""Common cache."""
|
|
@@ -18,14 +15,14 @@ class CommonCache:
|
|
|
18
15
|
def __init__(self, args: CommonConfig) -> None:
|
|
19
16
|
self.args = args
|
|
20
17
|
|
|
21
|
-
def get(self, key: str, factory: c.Callable[[], TValue]) -> TValue:
|
|
18
|
+
def get[TValue](self, key: str, factory: c.Callable[[], TValue]) -> TValue:
|
|
22
19
|
"""Return the value from the cache identified by the given key, using the specified factory method if it is not found."""
|
|
23
20
|
if key not in self.args.cache:
|
|
24
21
|
self.args.cache[key] = factory()
|
|
25
22
|
|
|
26
23
|
return self.args.cache[key]
|
|
27
24
|
|
|
28
|
-
def get_with_args(self, key: str, factory: c.Callable[[CommonConfig], TValue]) -> TValue:
|
|
25
|
+
def get_with_args[TValue](self, key: str, factory: c.Callable[[CommonConfig], TValue]) -> TValue:
|
|
29
26
|
"""Return the value from the cache identified by the given key, using the specified factory method (which accepts args) if it is not found."""
|
|
30
27
|
if key not in self.args.cache:
|
|
31
28
|
self.args.cache[key] = factory(self.args)
|
|
@@ -69,7 +69,7 @@ def controller_python(version: t.Optional[str]) -> t.Optional[str]:
|
|
|
69
69
|
|
|
70
70
|
def get_fallback_remote_controller() -> str:
|
|
71
71
|
"""Return the remote fallback platform for the controller."""
|
|
72
|
-
platform = '
|
|
72
|
+
platform = 'fedora' # Fedora is lower cost than other remotes and always supports a recent Python version
|
|
73
73
|
candidates = [item for item in filter_completion(remote_completion()).values() if item.controller_supported and item.platform == platform]
|
|
74
74
|
fallback = sorted(candidates, key=lambda value: str_to_version(value.version), reverse=True)[0]
|
|
75
75
|
return fallback.name
|
|
@@ -63,8 +63,6 @@ from . import (
|
|
|
63
63
|
PathChecker,
|
|
64
64
|
)
|
|
65
65
|
|
|
66
|
-
TValue = t.TypeVar('TValue')
|
|
67
|
-
|
|
68
66
|
|
|
69
67
|
def command_coverage_combine(args: CoverageCombineConfig) -> None:
|
|
70
68
|
"""Patch paths in coverage files and merge into a single file."""
|
|
@@ -287,7 +285,7 @@ def _get_coverage_targets(args: CoverageCombineConfig, walk_func: c.Callable) ->
|
|
|
287
285
|
return sources
|
|
288
286
|
|
|
289
287
|
|
|
290
|
-
def _build_stub_groups(
|
|
288
|
+
def _build_stub_groups[TValue](
|
|
291
289
|
args: CoverageCombineConfig,
|
|
292
290
|
sources: list[tuple[str, int]],
|
|
293
291
|
default_stub_value: c.Callable[[list[str]], dict[str, TValue]],
|
|
@@ -41,7 +41,6 @@ from ...target import (
|
|
|
41
41
|
walk_integration_targets,
|
|
42
42
|
IntegrationTarget,
|
|
43
43
|
walk_internal_targets,
|
|
44
|
-
TIntegrationTarget,
|
|
45
44
|
IntegrationTargetType,
|
|
46
45
|
)
|
|
47
46
|
|
|
@@ -50,7 +49,6 @@ from ...config import (
|
|
|
50
49
|
NetworkIntegrationConfig,
|
|
51
50
|
PosixIntegrationConfig,
|
|
52
51
|
WindowsIntegrationConfig,
|
|
53
|
-
TIntegrationConfig,
|
|
54
52
|
)
|
|
55
53
|
|
|
56
54
|
from ...io import (
|
|
@@ -132,8 +130,6 @@ from .coverage import (
|
|
|
132
130
|
CoverageManager,
|
|
133
131
|
)
|
|
134
132
|
|
|
135
|
-
THostProfile = t.TypeVar('THostProfile', bound=HostProfile)
|
|
136
|
-
|
|
137
133
|
|
|
138
134
|
def generate_dependency_map(integration_targets: list[IntegrationTarget]) -> dict[str, set[IntegrationTarget]]:
|
|
139
135
|
"""Analyze the given list of integration test targets and return a dictionary expressing target names and the targets on which they depend."""
|
|
@@ -331,7 +327,7 @@ def integration_test_environment(
|
|
|
331
327
|
display.info('Copying %s/ to %s/' % (dir_src, dir_dst), verbosity=2)
|
|
332
328
|
|
|
333
329
|
if not args.explain:
|
|
334
|
-
shutil.copytree(to_bytes(dir_src), to_bytes(dir_dst), symlinks=True) # type: ignore[arg-type] #
|
|
330
|
+
shutil.copytree(to_bytes(dir_src), to_bytes(dir_dst), symlinks=True) # type: ignore[type-var,arg-type] # type stub omits bytes path support
|
|
335
331
|
|
|
336
332
|
for file_src, file_dst in file_copies:
|
|
337
333
|
display.info('Copying %s to %s' % (file_src, file_dst), verbosity=2)
|
|
@@ -856,7 +852,7 @@ class IntegrationCache(CommonCache):
|
|
|
856
852
|
return self.get('dependency_map', lambda: generate_dependency_map(self.integration_targets))
|
|
857
853
|
|
|
858
854
|
|
|
859
|
-
def filter_profiles_for_target(args: IntegrationConfig, profiles: list[
|
|
855
|
+
def filter_profiles_for_target[T: HostProfile](args: IntegrationConfig, profiles: list[T], target: IntegrationTarget) -> list[T]:
|
|
860
856
|
"""Return a list of profiles after applying target filters."""
|
|
861
857
|
if target.target_type == IntegrationTargetType.CONTROLLER:
|
|
862
858
|
profile_filter = get_target_filter(args, [args.controller], True)
|
|
@@ -912,7 +908,7 @@ If necessary, context can be controlled by adding entries to the "aliases" file
|
|
|
912
908
|
return exclude
|
|
913
909
|
|
|
914
910
|
|
|
915
|
-
def command_integration_filter(
|
|
911
|
+
def command_integration_filter[TIntegrationTarget: IntegrationTarget, TIntegrationConfig: IntegrationConfig](
|
|
916
912
|
args: TIntegrationConfig,
|
|
917
913
|
targets: c.Iterable[TIntegrationTarget],
|
|
918
914
|
) -> tuple[HostState, tuple[TIntegrationTarget, ...]]:
|
|
@@ -32,7 +32,7 @@ class HttptesterProvider(CloudProvider):
|
|
|
32
32
|
def __init__(self, args: IntegrationConfig) -> None:
|
|
33
33
|
super().__init__(args)
|
|
34
34
|
|
|
35
|
-
self.image = os.environ.get('ANSIBLE_HTTP_TEST_CONTAINER', 'quay.io/ansible/http-test-container:3.
|
|
35
|
+
self.image = os.environ.get('ANSIBLE_HTTP_TEST_CONTAINER', 'quay.io/ansible/http-test-container:3.5.0')
|
|
36
36
|
|
|
37
37
|
self.uses_docker = True
|
|
38
38
|
|
|
@@ -79,10 +79,8 @@ from ...inventory import (
|
|
|
79
79
|
create_posix_inventory,
|
|
80
80
|
)
|
|
81
81
|
|
|
82
|
-
THostConfig = t.TypeVar('THostConfig', bound=HostConfig)
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
class CoverageHandler(t.Generic[THostConfig], metaclass=abc.ABCMeta):
|
|
83
|
+
class CoverageHandler[THostConfig: HostConfig](metaclass=abc.ABCMeta):
|
|
86
84
|
"""Base class for configuring hosts for integration test code coverage."""
|
|
87
85
|
|
|
88
86
|
def __init__(self, args: IntegrationConfig, host_state: HostState, inventory_path: str) -> None:
|
|
@@ -40,13 +40,8 @@ from ...host_profiles import (
|
|
|
40
40
|
HostProfile,
|
|
41
41
|
)
|
|
42
42
|
|
|
43
|
-
THostConfig = t.TypeVar('THostConfig', bound=HostConfig)
|
|
44
|
-
TPosixConfig = t.TypeVar('TPosixConfig', bound=PosixConfig)
|
|
45
|
-
TRemoteConfig = t.TypeVar('TRemoteConfig', bound=RemoteConfig)
|
|
46
|
-
THostProfile = t.TypeVar('THostProfile', bound=HostProfile)
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
class TargetFilter(t.Generic[THostConfig], metaclass=abc.ABCMeta):
|
|
44
|
+
class TargetFilter[THostConfig: HostConfig](metaclass=abc.ABCMeta):
|
|
50
45
|
"""Base class for target filters."""
|
|
51
46
|
|
|
52
47
|
def __init__(self, args: IntegrationConfig, configs: list[THostConfig], controller: bool) -> None:
|
|
@@ -92,7 +87,7 @@ class TargetFilter(t.Generic[THostConfig], metaclass=abc.ABCMeta):
|
|
|
92
87
|
exclude.update(skipped)
|
|
93
88
|
display.warning(f'Excluding {self.host_type} tests marked {marked} {reason}: {", ".join(skipped)}')
|
|
94
89
|
|
|
95
|
-
def filter_profiles(self, profiles: list[THostProfile], target: IntegrationTarget) -> list[THostProfile]:
|
|
90
|
+
def filter_profiles[THostProfile: HostProfile](self, profiles: list[THostProfile], target: IntegrationTarget) -> list[THostProfile]:
|
|
96
91
|
"""Filter the list of profiles, returning only those which are not skipped for the given target."""
|
|
97
92
|
del target
|
|
98
93
|
return profiles
|
|
@@ -138,7 +133,7 @@ class TargetFilter(t.Generic[THostConfig], metaclass=abc.ABCMeta):
|
|
|
138
133
|
self.skip('unstable', 'which require --allow-unstable or prefixing with "unstable/"', targets, exclude, override)
|
|
139
134
|
|
|
140
135
|
|
|
141
|
-
class PosixTargetFilter(TargetFilter[TPosixConfig]):
|
|
136
|
+
class PosixTargetFilter[TPosixConfig: PosixConfig](TargetFilter[TPosixConfig]):
|
|
142
137
|
"""Target filter for POSIX hosts."""
|
|
143
138
|
|
|
144
139
|
def filter_targets(self, targets: list[IntegrationTarget], exclude: set[str]) -> None:
|
|
@@ -169,10 +164,10 @@ class PosixSshTargetFilter(PosixTargetFilter[PosixSshConfig]):
|
|
|
169
164
|
"""Target filter for POSIX SSH hosts."""
|
|
170
165
|
|
|
171
166
|
|
|
172
|
-
class RemoteTargetFilter(TargetFilter[TRemoteConfig]):
|
|
167
|
+
class RemoteTargetFilter[TRemoteConfig: RemoteConfig](TargetFilter[TRemoteConfig]):
|
|
173
168
|
"""Target filter for remote Ansible Core CI managed hosts."""
|
|
174
169
|
|
|
175
|
-
def filter_profiles(self, profiles: list[THostProfile], target: IntegrationTarget) -> list[THostProfile]:
|
|
170
|
+
def filter_profiles[THostProfile: HostProfile](self, profiles: list[THostProfile], target: IntegrationTarget) -> list[THostProfile]:
|
|
176
171
|
"""Filter the list of profiles, returning only those which are not skipped for the given target."""
|
|
177
172
|
profiles = super().filter_profiles(profiles, target)
|
|
178
173
|
|
|
@@ -301,4 +301,15 @@ class PylintTest(SanitySingleVersion):
|
|
|
301
301
|
else:
|
|
302
302
|
messages = []
|
|
303
303
|
|
|
304
|
+
expected_paths = set(paths)
|
|
305
|
+
|
|
306
|
+
unexpected_messages = [message for message in messages if message["path"] not in expected_paths]
|
|
307
|
+
messages = [message for message in messages if message["path"] in expected_paths]
|
|
308
|
+
|
|
309
|
+
for unexpected_message in unexpected_messages:
|
|
310
|
+
display.info(f"Unexpected message: {json.dumps(unexpected_message)}", verbosity=4)
|
|
311
|
+
|
|
312
|
+
if unexpected_messages:
|
|
313
|
+
display.notice(f"Discarded {len(unexpected_messages)} unexpected messages. Use -vvvv to display.")
|
|
314
|
+
|
|
304
315
|
return messages
|
|
@@ -160,11 +160,7 @@ class ValidateModulesTest(SanitySingleVersion):
|
|
|
160
160
|
temp_dir = process_scoped_temporary_directory(args)
|
|
161
161
|
|
|
162
162
|
with tarfile.open(path) as file:
|
|
163
|
-
|
|
164
|
-
if hasattr(tarfile, 'data_filter'):
|
|
165
|
-
file.extractall(temp_dir, filter='data') # type: ignore[call-arg]
|
|
166
|
-
else:
|
|
167
|
-
file.extractall(temp_dir)
|
|
163
|
+
file.extractall(temp_dir, filter='data')
|
|
168
164
|
|
|
169
165
|
cmd.extend([
|
|
170
166
|
'--original-plugins', temp_dir,
|
|
@@ -241,19 +241,7 @@ def command_units(args: UnitsConfig) -> None:
|
|
|
241
241
|
sys.exit()
|
|
242
242
|
|
|
243
243
|
for test_context, python, paths, env in test_sets:
|
|
244
|
-
|
|
245
|
-
# This is done by enabling the mock_use_standalone_module feature, which forces use of mock even when unittest.mock is available.
|
|
246
|
-
# Later Python versions have not introduced additional unittest.mock features, so use of mock is not needed as of Python 3.8.
|
|
247
|
-
# If future Python versions introduce new unittest.mock features, they will not be available to older Python versions.
|
|
248
|
-
# Having the cutoff at Python 3.8 also eases packaging of ansible-core since no supported controller version requires the use of mock.
|
|
249
|
-
#
|
|
250
|
-
# NOTE: This only affects use of pytest-mock.
|
|
251
|
-
# Collection unit tests may directly import mock, which will be provided by ansible-test when it installs requirements using pip.
|
|
252
|
-
# Although mock is available for ansible-core unit tests, they should import unittest.mock instead.
|
|
253
|
-
if str_to_version(python.version) < (3, 8):
|
|
254
|
-
config_name = 'legacy.ini'
|
|
255
|
-
else:
|
|
256
|
-
config_name = 'default.ini'
|
|
244
|
+
config_name = 'default.ini'
|
|
257
245
|
|
|
258
246
|
cmd = [
|
|
259
247
|
'pytest',
|
|
@@ -12,8 +12,8 @@ try:
|
|
|
12
12
|
|
|
13
13
|
SpecifierSet: t.Optional[t.Type[specifiers.SpecifierSet]] = specifiers.SpecifierSet
|
|
14
14
|
Version: t.Optional[t.Type[version.Version]] = version.Version
|
|
15
|
-
PACKAGING_IMPORT_ERROR = None
|
|
15
|
+
PACKAGING_IMPORT_ERROR = None # pylint: disable=invalid-name
|
|
16
16
|
except ImportError as ex:
|
|
17
17
|
SpecifierSet = None # pylint: disable=invalid-name
|
|
18
18
|
Version = None # pylint: disable=invalid-name
|
|
19
|
-
PACKAGING_IMPORT_ERROR = ex
|
|
19
|
+
PACKAGING_IMPORT_ERROR = ex # pylint: disable=invalid-name
|
|
@@ -11,10 +11,10 @@ from functools import (
|
|
|
11
11
|
try:
|
|
12
12
|
import yaml as _yaml
|
|
13
13
|
|
|
14
|
-
YAML_IMPORT_ERROR = None
|
|
14
|
+
YAML_IMPORT_ERROR = None # pylint: disable=invalid-name
|
|
15
15
|
except ImportError as ex:
|
|
16
16
|
yaml_load = None # pylint: disable=invalid-name
|
|
17
|
-
YAML_IMPORT_ERROR = ex
|
|
17
|
+
YAML_IMPORT_ERROR = ex # pylint: disable=invalid-name
|
|
18
18
|
else:
|
|
19
19
|
try:
|
|
20
20
|
_SafeLoader: t.Union[t.Type[_yaml.CSafeLoader], t.Type[_yaml.SafeLoader]] = _yaml.CSafeLoader
|
|
@@ -250,10 +250,7 @@ class WindowsRemoteCompletionConfig(RemoteCompletionConfig):
|
|
|
250
250
|
connection: str = ''
|
|
251
251
|
|
|
252
252
|
|
|
253
|
-
TCompletionConfig
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
def load_completion(name: str, completion_type: t.Type[TCompletionConfig]) -> dict[str, TCompletionConfig]:
|
|
253
|
+
def load_completion[TCompletionConfig: CompletionConfig](name: str, completion_type: t.Type[TCompletionConfig]) -> dict[str, TCompletionConfig]:
|
|
257
254
|
"""Load the named completion entries, returning them in dictionary form using the specified completion type."""
|
|
258
255
|
lines = read_lines_without_comments(os.path.join(ANSIBLE_TEST_DATA_ROOT, 'completion', '%s.txt' % name), remove_blank_lines=True)
|
|
259
256
|
|
|
@@ -283,7 +280,7 @@ def parse_completion_entry(value: str) -> tuple[str, dict[str, str]]:
|
|
|
283
280
|
return name, data
|
|
284
281
|
|
|
285
282
|
|
|
286
|
-
def filter_completion(
|
|
283
|
+
def filter_completion[TCompletionConfig: CompletionConfig](
|
|
287
284
|
completion: dict[str, TCompletionConfig],
|
|
288
285
|
controller_only: bool = False,
|
|
289
286
|
include_defaults: bool = False,
|
ansible_test/_internal/config.py
CHANGED
|
@@ -38,8 +38,6 @@ from .host_configs import (
|
|
|
38
38
|
VirtualPythonConfig,
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
-
THostConfig = t.TypeVar('THostConfig', bound=HostConfig)
|
|
42
|
-
|
|
43
41
|
|
|
44
42
|
class TerminateMode(enum.Enum):
|
|
45
43
|
"""When to terminate instances."""
|
|
@@ -166,7 +164,7 @@ class EnvironmentConfig(CommonConfig):
|
|
|
166
164
|
"""Host configuration for the targets."""
|
|
167
165
|
return self.host_settings.targets
|
|
168
166
|
|
|
169
|
-
def only_target(self, target_type: t.Type[THostConfig]) -> THostConfig:
|
|
167
|
+
def only_target[THostConfig: HostConfig](self, target_type: t.Type[THostConfig]) -> THostConfig:
|
|
170
168
|
"""
|
|
171
169
|
Return the host configuration for the target.
|
|
172
170
|
Requires that there is exactly one target of the specified type.
|
|
@@ -183,7 +181,7 @@ class EnvironmentConfig(CommonConfig):
|
|
|
183
181
|
|
|
184
182
|
return target
|
|
185
183
|
|
|
186
|
-
def only_targets(self, target_type: t.Type[THostConfig]) -> list[THostConfig]:
|
|
184
|
+
def only_targets[THostConfig: HostConfig](self, target_type: t.Type[THostConfig]) -> list[THostConfig]:
|
|
187
185
|
"""
|
|
188
186
|
Return a list of target host configurations.
|
|
189
187
|
Requires that there are one or more targets, all the specified type.
|
|
@@ -318,9 +316,6 @@ class IntegrationConfig(TestConfig):
|
|
|
318
316
|
return ansible_config_path
|
|
319
317
|
|
|
320
318
|
|
|
321
|
-
TIntegrationConfig = t.TypeVar('TIntegrationConfig', bound=IntegrationConfig)
|
|
322
|
-
|
|
323
|
-
|
|
324
319
|
class PosixIntegrationConfig(IntegrationConfig):
|
|
325
320
|
"""Configuration for the posix integration command."""
|
|
326
321
|
|
|
@@ -69,7 +69,7 @@ class CoverageVersion:
|
|
|
69
69
|
|
|
70
70
|
COVERAGE_VERSIONS = (
|
|
71
71
|
# IMPORTANT: Keep this in sync with the ansible-test.txt requirements file.
|
|
72
|
-
CoverageVersion('7.
|
|
72
|
+
CoverageVersion('7.10.7', 7, (3, 9), (3, 14)),
|
|
73
73
|
)
|
|
74
74
|
"""
|
|
75
75
|
This tuple specifies the coverage version to use for Python version ranges.
|
|
@@ -124,6 +124,8 @@ def delegate(args: CommonConfig, host_state: HostState, exclude: list[str], requ
|
|
|
124
124
|
@contextlib.contextmanager
|
|
125
125
|
def metadata_context(args: EnvironmentConfig) -> t.Generator[None]:
|
|
126
126
|
"""A context manager which exports delegation metadata."""
|
|
127
|
+
os.makedirs(ResultType.TMP.path, exist_ok=True)
|
|
128
|
+
|
|
127
129
|
with tempfile.NamedTemporaryFile(prefix='metadata-', suffix='.json', dir=ResultType.TMP.path) as metadata_fd:
|
|
128
130
|
args.metadata_path = os.path.join(ResultType.TMP.relative_path, os.path.basename(metadata_fd.name))
|
|
129
131
|
args.metadata.to_file(args.metadata_path)
|
|
@@ -50,7 +50,7 @@ DOCKER_COMMANDS = [
|
|
|
50
50
|
'podman',
|
|
51
51
|
]
|
|
52
52
|
|
|
53
|
-
UTILITY_IMAGE = 'quay.io/ansible/ansible-test-utility-container:3.
|
|
53
|
+
UTILITY_IMAGE = 'quay.io/ansible/ansible-test-utility-container:3.4.0'
|
|
54
54
|
|
|
55
55
|
# Max number of open files in a docker container.
|
|
56
56
|
# Passed with --ulimit option to the docker run command.
|
|
@@ -144,11 +144,6 @@ from .debugging import (
|
|
|
144
144
|
DebuggerSettings,
|
|
145
145
|
)
|
|
146
146
|
|
|
147
|
-
TControllerHostConfig = t.TypeVar('TControllerHostConfig', bound=ControllerHostConfig)
|
|
148
|
-
THostConfig = t.TypeVar('THostConfig', bound=HostConfig)
|
|
149
|
-
TPosixConfig = t.TypeVar('TPosixConfig', bound=PosixConfig)
|
|
150
|
-
TRemoteConfig = t.TypeVar('TRemoteConfig', bound=RemoteConfig)
|
|
151
|
-
|
|
152
147
|
|
|
153
148
|
class ControlGroupError(ApplicationError):
|
|
154
149
|
"""Raised when the container host does not have the necessary cgroup support to run a container."""
|
|
@@ -239,7 +234,7 @@ class Inventory:
|
|
|
239
234
|
display.info(f'>>> Inventory\n{inventory_text}', verbosity=3)
|
|
240
235
|
|
|
241
236
|
|
|
242
|
-
class HostProfile
|
|
237
|
+
class HostProfile[THostConfig: HostConfig](metaclass=abc.ABCMeta):
|
|
243
238
|
"""Base class for host profiles."""
|
|
244
239
|
|
|
245
240
|
def __init__(
|
|
@@ -299,7 +294,7 @@ class HostProfile(t.Generic[THostConfig], metaclass=abc.ABCMeta):
|
|
|
299
294
|
return f'{self.__class__.__name__}: {self.name}'
|
|
300
295
|
|
|
301
296
|
|
|
302
|
-
class DebuggableProfile(HostProfile[THostConfig], DebuggerProfile, metaclass=abc.ABCMeta):
|
|
297
|
+
class DebuggableProfile[THostConfig: HostConfig](HostProfile[THostConfig], DebuggerProfile, metaclass=abc.ABCMeta):
|
|
303
298
|
"""Base class for profiles remote debugging."""
|
|
304
299
|
|
|
305
300
|
__DEBUGGING_PORT_KEY = 'debugging_port'
|
|
@@ -465,7 +460,7 @@ class DebuggableProfile(HostProfile[THostConfig], DebuggerProfile, metaclass=abc
|
|
|
465
460
|
)
|
|
466
461
|
|
|
467
462
|
|
|
468
|
-
class PosixProfile(HostProfile[TPosixConfig], metaclass=abc.ABCMeta):
|
|
463
|
+
class PosixProfile[TPosixConfig: PosixConfig](HostProfile[TPosixConfig], metaclass=abc.ABCMeta):
|
|
469
464
|
"""Base class for POSIX host profiles."""
|
|
470
465
|
|
|
471
466
|
@property
|
|
@@ -487,7 +482,7 @@ class PosixProfile(HostProfile[TPosixConfig], metaclass=abc.ABCMeta):
|
|
|
487
482
|
return python
|
|
488
483
|
|
|
489
484
|
|
|
490
|
-
class ControllerHostProfile(PosixProfile[
|
|
485
|
+
class ControllerHostProfile[T: ControllerHostConfig](PosixProfile[T], DebuggableProfile[T], metaclass=abc.ABCMeta):
|
|
491
486
|
"""Base class for profiles usable as a controller."""
|
|
492
487
|
|
|
493
488
|
@abc.abstractmethod
|
|
@@ -499,7 +494,7 @@ class ControllerHostProfile(PosixProfile[TControllerHostConfig], DebuggableProfi
|
|
|
499
494
|
"""Return the working directory for the host."""
|
|
500
495
|
|
|
501
496
|
|
|
502
|
-
class SshTargetHostProfile(HostProfile[THostConfig], metaclass=abc.ABCMeta):
|
|
497
|
+
class SshTargetHostProfile[THostConfig: HostConfig](HostProfile[THostConfig], metaclass=abc.ABCMeta):
|
|
503
498
|
"""Base class for profiles offering SSH connectivity."""
|
|
504
499
|
|
|
505
500
|
@abc.abstractmethod
|
|
@@ -507,7 +502,7 @@ class SshTargetHostProfile(HostProfile[THostConfig], metaclass=abc.ABCMeta):
|
|
|
507
502
|
"""Return SSH connection(s) for accessing the host as a target from the controller."""
|
|
508
503
|
|
|
509
504
|
|
|
510
|
-
class RemoteProfile(SshTargetHostProfile[TRemoteConfig], metaclass=abc.ABCMeta):
|
|
505
|
+
class RemoteProfile[TRemoteConfig: RemoteConfig](SshTargetHostProfile[TRemoteConfig], metaclass=abc.ABCMeta):
|
|
511
506
|
"""Base class for remote instance profiles."""
|
|
512
507
|
|
|
513
508
|
@property
|
|
@@ -12,12 +12,12 @@ from ..util import (
|
|
|
12
12
|
)
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def get_path_provider_classes(provider_type: t.Type[TPathProvider]) -> list[t.Type[TPathProvider]]:
|
|
15
|
+
def get_path_provider_classes[TPathProvider: PathProvider](provider_type: t.Type[TPathProvider]) -> list[t.Type[TPathProvider]]:
|
|
16
16
|
"""Return a list of path provider classes of the given type."""
|
|
17
17
|
return sorted(get_subclasses(provider_type), key=lambda subclass: (subclass.priority, subclass.__name__))
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def find_path_provider(
|
|
20
|
+
def find_path_provider[TPathProvider: PathProvider](
|
|
21
21
|
provider_type: t.Type[TPathProvider],
|
|
22
22
|
provider_classes: list[t.Type[TPathProvider]],
|
|
23
23
|
path: str,
|
|
@@ -71,6 +71,3 @@ class PathProvider(metaclass=abc.ABCMeta):
|
|
|
71
71
|
@abc.abstractmethod
|
|
72
72
|
def is_content_root(path: str) -> bool:
|
|
73
73
|
"""Return True if the given path is a content root for this provider."""
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
TPathProvider = t.TypeVar('TPathProvider', bound=PathProvider)
|
|
@@ -48,9 +48,6 @@ from .pypi_proxy import (
|
|
|
48
48
|
run_pypi_proxy,
|
|
49
49
|
)
|
|
50
50
|
|
|
51
|
-
THostProfile = t.TypeVar('THostProfile', bound=HostProfile)
|
|
52
|
-
TEnvironmentConfig = t.TypeVar('TEnvironmentConfig', bound=EnvironmentConfig)
|
|
53
|
-
|
|
54
51
|
|
|
55
52
|
class PrimeContainers(ApplicationError):
|
|
56
53
|
"""Exception raised to end execution early after priming containers."""
|
|
@@ -91,7 +88,7 @@ class HostState:
|
|
|
91
88
|
return list(itertools.chain.from_iterable([target.get_controller_target_connections() for
|
|
92
89
|
target in self.target_profiles if isinstance(target, SshTargetHostProfile)]))
|
|
93
90
|
|
|
94
|
-
def targets(self, profile_type: t.Type[THostProfile]) -> list[THostProfile]:
|
|
91
|
+
def targets[THostProfile: HostProfile](self, profile_type: t.Type[THostProfile]) -> list[THostProfile]:
|
|
95
92
|
"""The list of target(s), verified to be of the specified type."""
|
|
96
93
|
if not self.target_profiles:
|
|
97
94
|
raise Exception('No target profiles found.')
|
|
@@ -101,7 +98,7 @@ class HostState:
|
|
|
101
98
|
return t.cast(list[THostProfile], self.target_profiles)
|
|
102
99
|
|
|
103
100
|
|
|
104
|
-
def prepare_profiles(
|
|
101
|
+
def prepare_profiles[TEnvironmentConfig: EnvironmentConfig](
|
|
105
102
|
args: TEnvironmentConfig,
|
|
106
103
|
targets_use_pypi: bool = False,
|
|
107
104
|
skip_setup: bool = False,
|
|
@@ -70,7 +70,7 @@ def run_pypi_proxy(args: EnvironmentConfig, targets_use_pypi: bool) -> None:
|
|
|
70
70
|
display.warning('Unable to use the PyPI proxy because Docker is not available. Installation of packages using `pip` may fail.')
|
|
71
71
|
return
|
|
72
72
|
|
|
73
|
-
image = 'quay.io/ansible/pypi-test-container:3.
|
|
73
|
+
image = 'quay.io/ansible/pypi-test-container:3.5.0'
|
|
74
74
|
port = 3141
|
|
75
75
|
|
|
76
76
|
run_support_container(
|
|
@@ -433,7 +433,7 @@ def get_venv_packages(python: PythonConfig) -> dict[str, str]:
|
|
|
433
433
|
# See: https://github.com/ansible/base-test-container/blob/main/files/installer.py
|
|
434
434
|
|
|
435
435
|
default_packages = dict(
|
|
436
|
-
pip='
|
|
436
|
+
pip='25.2',
|
|
437
437
|
)
|
|
438
438
|
|
|
439
439
|
override_packages: dict[str, dict[str, str]] = {
|