ansible-core 2.15.4rc1__py3-none-any.whl → 2.16.0b2__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/cli/__init__.py +3 -3
- ansible/cli/adhoc.py +1 -1
- ansible/cli/arguments/option_helpers.py +15 -5
- ansible/cli/config.py +2 -2
- ansible/cli/console.py +21 -17
- ansible/cli/doc.py +8 -9
- ansible/cli/galaxy.py +60 -27
- ansible/cli/inventory.py +1 -1
- ansible/cli/playbook.py +1 -1
- ansible/cli/pull.py +2 -2
- ansible/cli/scripts/ansible_connection_cli_stub.py +1 -1
- ansible/cli/vault.py +11 -6
- ansible/collections/__init__.py +0 -29
- ansible/collections/list.py +23 -44
- ansible/config/ansible_builtin_runtime.yml +8 -4
- ansible/config/base.yml +34 -22
- ansible/config/manager.py +1 -1
- ansible/constants.py +3 -5
- ansible/errors/__init__.py +1 -1
- ansible/executor/interpreter_discovery.py +1 -1
- ansible/executor/module_common.py +39 -32
- ansible/executor/play_iterator.py +0 -15
- ansible/executor/playbook_executor.py +3 -3
- ansible/executor/powershell/module_manifest.py +1 -1
- ansible/executor/powershell/module_wrapper.ps1 +4 -1
- ansible/executor/process/worker.py +22 -7
- ansible/executor/task_executor.py +39 -40
- ansible/executor/task_queue_manager.py +8 -11
- ansible/galaxy/__init__.py +1 -1
- ansible/galaxy/api.py +8 -11
- ansible/galaxy/collection/__init__.py +17 -4
- ansible/galaxy/collection/concrete_artifact_manager.py +7 -2
- ansible/galaxy/collection/galaxy_api_proxy.py +1 -1
- ansible/galaxy/data/container/README.md +3 -5
- ansible/galaxy/dependency_resolution/__init__.py +1 -6
- ansible/galaxy/dependency_resolution/dataclasses.py +22 -1
- ansible/galaxy/dependency_resolution/providers.py +61 -69
- ansible/galaxy/role.py +31 -13
- ansible/galaxy/token.py +2 -2
- ansible/inventory/group.py +1 -1
- ansible/inventory/manager.py +1 -1
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/basic.py +11 -41
- ansible/module_utils/common/file.py +0 -100
- ansible/module_utils/common/json.py +1 -1
- ansible/module_utils/common/locale.py +1 -1
- ansible/module_utils/common/text/converters.py +2 -2
- ansible/module_utils/common/validation.py +1 -1
- ansible/module_utils/compat/_selectors2.py +4 -4
- ansible/module_utils/compat/datetime.py +40 -0
- ansible/module_utils/compat/selinux.py +1 -1
- ansible/module_utils/compat/typing.py +1 -1
- ansible/module_utils/connection.py +1 -1
- ansible/module_utils/facts/hardware/linux.py +2 -2
- ansible/module_utils/facts/hardware/openbsd.py +1 -1
- ansible/module_utils/facts/network/linux.py +3 -3
- ansible/module_utils/facts/other/facter.py +8 -15
- ansible/module_utils/facts/sysctl.py +1 -1
- ansible/module_utils/facts/system/date_time.py +2 -2
- ansible/module_utils/facts/system/distribution.py +1 -1
- ansible/module_utils/facts/system/local.py +6 -2
- ansible/module_utils/facts/system/pkg_mgr.py +6 -1
- ansible/module_utils/facts/system/service_mgr.py +4 -2
- ansible/module_utils/parsing/convert_bool.py +1 -1
- ansible/module_utils/service.py +9 -6
- ansible/module_utils/urls.py +40 -22
- ansible/modules/add_host.py +2 -2
- ansible/modules/apt.py +48 -31
- ansible/modules/apt_key.py +4 -4
- ansible/modules/apt_repository.py +5 -5
- ansible/modules/assemble.py +7 -7
- ansible/modules/assert.py +1 -1
- ansible/modules/async_status.py +11 -7
- ansible/modules/async_wrapper.py +1 -1
- ansible/modules/blockinfile.py +60 -17
- ansible/modules/command.py +37 -15
- ansible/modules/copy.py +35 -30
- ansible/modules/cron.py +14 -14
- ansible/modules/deb822_repository.py +4 -3
- ansible/modules/debconf.py +35 -14
- ansible/modules/debug.py +1 -1
- ansible/modules/dnf.py +29 -27
- ansible/modules/dnf5.py +22 -22
- ansible/modules/dpkg_selections.py +9 -2
- ansible/modules/expect.py +4 -4
- ansible/modules/fetch.py +7 -7
- ansible/modules/file.py +30 -30
- ansible/modules/find.py +82 -22
- ansible/modules/gather_facts.py +6 -2
- ansible/modules/get_url.py +29 -29
- ansible/modules/getent.py +4 -4
- ansible/modules/git.py +27 -27
- ansible/modules/group.py +5 -12
- ansible/modules/hostname.py +21 -2
- ansible/modules/include_role.py +5 -5
- ansible/modules/include_tasks.py +2 -2
- ansible/modules/include_vars.py +5 -5
- ansible/modules/iptables.py +70 -65
- ansible/modules/known_hosts.py +7 -7
- ansible/modules/lineinfile.py +33 -33
- ansible/modules/meta.py +13 -13
- ansible/modules/package.py +8 -8
- ansible/modules/package_facts.py +3 -3
- ansible/modules/pause.py +2 -2
- ansible/modules/ping.py +5 -5
- ansible/modules/pip.py +80 -46
- ansible/modules/reboot.py +8 -4
- ansible/modules/replace.py +20 -15
- ansible/modules/rpm_key.py +2 -2
- ansible/modules/script.py +16 -10
- ansible/modules/service.py +26 -98
- ansible/modules/service_facts.py +36 -12
- ansible/modules/set_fact.py +2 -2
- ansible/modules/set_stats.py +2 -2
- ansible/modules/setup.py +18 -18
- ansible/modules/shell.py +3 -3
- ansible/modules/stat.py +9 -30
- ansible/modules/subversion.py +9 -9
- ansible/modules/systemd.py +20 -19
- ansible/modules/systemd_service.py +20 -19
- ansible/modules/sysvinit.py +26 -21
- ansible/modules/tempfile.py +5 -4
- ansible/modules/template.py +60 -6
- ansible/modules/unarchive.py +21 -18
- ansible/modules/uri.py +39 -39
- ansible/modules/user.py +81 -53
- ansible/modules/wait_for.py +22 -21
- ansible/modules/wait_for_connection.py +4 -4
- ansible/modules/yum.py +38 -38
- ansible/modules/yum_repository.py +58 -80
- ansible/parsing/dataloader.py +27 -27
- ansible/parsing/mod_args.py +1 -1
- ansible/parsing/plugin_docs.py +3 -3
- ansible/parsing/splitter.py +14 -16
- ansible/parsing/utils/yaml.py +1 -1
- ansible/parsing/vault/__init__.py +8 -6
- ansible/parsing/yaml/constructor.py +1 -1
- ansible/parsing/yaml/objects.py +1 -1
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/base.py +2 -2
- ansible/playbook/block.py +0 -1
- ansible/playbook/conditional.py +40 -114
- ansible/playbook/helpers.py +5 -28
- ansible/playbook/included_file.py +8 -7
- ansible/playbook/play.py +1 -1
- ansible/playbook/play_context.py +2 -2
- ansible/playbook/playbook_include.py +2 -2
- ansible/playbook/role/__init__.py +1 -1
- ansible/playbook/role/include.py +1 -1
- ansible/playbook/role/metadata.py +1 -1
- ansible/playbook/role_include.py +1 -1
- ansible/playbook/task.py +2 -2
- ansible/playbook/task_include.py +1 -24
- ansible/plugins/__init__.py +13 -5
- ansible/plugins/action/__init__.py +17 -43
- ansible/plugins/action/add_host.py +2 -3
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +2 -1
- ansible/plugins/action/copy.py +2 -2
- ansible/plugins/action/debug.py +2 -1
- ansible/plugins/action/fail.py +1 -0
- ansible/plugins/action/fetch.py +3 -1
- ansible/plugins/action/gather_facts.py +37 -13
- ansible/plugins/action/group_by.py +1 -0
- ansible/plugins/action/include_vars.py +3 -2
- ansible/plugins/action/normal.py +3 -3
- ansible/plugins/action/pause.py +1 -1
- ansible/plugins/action/reboot.py +21 -16
- ansible/plugins/action/script.py +23 -8
- ansible/plugins/action/set_fact.py +1 -0
- ansible/plugins/action/set_stats.py +1 -0
- ansible/plugins/action/shell.py +6 -0
- ansible/plugins/action/template.py +1 -1
- ansible/plugins/action/unarchive.py +1 -1
- ansible/plugins/action/uri.py +1 -1
- ansible/plugins/action/validate_argument_spec.py +1 -0
- ansible/plugins/action/wait_for_connection.py +4 -4
- ansible/plugins/become/__init__.py +1 -1
- ansible/plugins/become/su.py +1 -1
- ansible/plugins/cache/__init__.py +1 -1
- ansible/plugins/callback/junit.py +1 -1
- ansible/plugins/callback/oneline.py +1 -1
- ansible/plugins/callback/tree.py +1 -1
- ansible/plugins/cliconf/__init__.py +2 -2
- ansible/plugins/connection/__init__.py +65 -37
- ansible/plugins/connection/local.py +9 -8
- ansible/plugins/connection/paramiko_ssh.py +34 -28
- ansible/plugins/connection/psrp.py +56 -43
- ansible/plugins/connection/ssh.py +67 -43
- ansible/plugins/connection/winrm.py +77 -30
- ansible/plugins/doc_fragments/constructed.py +4 -4
- ansible/plugins/doc_fragments/files.py +12 -12
- ansible/plugins/doc_fragments/inventory_cache.py +0 -6
- ansible/plugins/doc_fragments/result_format_callback.py +5 -5
- ansible/plugins/doc_fragments/shell_common.py +2 -2
- ansible/plugins/doc_fragments/shell_windows.py +1 -1
- ansible/plugins/doc_fragments/template_common.py +6 -6
- ansible/plugins/doc_fragments/url.py +10 -10
- ansible/plugins/doc_fragments/url_windows.py +15 -15
- ansible/plugins/doc_fragments/vars_plugin_staging.py +4 -4
- ansible/plugins/filter/b64decode.yml +1 -1
- ansible/plugins/filter/b64encode.yml +2 -2
- ansible/plugins/filter/bool.yml +5 -5
- ansible/plugins/filter/combine.yml +1 -1
- ansible/plugins/filter/commonpath.yml +2 -1
- ansible/plugins/filter/core.py +6 -8
- ansible/plugins/filter/dict2items.yml +11 -1
- ansible/plugins/filter/difference.yml +1 -0
- ansible/plugins/filter/encryption.py +1 -1
- ansible/plugins/filter/extract.yml +1 -1
- ansible/plugins/filter/flatten.yml +1 -1
- ansible/plugins/filter/from_yaml.yml +1 -1
- ansible/plugins/filter/from_yaml_all.yml +2 -2
- ansible/plugins/filter/hash.yml +1 -1
- ansible/plugins/filter/human_readable.yml +1 -1
- ansible/plugins/filter/human_to_bytes.yml +2 -2
- ansible/plugins/filter/intersect.yml +1 -0
- ansible/plugins/filter/mandatory.yml +7 -0
- ansible/plugins/filter/mathstuff.py +15 -17
- ansible/plugins/filter/normpath.yml +1 -1
- ansible/plugins/filter/path_join.yml +8 -1
- ansible/plugins/filter/realpath.yml +3 -2
- ansible/plugins/filter/regex_findall.yml +8 -2
- ansible/plugins/filter/regex_replace.yml +9 -3
- ansible/plugins/filter/regex_search.yml +8 -2
- ansible/plugins/filter/relpath.yml +2 -2
- ansible/plugins/filter/root.yml +1 -1
- ansible/plugins/filter/splitext.yml +1 -1
- ansible/plugins/filter/subelements.yml +2 -2
- ansible/plugins/filter/symmetric_difference.yml +1 -0
- ansible/plugins/filter/ternary.yml +5 -5
- ansible/plugins/filter/to_json.yml +7 -7
- ansible/plugins/filter/to_nice_json.yml +5 -5
- ansible/plugins/filter/to_yaml.yml +2 -2
- ansible/plugins/filter/type_debug.yml +1 -1
- ansible/plugins/filter/union.yml +1 -0
- ansible/plugins/filter/unvault.yml +2 -2
- ansible/plugins/filter/urldecode.yml +13 -32
- ansible/plugins/filter/urlsplit.py +1 -1
- ansible/plugins/filter/vault.yml +1 -1
- ansible/plugins/filter/zip.yml +1 -1
- ansible/plugins/filter/zip_longest.yml +1 -1
- ansible/plugins/inventory/__init__.py +1 -1
- ansible/plugins/inventory/advanced_host_list.py +1 -1
- ansible/plugins/inventory/constructed.py +2 -2
- ansible/plugins/inventory/host_list.py +1 -1
- ansible/plugins/inventory/ini.py +6 -3
- ansible/plugins/inventory/script.py +8 -2
- ansible/plugins/inventory/toml.py +1 -1
- ansible/plugins/inventory/yaml.py +1 -1
- ansible/plugins/list.py +21 -17
- ansible/plugins/loader.py +66 -88
- ansible/plugins/lookup/__init__.py +1 -1
- ansible/plugins/lookup/config.py +16 -6
- ansible/plugins/lookup/csvfile.py +7 -4
- ansible/plugins/lookup/env.py +1 -1
- ansible/plugins/lookup/file.py +5 -2
- ansible/plugins/lookup/fileglob.py +5 -2
- ansible/plugins/lookup/first_found.py +20 -14
- ansible/plugins/lookup/ini.py +6 -3
- ansible/plugins/lookup/lines.py +2 -1
- ansible/plugins/lookup/password.py +7 -7
- ansible/plugins/lookup/pipe.py +1 -0
- ansible/plugins/lookup/random_choice.py +2 -2
- ansible/plugins/lookup/sequence.py +1 -1
- ansible/plugins/lookup/subelements.py +2 -2
- ansible/plugins/lookup/template.py +4 -1
- ansible/plugins/lookup/unvault.py +4 -1
- ansible/plugins/lookup/url.py +6 -6
- ansible/plugins/lookup/varnames.py +1 -1
- ansible/plugins/netconf/__init__.py +3 -3
- ansible/plugins/shell/__init__.py +1 -1
- ansible/plugins/shell/cmd.py +7 -7
- ansible/plugins/shell/powershell.py +1 -1
- ansible/plugins/strategy/__init__.py +8 -10
- ansible/plugins/strategy/free.py +1 -1
- ansible/plugins/strategy/linear.py +3 -3
- ansible/plugins/terminal/__init__.py +2 -2
- ansible/plugins/test/abs.yml +1 -1
- ansible/plugins/test/all.yml +1 -1
- ansible/plugins/test/any.yml +1 -1
- ansible/plugins/test/change.yml +2 -2
- ansible/plugins/test/changed.yml +2 -2
- ansible/plugins/test/contains.yml +1 -1
- ansible/plugins/test/core.py +1 -1
- ansible/plugins/test/directory.yml +1 -1
- ansible/plugins/test/exists.yml +3 -2
- ansible/plugins/test/failed.yml +2 -2
- ansible/plugins/test/failure.yml +2 -2
- ansible/plugins/test/falsy.yml +2 -2
- ansible/plugins/test/file.yml +1 -1
- ansible/plugins/test/finished.yml +2 -2
- ansible/plugins/test/is_abs.yml +1 -1
- ansible/plugins/test/is_dir.yml +1 -1
- ansible/plugins/test/is_file.yml +1 -1
- ansible/plugins/test/is_link.yml +1 -1
- ansible/plugins/test/is_mount.yml +1 -1
- ansible/plugins/test/is_same_file.yml +1 -1
- ansible/plugins/test/isnan.yml +1 -1
- ansible/plugins/test/issubset.yml +1 -2
- ansible/plugins/test/issuperset.yml +1 -2
- ansible/plugins/test/link.yml +1 -1
- ansible/plugins/test/link_exists.yml +1 -1
- ansible/plugins/test/match.yml +2 -2
- ansible/plugins/test/mount.yml +1 -1
- ansible/plugins/test/nan.yml +1 -1
- ansible/plugins/test/reachable.yml +2 -2
- ansible/plugins/test/regex.yml +1 -1
- ansible/plugins/test/same_file.yml +1 -1
- ansible/plugins/test/search.yml +2 -2
- ansible/plugins/test/skip.yml +3 -3
- ansible/plugins/test/skipped.yml +3 -3
- ansible/plugins/test/started.yml +2 -2
- ansible/plugins/test/subset.yml +1 -2
- ansible/plugins/test/succeeded.yml +2 -2
- ansible/plugins/test/success.yml +2 -2
- ansible/plugins/test/successful.yml +2 -2
- ansible/plugins/test/superset.yml +1 -2
- ansible/plugins/test/truthy.yml +3 -3
- ansible/plugins/test/unreachable.yml +2 -2
- ansible/plugins/test/uri.yml +1 -1
- ansible/plugins/test/url.yml +1 -1
- ansible/plugins/test/urn.yml +1 -1
- ansible/plugins/test/vault_encrypted.yml +1 -1
- ansible/plugins/test/version.yml +7 -7
- ansible/plugins/test/version_compare.yml +7 -7
- ansible/plugins/vars/host_group_vars.py +1 -1
- ansible/release.py +2 -2
- ansible/template/__init__.py +24 -26
- ansible/template/native_helpers.py +1 -1
- ansible/template/vars.py +1 -1
- ansible/utils/_junit_xml.py +1 -1
- ansible/utils/cmd_functions.py +1 -1
- ansible/utils/collection_loader/_collection_finder.py +12 -1
- ansible/utils/display.py +113 -62
- ansible/utils/encrypt.py +11 -14
- ansible/utils/hashing.py +1 -1
- ansible/utils/jsonrpc.py +1 -1
- ansible/utils/path.py +1 -1
- ansible/utils/plugin_docs.py +1 -1
- ansible/utils/py3compat.py +1 -1
- ansible/utils/shlex.py +2 -10
- ansible/utils/ssh_functions.py +5 -4
- ansible/utils/unicode.py +1 -1
- ansible/utils/unsafe_proxy.py +1 -1
- ansible/utils/vars.py +4 -29
- ansible/vars/hostvars.py +1 -2
- ansible/vars/manager.py +13 -9
- ansible/vars/plugins.py +2 -2
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/COPYING +4 -5
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/METADATA +2 -4
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/RECORD +424 -425
- ansible_test/_data/completion/docker.txt +9 -9
- ansible_test/_data/completion/remote.txt +4 -7
- ansible_test/_data/completion/windows.txt +0 -2
- ansible_test/_data/requirements/ansible-test.txt +2 -1
- ansible_test/_data/requirements/ansible.txt +0 -3
- ansible_test/_data/requirements/constraints.txt +0 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -5
- ansible_test/_data/requirements/sanity.changelog.in +1 -2
- ansible_test/_data/requirements/sanity.changelog.txt +4 -6
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -4
- ansible_test/_data/requirements/sanity.import.txt +1 -3
- ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -3
- ansible_test/_data/requirements/sanity.mypy.txt +12 -12
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +6 -12
- ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -3
- ansible_test/_data/requirements/sanity.validate-modules.in +1 -1
- ansible_test/_data/requirements/sanity.validate-modules.txt +3 -5
- ansible_test/_data/requirements/sanity.yamllint.txt +3 -5
- ansible_test/_data/requirements/units.txt +0 -1
- ansible_test/_internal/ci/azp.py +4 -4
- ansible_test/_internal/cli/environments.py +0 -13
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +4 -4
- ansible_test/_internal/commands/coverage/combine.py +1 -1
- ansible_test/_internal/commands/integration/cloud/acme.py +6 -8
- ansible_test/_internal/commands/integration/cloud/cs.py +4 -9
- ansible_test/_internal/commands/integration/cloud/galaxy.py +103 -96
- ansible_test/_internal/commands/integration/cloud/httptester.py +0 -3
- ansible_test/_internal/commands/integration/cloud/nios.py +7 -9
- ansible_test/_internal/commands/integration/cloud/openshift.py +2 -7
- ansible_test/_internal/commands/integration/cloud/vcenter.py +11 -95
- ansible_test/_internal/commands/sanity/__init__.py +10 -0
- ansible_test/_internal/commands/sanity/import.py +8 -2
- ansible_test/_internal/commands/sanity/pylint.py +27 -1
- ansible_test/_internal/commands/units/__init__.py +2 -1
- ansible_test/_internal/config.py +0 -7
- ansible_test/_internal/containers.py +11 -56
- ansible_test/_internal/core_ci.py +0 -7
- ansible_test/_internal/coverage_util.py +8 -3
- ansible_test/_internal/delegation.py +0 -1
- ansible_test/_internal/diff.py +1 -1
- ansible_test/_internal/docker_util.py +9 -2
- ansible_test/_internal/host_profiles.py +6 -6
- ansible_test/_internal/http.py +1 -1
- ansible_test/_internal/junit_xml.py +1 -1
- ansible_test/_internal/pypi_proxy.py +1 -1
- ansible_test/_internal/python_requirements.py +3 -8
- ansible_test/_internal/util.py +1 -6
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.json +4 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.json +4 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.json +4 -0
- ansible_test/_util/controller/sanity/mypy/ansible-core.ini +3 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +2 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +0 -1
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +172 -10
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +13 -2
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +7 -1
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +6 -6
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +1 -1
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -1
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +3 -3
- ansible_test/_util/controller/tools/collection_detail.py +2 -2
- ansible_test/_util/target/common/constants.py +2 -2
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +103 -0
- ansible_test/_util/target/sanity/import/importer.py +0 -8
- ansible_test/_util/target/setup/bootstrap.sh +36 -16
- ansible_test/_util/target/setup/quiet_pip.py +0 -4
- ansible/modules/_include.py +0 -80
- ansible_test/_internal/commands/integration/cloud/foreman.py +0 -102
- ansible_test/_util/target/setup/ConfigureRemotingForAnsible.ps1 +0 -435
- {ansible_core-2.15.4rc1.data → ansible_core-2.16.0b2.data}/scripts/ansible-test +0 -0
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/WHEEL +0 -0
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/top_level.txt +0 -0
|
@@ -28,7 +28,7 @@ from multiprocessing.queues import Queue
|
|
|
28
28
|
|
|
29
29
|
from ansible.errors import AnsibleConnectionFailure, AnsibleError
|
|
30
30
|
from ansible.executor.task_executor import TaskExecutor
|
|
31
|
-
from ansible.module_utils.
|
|
31
|
+
from ansible.module_utils.common.text.converters import to_text
|
|
32
32
|
from ansible.utils.display import Display
|
|
33
33
|
from ansible.utils.multiprocessing import context as multiprocessing_context
|
|
34
34
|
|
|
@@ -194,12 +194,27 @@ class WorkerProcess(multiprocessing_context.Process): # type: ignore[name-defin
|
|
|
194
194
|
|
|
195
195
|
# put the result on the result queue
|
|
196
196
|
display.debug("sending task result for task %s" % self._task._uuid)
|
|
197
|
-
|
|
198
|
-
self.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
197
|
+
try:
|
|
198
|
+
self._final_q.send_task_result(
|
|
199
|
+
self._host.name,
|
|
200
|
+
self._task._uuid,
|
|
201
|
+
executor_result,
|
|
202
|
+
task_fields=self._task.dump_attrs(),
|
|
203
|
+
)
|
|
204
|
+
except Exception as e:
|
|
205
|
+
display.debug(f'failed to send task result ({e}), sending surrogate result')
|
|
206
|
+
self._final_q.send_task_result(
|
|
207
|
+
self._host.name,
|
|
208
|
+
self._task._uuid,
|
|
209
|
+
# Overriding the task result, to represent the failure
|
|
210
|
+
{
|
|
211
|
+
'failed': True,
|
|
212
|
+
'msg': f'{e}',
|
|
213
|
+
'exception': traceback.format_exc(),
|
|
214
|
+
},
|
|
215
|
+
# The failure pickling may have been caused by the task attrs, omit for safety
|
|
216
|
+
{},
|
|
217
|
+
)
|
|
203
218
|
display.debug("done sending task result for task %s" % self._task._uuid)
|
|
204
219
|
|
|
205
220
|
except AnsibleConnectionFailure:
|
|
@@ -20,7 +20,7 @@ from ansible.executor.task_result import TaskResult
|
|
|
20
20
|
from ansible.executor.module_common import get_action_args_with_defaults
|
|
21
21
|
from ansible.module_utils.parsing.convert_bool import boolean
|
|
22
22
|
from ansible.module_utils.six import binary_type
|
|
23
|
-
from ansible.module_utils.
|
|
23
|
+
from ansible.module_utils.common.text.converters import to_text, to_native
|
|
24
24
|
from ansible.module_utils.connection import write_to_file_descriptor
|
|
25
25
|
from ansible.playbook.conditional import Conditional
|
|
26
26
|
from ansible.playbook.task import Task
|
|
@@ -224,14 +224,11 @@ class TaskExecutor:
|
|
|
224
224
|
items = None
|
|
225
225
|
if self._task.loop_with:
|
|
226
226
|
if self._task.loop_with in self._shared_loader_obj.lookup_loader:
|
|
227
|
-
fail = True
|
|
228
|
-
if self._task.loop_with == 'first_found':
|
|
229
|
-
# first_found loops are special. If the item is undefined then we want to fall through to the next value rather than failing.
|
|
230
|
-
fail = False
|
|
231
227
|
|
|
228
|
+
# TODO: hardcoded so it fails for non first_found lookups, but thhis shoudl be generalized for those that don't do their own templating
|
|
229
|
+
# lookup prop/attribute?
|
|
230
|
+
fail = bool(self._task.loop_with != 'first_found')
|
|
232
231
|
loop_terms = listify_lookup_plugin_terms(terms=self._task.loop, templar=templar, fail_on_undefined=fail, convert_bare=False)
|
|
233
|
-
if not fail:
|
|
234
|
-
loop_terms = [t for t in loop_terms if not templar.is_template(t)]
|
|
235
232
|
|
|
236
233
|
# get lookup
|
|
237
234
|
mylookup = self._shared_loader_obj.lookup_loader.get(self._task.loop_with, loader=self._loader, templar=templar)
|
|
@@ -514,7 +511,7 @@ class TaskExecutor:
|
|
|
514
511
|
|
|
515
512
|
# if this task is a TaskInclude, we just return now with a success code so the
|
|
516
513
|
# main thread can expand the task list for the given host
|
|
517
|
-
if self._task.action in C.
|
|
514
|
+
if self._task.action in C._ACTION_INCLUDE_TASKS:
|
|
518
515
|
include_args = self._task.args.copy()
|
|
519
516
|
include_file = include_args.pop('_raw_params', None)
|
|
520
517
|
if not include_file:
|
|
@@ -598,24 +595,14 @@ class TaskExecutor:
|
|
|
598
595
|
# feed back into pc to ensure plugins not using get_option can get correct value
|
|
599
596
|
self._connection._play_context = self._play_context.set_task_and_variable_override(task=self._task, variables=vars_copy, templar=templar)
|
|
600
597
|
|
|
601
|
-
#
|
|
602
|
-
if any(((self._connection.supports_persistence and C.USE_PERSISTENT_CONNECTIONS), self._connection.force_persistence)):
|
|
603
|
-
self._play_context.timeout = self._connection.get_option('persistent_command_timeout')
|
|
604
|
-
display.vvvv('attempting to start connection', host=self._play_context.remote_addr)
|
|
605
|
-
display.vvvv('using connection plugin %s' % self._connection.transport, host=self._play_context.remote_addr)
|
|
606
|
-
|
|
607
|
-
options = self._connection.get_options()
|
|
608
|
-
socket_path = start_connection(self._play_context, options, self._task._uuid)
|
|
609
|
-
display.vvvv('local domain socket path is %s' % socket_path, host=self._play_context.remote_addr)
|
|
610
|
-
setattr(self._connection, '_socket_path', socket_path)
|
|
611
|
-
|
|
598
|
+
# TODO: eventually remove this block as this should be a 'consequence' of 'forced_local' modules, right now rely on remote_is_local connection
|
|
612
599
|
# special handling for python interpreter for network_os, default to ansible python unless overridden
|
|
613
600
|
if 'ansible_python_interpreter' not in cvars and 'ansible_network_os' in cvars and getattr(self._connection, '_remote_is_local', False):
|
|
614
601
|
# this also avoids 'python discovery'
|
|
615
602
|
cvars['ansible_python_interpreter'] = sys.executable
|
|
616
603
|
|
|
617
604
|
# get handler
|
|
618
|
-
self._handler, module_context = self._get_action_handler_with_module_context(
|
|
605
|
+
self._handler, module_context = self._get_action_handler_with_module_context(templar=templar)
|
|
619
606
|
|
|
620
607
|
if module_context is not None:
|
|
621
608
|
module_defaults_fqcn = module_context.resolved_fqcn
|
|
@@ -633,17 +620,11 @@ class TaskExecutor:
|
|
|
633
620
|
if omit_token is not None:
|
|
634
621
|
self._task.args = remove_omit(self._task.args, omit_token)
|
|
635
622
|
|
|
636
|
-
|
|
637
|
-
if self._task.
|
|
638
|
-
retries
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
elif retries <= 0:
|
|
642
|
-
retries = 1
|
|
643
|
-
else:
|
|
644
|
-
retries += 1
|
|
645
|
-
else:
|
|
646
|
-
retries = 1
|
|
623
|
+
retries = 1 # includes the default actual run + retries set by user/default
|
|
624
|
+
if self._task.retries is not None:
|
|
625
|
+
retries += max(0, self._task.retries)
|
|
626
|
+
elif self._task.until:
|
|
627
|
+
retries += 3 # the default is not set in FA because we need to differentiate "unset" value
|
|
647
628
|
|
|
648
629
|
delay = self._task.delay
|
|
649
630
|
if delay < 0:
|
|
@@ -749,7 +730,7 @@ class TaskExecutor:
|
|
|
749
730
|
result['failed'] = False
|
|
750
731
|
|
|
751
732
|
# Make attempts and retries available early to allow their use in changed/failed_when
|
|
752
|
-
if
|
|
733
|
+
if retries > 1:
|
|
753
734
|
result['attempts'] = attempt
|
|
754
735
|
|
|
755
736
|
# set the changed property if it was missing.
|
|
@@ -781,7 +762,7 @@ class TaskExecutor:
|
|
|
781
762
|
|
|
782
763
|
if retries > 1:
|
|
783
764
|
cond = Conditional(loader=self._loader)
|
|
784
|
-
cond.when = self._task.until
|
|
765
|
+
cond.when = self._task.until or [not result['failed']]
|
|
785
766
|
if cond.evaluate_conditional(templar, vars_copy):
|
|
786
767
|
break
|
|
787
768
|
else:
|
|
@@ -800,7 +781,7 @@ class TaskExecutor:
|
|
|
800
781
|
)
|
|
801
782
|
)
|
|
802
783
|
time.sleep(delay)
|
|
803
|
-
self._handler = self._get_action_handler(
|
|
784
|
+
self._handler = self._get_action_handler(templar=templar)
|
|
804
785
|
else:
|
|
805
786
|
if retries > 1:
|
|
806
787
|
# we ran out of attempts, so mark the result as failed
|
|
@@ -1118,13 +1099,13 @@ class TaskExecutor:
|
|
|
1118
1099
|
|
|
1119
1100
|
return varnames
|
|
1120
1101
|
|
|
1121
|
-
def _get_action_handler(self,
|
|
1102
|
+
def _get_action_handler(self, templar):
|
|
1122
1103
|
'''
|
|
1123
1104
|
Returns the correct action plugin to handle the requestion task action
|
|
1124
1105
|
'''
|
|
1125
|
-
return self._get_action_handler_with_module_context(
|
|
1106
|
+
return self._get_action_handler_with_module_context(templar)[0]
|
|
1126
1107
|
|
|
1127
|
-
def _get_action_handler_with_module_context(self,
|
|
1108
|
+
def _get_action_handler_with_module_context(self, templar):
|
|
1128
1109
|
'''
|
|
1129
1110
|
Returns the correct action plugin to handle the requestion task action and the module context
|
|
1130
1111
|
'''
|
|
@@ -1161,10 +1142,29 @@ class TaskExecutor:
|
|
|
1161
1142
|
handler_name = 'ansible.legacy.normal'
|
|
1162
1143
|
collections = None # until then, we don't want the task's collection list to be consulted; use the builtin
|
|
1163
1144
|
|
|
1145
|
+
# networking/psersistent connections handling
|
|
1146
|
+
if any(((self._connection.supports_persistence and C.USE_PERSISTENT_CONNECTIONS), self._connection.force_persistence)):
|
|
1147
|
+
|
|
1148
|
+
# check handler in case we dont need to do all the work to setup persistent connection
|
|
1149
|
+
handler_class = self._shared_loader_obj.action_loader.get(handler_name, class_only=True)
|
|
1150
|
+
if getattr(handler_class, '_requires_connection', True):
|
|
1151
|
+
# for persistent connections, initialize socket path and start connection manager
|
|
1152
|
+
self._play_context.timeout = self._connection.get_option('persistent_command_timeout')
|
|
1153
|
+
display.vvvv('attempting to start connection', host=self._play_context.remote_addr)
|
|
1154
|
+
display.vvvv('using connection plugin %s' % self._connection.transport, host=self._play_context.remote_addr)
|
|
1155
|
+
|
|
1156
|
+
options = self._connection.get_options()
|
|
1157
|
+
socket_path = start_connection(self._play_context, options, self._task._uuid)
|
|
1158
|
+
display.vvvv('local domain socket path is %s' % socket_path, host=self._play_context.remote_addr)
|
|
1159
|
+
setattr(self._connection, '_socket_path', socket_path)
|
|
1160
|
+
else:
|
|
1161
|
+
# TODO: set self._connection to dummy/noop connection, using local for now
|
|
1162
|
+
self._connection = self._get_connection({}, templar, 'local')
|
|
1163
|
+
|
|
1164
1164
|
handler = self._shared_loader_obj.action_loader.get(
|
|
1165
1165
|
handler_name,
|
|
1166
1166
|
task=self._task,
|
|
1167
|
-
connection=
|
|
1167
|
+
connection=self._connection,
|
|
1168
1168
|
play_context=self._play_context,
|
|
1169
1169
|
loader=self._loader,
|
|
1170
1170
|
templar=templar,
|
|
@@ -1240,8 +1240,7 @@ def start_connection(play_context, options, task_uuid):
|
|
|
1240
1240
|
else:
|
|
1241
1241
|
try:
|
|
1242
1242
|
result = json.loads(to_text(stderr, errors='surrogate_then_replace'))
|
|
1243
|
-
except
|
|
1244
|
-
# JSONDecodeError only available on Python 3.5+
|
|
1243
|
+
except json.decoder.JSONDecodeError:
|
|
1245
1244
|
result = {'error': to_text(stderr, errors='surrogate_then_replace')}
|
|
1246
1245
|
|
|
1247
1246
|
if 'messages' in result:
|
|
@@ -34,7 +34,7 @@ from ansible.executor.play_iterator import PlayIterator
|
|
|
34
34
|
from ansible.executor.stats import AggregateStats
|
|
35
35
|
from ansible.executor.task_result import TaskResult
|
|
36
36
|
from ansible.module_utils.six import string_types
|
|
37
|
-
from ansible.module_utils.
|
|
37
|
+
from ansible.module_utils.common.text.converters import to_text, to_native
|
|
38
38
|
from ansible.playbook.play_context import PlayContext
|
|
39
39
|
from ansible.playbook.task import Task
|
|
40
40
|
from ansible.plugins.loader import callback_loader, strategy_loader, module_loader
|
|
@@ -61,7 +61,8 @@ class CallbackSend:
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
class DisplaySend:
|
|
64
|
-
def __init__(self, *args, **kwargs):
|
|
64
|
+
def __init__(self, method, *args, **kwargs):
|
|
65
|
+
self.method = method
|
|
65
66
|
self.args = args
|
|
66
67
|
self.kwargs = kwargs
|
|
67
68
|
|
|
@@ -76,15 +77,14 @@ class PromptSend:
|
|
|
76
77
|
complete_input: t.Iterable[bytes] = None
|
|
77
78
|
|
|
78
79
|
|
|
79
|
-
class FinalQueue(multiprocessing.queues.
|
|
80
|
+
class FinalQueue(multiprocessing.queues.SimpleQueue):
|
|
80
81
|
def __init__(self, *args, **kwargs):
|
|
81
82
|
kwargs['ctx'] = multiprocessing_context
|
|
82
|
-
super(
|
|
83
|
+
super().__init__(*args, **kwargs)
|
|
83
84
|
|
|
84
85
|
def send_callback(self, method_name, *args, **kwargs):
|
|
85
86
|
self.put(
|
|
86
87
|
CallbackSend(method_name, *args, **kwargs),
|
|
87
|
-
block=False
|
|
88
88
|
)
|
|
89
89
|
|
|
90
90
|
def send_task_result(self, *args, **kwargs):
|
|
@@ -94,19 +94,16 @@ class FinalQueue(multiprocessing.queues.Queue):
|
|
|
94
94
|
tr = TaskResult(*args, **kwargs)
|
|
95
95
|
self.put(
|
|
96
96
|
tr,
|
|
97
|
-
block=False
|
|
98
97
|
)
|
|
99
98
|
|
|
100
|
-
def send_display(self, *args, **kwargs):
|
|
99
|
+
def send_display(self, method, *args, **kwargs):
|
|
101
100
|
self.put(
|
|
102
|
-
DisplaySend(*args, **kwargs),
|
|
103
|
-
block=False
|
|
101
|
+
DisplaySend(method, *args, **kwargs),
|
|
104
102
|
)
|
|
105
103
|
|
|
106
104
|
def send_prompt(self, **kwargs):
|
|
107
105
|
self.put(
|
|
108
106
|
PromptSend(**kwargs),
|
|
109
|
-
block=False
|
|
110
107
|
)
|
|
111
108
|
|
|
112
109
|
|
|
@@ -235,7 +232,7 @@ class TaskQueueManager:
|
|
|
235
232
|
callback_name = cnames[0]
|
|
236
233
|
else:
|
|
237
234
|
# fallback to 'old loader name'
|
|
238
|
-
(callback_name,
|
|
235
|
+
(callback_name, ext) = os.path.splitext(os.path.basename(callback_plugin._original_path))
|
|
239
236
|
|
|
240
237
|
display.vvvvv("Attempting to use '%s' callback." % (callback_name))
|
|
241
238
|
if callback_type == 'stdout':
|
ansible/galaxy/__init__.py
CHANGED
|
@@ -27,7 +27,7 @@ import os
|
|
|
27
27
|
|
|
28
28
|
import ansible.constants as C
|
|
29
29
|
from ansible import context
|
|
30
|
-
from ansible.module_utils.
|
|
30
|
+
from ansible.module_utils.common.text.converters import to_bytes
|
|
31
31
|
from ansible.module_utils.common.yaml import yaml_load
|
|
32
32
|
|
|
33
33
|
# default_readme_template
|
ansible/galaxy/api.py
CHANGED
|
@@ -11,7 +11,6 @@ import functools
|
|
|
11
11
|
import hashlib
|
|
12
12
|
import json
|
|
13
13
|
import os
|
|
14
|
-
import socket
|
|
15
14
|
import stat
|
|
16
15
|
import tarfile
|
|
17
16
|
import time
|
|
@@ -28,7 +27,7 @@ from ansible.galaxy.user_agent import user_agent
|
|
|
28
27
|
from ansible.module_utils.api import retry_with_delays_and_condition
|
|
29
28
|
from ansible.module_utils.api import generate_jittered_backoff
|
|
30
29
|
from ansible.module_utils.six import string_types
|
|
31
|
-
from ansible.module_utils.
|
|
30
|
+
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
|
32
31
|
from ansible.module_utils.urls import open_url, prepare_multipart
|
|
33
32
|
from ansible.utils.display import Display
|
|
34
33
|
from ansible.utils.hashing import secure_hash_s
|
|
@@ -66,7 +65,7 @@ def should_retry_error(exception):
|
|
|
66
65
|
|
|
67
66
|
# Handle common URL related errors such as TimeoutError, and BadStatusLine
|
|
68
67
|
# Note: socket.timeout is only required for Py3.9
|
|
69
|
-
if isinstance(orig_exc, (TimeoutError, BadStatusLine, IncompleteRead
|
|
68
|
+
if isinstance(orig_exc, (TimeoutError, BadStatusLine, IncompleteRead)):
|
|
70
69
|
return True
|
|
71
70
|
|
|
72
71
|
return False
|
|
@@ -360,7 +359,8 @@ class GalaxyAPI:
|
|
|
360
359
|
valid = False
|
|
361
360
|
if cache_key in server_cache:
|
|
362
361
|
expires = datetime.datetime.strptime(server_cache[cache_key]['expires'], iso_datetime_format)
|
|
363
|
-
|
|
362
|
+
expires = expires.replace(tzinfo=datetime.timezone.utc)
|
|
363
|
+
valid = datetime.datetime.now(datetime.timezone.utc) < expires
|
|
364
364
|
|
|
365
365
|
is_paginated_url = 'page' in query or 'offset' in query
|
|
366
366
|
if valid and not is_paginated_url:
|
|
@@ -385,7 +385,7 @@ class GalaxyAPI:
|
|
|
385
385
|
|
|
386
386
|
elif not is_paginated_url:
|
|
387
387
|
# The cache entry had expired or does not exist, start a new blank entry to be filled later.
|
|
388
|
-
expires = datetime.datetime.
|
|
388
|
+
expires = datetime.datetime.now(datetime.timezone.utc)
|
|
389
389
|
expires += datetime.timedelta(days=1)
|
|
390
390
|
server_cache[cache_key] = {
|
|
391
391
|
'expires': expires.strftime(iso_datetime_format),
|
|
@@ -923,10 +923,7 @@ class GalaxyAPI:
|
|
|
923
923
|
data = self._call_galaxy(n_collection_url, error_context_msg=error_context_msg, cache=True)
|
|
924
924
|
self._set_cache()
|
|
925
925
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
except KeyError:
|
|
926
|
+
signatures = [signature_info["signature"] for signature_info in data.get("signatures") or []]
|
|
927
|
+
if not signatures:
|
|
929
928
|
display.vvvv(f"Server {self.api_server} has not signed {namespace}.{name}:{version}")
|
|
930
|
-
|
|
931
|
-
else:
|
|
932
|
-
return [signature_info["signature"] for signature_info in signatures]
|
|
929
|
+
return signatures
|
|
@@ -124,7 +124,7 @@ from ansible.galaxy.dependency_resolution.dataclasses import (
|
|
|
124
124
|
)
|
|
125
125
|
from ansible.galaxy.dependency_resolution.versioning import meets_requirements
|
|
126
126
|
from ansible.plugins.loader import get_all_plugin_loaders
|
|
127
|
-
from ansible.module_utils.
|
|
127
|
+
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
|
128
128
|
from ansible.module_utils.common.collections import is_sequence
|
|
129
129
|
from ansible.module_utils.common.yaml import yaml_dump
|
|
130
130
|
from ansible.utils.collection_loader import AnsibleCollectionRef
|
|
@@ -1325,6 +1325,8 @@ def _build_collection_tar(
|
|
|
1325
1325
|
|
|
1326
1326
|
if os.path.islink(b_src_path):
|
|
1327
1327
|
b_link_target = os.path.realpath(b_src_path)
|
|
1328
|
+
if not os.path.exists(b_link_target):
|
|
1329
|
+
raise AnsibleError(f"Failed to find the target path '{to_native(b_link_target)}' for the symlink '{to_native(b_src_path)}'.")
|
|
1328
1330
|
if _is_child_path(b_link_target, b_collection_path):
|
|
1329
1331
|
b_rel_path = os.path.relpath(b_link_target, start=os.path.dirname(b_src_path))
|
|
1330
1332
|
|
|
@@ -1420,6 +1422,10 @@ def find_existing_collections(path_filter, artifacts_manager, namespace_filter=N
|
|
|
1420
1422
|
|
|
1421
1423
|
if path_filter and not is_sequence(path_filter):
|
|
1422
1424
|
path_filter = [path_filter]
|
|
1425
|
+
if namespace_filter and not is_sequence(namespace_filter):
|
|
1426
|
+
namespace_filter = [namespace_filter]
|
|
1427
|
+
if collection_filter and not is_sequence(collection_filter):
|
|
1428
|
+
collection_filter = [collection_filter]
|
|
1423
1429
|
|
|
1424
1430
|
paths = set()
|
|
1425
1431
|
for path in files('ansible_collections').glob('*/*/'):
|
|
@@ -1441,9 +1447,9 @@ def find_existing_collections(path_filter, artifacts_manager, namespace_filter=N
|
|
|
1441
1447
|
for path in paths:
|
|
1442
1448
|
namespace = path.parent.name
|
|
1443
1449
|
name = path.name
|
|
1444
|
-
if namespace_filter and namespace
|
|
1450
|
+
if namespace_filter and namespace not in namespace_filter:
|
|
1445
1451
|
continue
|
|
1446
|
-
if collection_filter and name
|
|
1452
|
+
if collection_filter and name not in collection_filter:
|
|
1447
1453
|
continue
|
|
1448
1454
|
|
|
1449
1455
|
if dedupe:
|
|
@@ -1811,10 +1817,15 @@ def _resolve_depenency_map(
|
|
|
1811
1817
|
elif not req.specifier.contains(RESOLVELIB_VERSION.vstring):
|
|
1812
1818
|
raise AnsibleError(f"ansible-galaxy requires {req.name}{req.specifier}")
|
|
1813
1819
|
|
|
1820
|
+
pre_release_hint = '' if allow_pre_release else (
|
|
1821
|
+
'Hint: Pre-releases hosted on Galaxy or Automation Hub are not '
|
|
1822
|
+
'installed by default unless a specific version is requested. '
|
|
1823
|
+
'To enable pre-releases globally, use --pre.'
|
|
1824
|
+
)
|
|
1825
|
+
|
|
1814
1826
|
collection_dep_resolver = build_collection_dependency_resolver(
|
|
1815
1827
|
galaxy_apis=galaxy_apis,
|
|
1816
1828
|
concrete_artifacts_manager=concrete_artifacts_manager,
|
|
1817
|
-
user_requirements=requested_requirements,
|
|
1818
1829
|
preferred_candidates=preferred_candidates,
|
|
1819
1830
|
with_deps=not no_deps,
|
|
1820
1831
|
with_pre_releases=allow_pre_release,
|
|
@@ -1846,6 +1857,7 @@ def _resolve_depenency_map(
|
|
|
1846
1857
|
),
|
|
1847
1858
|
conflict_causes,
|
|
1848
1859
|
))
|
|
1860
|
+
error_msg_lines.append(pre_release_hint)
|
|
1849
1861
|
raise AnsibleError('\n'.join(error_msg_lines)) from dep_exc
|
|
1850
1862
|
except CollectionDependencyInconsistentCandidate as dep_exc:
|
|
1851
1863
|
parents = [
|
|
@@ -1872,6 +1884,7 @@ def _resolve_depenency_map(
|
|
|
1872
1884
|
error_msg_lines.append(
|
|
1873
1885
|
'* {req.fqcn!s}:{req.ver!s}'.format(req=req)
|
|
1874
1886
|
)
|
|
1887
|
+
error_msg_lines.append(pre_release_hint)
|
|
1875
1888
|
|
|
1876
1889
|
raise AnsibleError('\n'.join(error_msg_lines)) from dep_exc
|
|
1877
1890
|
except ValueError as exc:
|
|
@@ -30,7 +30,7 @@ from ansible.galaxy import get_collections_galaxy_meta_info
|
|
|
30
30
|
from ansible.galaxy.api import should_retry_error
|
|
31
31
|
from ansible.galaxy.dependency_resolution.dataclasses import _GALAXY_YAML
|
|
32
32
|
from ansible.galaxy.user_agent import user_agent
|
|
33
|
-
from ansible.module_utils.
|
|
33
|
+
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
|
34
34
|
from ansible.module_utils.api import retry_with_delays_and_condition
|
|
35
35
|
from ansible.module_utils.api import generate_jittered_backoff
|
|
36
36
|
from ansible.module_utils.common.process import get_bin_path
|
|
@@ -140,7 +140,7 @@ class ConcreteArtifactsManager:
|
|
|
140
140
|
url, sha256_hash, token = self._galaxy_collection_cache[collection]
|
|
141
141
|
except KeyError as key_err:
|
|
142
142
|
raise RuntimeError(
|
|
143
|
-
'
|
|
143
|
+
'There is no known source for {coll!s}'.
|
|
144
144
|
format(coll=collection),
|
|
145
145
|
) from key_err
|
|
146
146
|
|
|
@@ -702,6 +702,11 @@ def _get_meta_from_installed_dir(
|
|
|
702
702
|
def _get_meta_from_tar(
|
|
703
703
|
b_path, # type: bytes
|
|
704
704
|
): # type: (...) -> dict[str, t.Union[str, list[str], dict[str, str], None, t.Type[Sentinel]]]
|
|
705
|
+
if not os.path.exists(b_path):
|
|
706
|
+
raise AnsibleError(
|
|
707
|
+
f"Unable to find collection artifact file at '{to_native(b_path)}'."
|
|
708
|
+
)
|
|
709
|
+
|
|
705
710
|
if not tarfile.is_tarfile(b_path):
|
|
706
711
|
raise AnsibleError(
|
|
707
712
|
"Collection artifact at '{path!s}' is not a valid tar file.".
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Adds a <SERVICE_NAME> service to your [Ansible Container](https://github.com/ansible/ansible-container) project. Run the following commands
|
|
4
4
|
to install the service:
|
|
5
5
|
|
|
6
|
-
```
|
|
6
|
+
```shell
|
|
7
7
|
# Set the working directory to your Ansible Container project root
|
|
8
8
|
$ cd myproject
|
|
9
9
|
|
|
@@ -15,7 +15,8 @@ $ ansible-container install <USERNAME.ROLE_NAME>
|
|
|
15
15
|
|
|
16
16
|
- [Ansible Container](https://github.com/ansible/ansible-container)
|
|
17
17
|
- An existing Ansible Container project. To create a project, simply run the following:
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
```shell
|
|
19
20
|
# Create an empty project directory
|
|
20
21
|
$ mkdir myproject
|
|
21
22
|
|
|
@@ -28,7 +29,6 @@ $ ansible-container install <USERNAME.ROLE_NAME>
|
|
|
28
29
|
|
|
29
30
|
- Continue listing any prerequisites here...
|
|
30
31
|
|
|
31
|
-
|
|
32
32
|
## Role Variables
|
|
33
33
|
|
|
34
34
|
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set
|
|
@@ -45,5 +45,3 @@ BSD
|
|
|
45
45
|
## Author Information
|
|
46
46
|
|
|
47
47
|
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
|
|
48
|
-
|
|
49
|
-
|
|
@@ -13,10 +13,7 @@ if t.TYPE_CHECKING:
|
|
|
13
13
|
from ansible.galaxy.collection.concrete_artifact_manager import (
|
|
14
14
|
ConcreteArtifactsManager,
|
|
15
15
|
)
|
|
16
|
-
from ansible.galaxy.dependency_resolution.dataclasses import
|
|
17
|
-
Candidate,
|
|
18
|
-
Requirement,
|
|
19
|
-
)
|
|
16
|
+
from ansible.galaxy.dependency_resolution.dataclasses import Candidate
|
|
20
17
|
|
|
21
18
|
from ansible.galaxy.collection.galaxy_api_proxy import MultiGalaxyAPIProxy
|
|
22
19
|
from ansible.galaxy.dependency_resolution.providers import CollectionDependencyProvider
|
|
@@ -27,7 +24,6 @@ from ansible.galaxy.dependency_resolution.resolvers import CollectionDependencyR
|
|
|
27
24
|
def build_collection_dependency_resolver(
|
|
28
25
|
galaxy_apis, # type: t.Iterable[GalaxyAPI]
|
|
29
26
|
concrete_artifacts_manager, # type: ConcreteArtifactsManager
|
|
30
|
-
user_requirements, # type: t.Iterable[Requirement]
|
|
31
27
|
preferred_candidates=None, # type: t.Iterable[Candidate]
|
|
32
28
|
with_deps=True, # type: bool
|
|
33
29
|
with_pre_releases=False, # type: bool
|
|
@@ -44,7 +40,6 @@ def build_collection_dependency_resolver(
|
|
|
44
40
|
CollectionDependencyProvider(
|
|
45
41
|
apis=MultiGalaxyAPIProxy(galaxy_apis, concrete_artifacts_manager, offline=offline),
|
|
46
42
|
concrete_artifacts_manager=concrete_artifacts_manager,
|
|
47
|
-
user_requirements=user_requirements,
|
|
48
43
|
preferred_candidates=preferred_candidates,
|
|
49
44
|
with_deps=with_deps,
|
|
50
45
|
with_pre_releases=with_pre_releases,
|
|
@@ -30,7 +30,7 @@ if t.TYPE_CHECKING:
|
|
|
30
30
|
from ansible.errors import AnsibleError, AnsibleAssertionError
|
|
31
31
|
from ansible.galaxy.api import GalaxyAPI
|
|
32
32
|
from ansible.galaxy.collection import HAS_PACKAGING, PkgReq
|
|
33
|
-
from ansible.module_utils.
|
|
33
|
+
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
|
34
34
|
from ansible.module_utils.common.arg_spec import ArgumentSpecValidator
|
|
35
35
|
from ansible.utils.collection_loader import AnsibleCollectionRef
|
|
36
36
|
from ansible.utils.display import Display
|
|
@@ -564,6 +564,27 @@ class _ComputedReqKindsMixin:
|
|
|
564
564
|
def is_online_index_pointer(self):
|
|
565
565
|
return not self.is_concrete_artifact
|
|
566
566
|
|
|
567
|
+
@property
|
|
568
|
+
def is_pinned(self):
|
|
569
|
+
"""Indicate if the version set is considered pinned.
|
|
570
|
+
|
|
571
|
+
This essentially computes whether the version field of the current
|
|
572
|
+
requirement explicitly requests a specific version and not an allowed
|
|
573
|
+
version range.
|
|
574
|
+
|
|
575
|
+
It is then used to help the resolvelib-based dependency resolver judge
|
|
576
|
+
whether it's acceptable to consider a pre-release candidate version
|
|
577
|
+
despite pre-release installs not being requested by the end-user
|
|
578
|
+
explicitly.
|
|
579
|
+
|
|
580
|
+
See https://github.com/ansible/ansible/pull/81606 for extra context.
|
|
581
|
+
"""
|
|
582
|
+
version_string = self.ver[0]
|
|
583
|
+
return version_string.isdigit() or not (
|
|
584
|
+
version_string == '*' or
|
|
585
|
+
version_string.startswith(('<', '>', '!='))
|
|
586
|
+
)
|
|
587
|
+
|
|
567
588
|
@property
|
|
568
589
|
def source_info(self):
|
|
569
590
|
return self._source_info
|