ansible-core 2.18.4rc1__py3-none-any.whl → 2.19.0b1__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.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz.py +265 -0
- ansible/_internal/_datatag/__init__.py +0 -0
- ansible/_internal/_datatag/_tags.py +130 -0
- ansible/_internal/_datatag/_utils.py +19 -0
- ansible/_internal/_datatag/_wrappers.py +33 -0
- ansible/_internal/_errors/__init__.py +0 -0
- ansible/_internal/_errors/_captured.py +128 -0
- ansible/_internal/_errors/_handler.py +91 -0
- ansible/_internal/_errors/_utils.py +310 -0
- ansible/_internal/_json/__init__.py +160 -0
- ansible/_internal/_json/_legacy_encoder.py +34 -0
- ansible/_internal/_json/_profiles/__init__.py +0 -0
- ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
- ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
- ansible/_internal/_json/_profiles/_legacy.py +198 -0
- ansible/_internal/_locking.py +21 -0
- ansible/_internal/_plugins/__init__.py +0 -0
- ansible/_internal/_plugins/_cache.py +57 -0
- ansible/_internal/_task.py +78 -0
- ansible/_internal/_templating/__init__.py +10 -0
- ansible/_internal/_templating/_access.py +86 -0
- ansible/_internal/_templating/_chain_templar.py +63 -0
- ansible/_internal/_templating/_datatag.py +95 -0
- ansible/_internal/_templating/_engine.py +588 -0
- ansible/_internal/_templating/_errors.py +28 -0
- ansible/_internal/_templating/_jinja_bits.py +1066 -0
- ansible/_internal/_templating/_jinja_common.py +332 -0
- ansible/_internal/_templating/_jinja_patches.py +44 -0
- ansible/_internal/_templating/_jinja_plugins.py +351 -0
- ansible/_internal/_templating/_lazy_containers.py +633 -0
- ansible/_internal/_templating/_marker_behaviors.py +103 -0
- ansible/_internal/_templating/_transform.py +63 -0
- ansible/_internal/_templating/_utils.py +107 -0
- ansible/_internal/_wrapt.py +1052 -0
- ansible/_internal/_yaml/__init__.py +0 -0
- ansible/_internal/_yaml/_constructor.py +240 -0
- ansible/_internal/_yaml/_dumper.py +62 -0
- ansible/_internal/_yaml/_errors.py +166 -0
- ansible/_internal/_yaml/_loader.py +66 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
- ansible/cli/__init__.py +153 -89
- ansible/cli/_ssh_askpass.py +47 -0
- ansible/cli/adhoc.py +14 -7
- ansible/cli/arguments/option_helpers.py +154 -7
- ansible/cli/config.py +43 -68
- ansible/cli/console.py +10 -8
- ansible/cli/doc.py +48 -46
- ansible/cli/galaxy.py +27 -20
- ansible/cli/inventory.py +28 -26
- ansible/cli/playbook.py +4 -12
- ansible/cli/pull.py +51 -11
- ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
- ansible/cli/vault.py +12 -11
- ansible/compat/__init__.py +2 -2
- ansible/config/base.yml +165 -108
- ansible/config/manager.py +52 -49
- ansible/constants.py +3 -4
- ansible/errors/__init__.py +277 -235
- ansible/executor/interpreter_discovery.py +28 -149
- ansible/executor/module_common.py +426 -493
- ansible/executor/play_iterator.py +22 -27
- ansible/executor/playbook_executor.py +11 -11
- ansible/executor/powershell/async_watchdog.ps1 +97 -102
- ansible/executor/powershell/async_wrapper.ps1 +202 -151
- ansible/executor/powershell/become_wrapper.ps1 +89 -144
- ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
- ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
- ansible/executor/powershell/exec_wrapper.ps1 +462 -196
- ansible/executor/powershell/module_manifest.py +417 -265
- ansible/executor/powershell/module_wrapper.ps1 +169 -186
- ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
- ansible/executor/powershell/psrp_put_file.ps1 +122 -0
- ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
- ansible/executor/powershell/winrm_put_file.ps1 +36 -0
- ansible/executor/process/worker.py +136 -76
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +237 -236
- ansible/executor/task_queue_manager.py +62 -38
- ansible/executor/task_result.py +21 -12
- ansible/galaxy/__init__.py +2 -2
- ansible/galaxy/api.py +22 -18
- ansible/galaxy/collection/__init__.py +1 -1
- ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
- ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
- ansible/galaxy/dependency_resolution/providers.py +1 -1
- ansible/galaxy/dependency_resolution/reporters.py +81 -0
- ansible/galaxy/role.py +4 -8
- ansible/galaxy/token.py +28 -21
- ansible/inventory/data.py +47 -57
- ansible/inventory/group.py +44 -72
- ansible/inventory/helpers.py +9 -0
- ansible/inventory/host.py +32 -54
- ansible/inventory/manager.py +77 -34
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +55 -0
- ansible/module_utils/_internal/_ambient_context.py +58 -0
- ansible/module_utils/_internal/_ansiballz.py +133 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
- ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
- ansible/module_utils/_internal/_dataclass_validation.py +217 -0
- ansible/module_utils/_internal/_datatag/__init__.py +928 -0
- ansible/module_utils/_internal/_datatag/_tags.py +38 -0
- ansible/module_utils/_internal/_debugging.py +31 -0
- ansible/module_utils/_internal/_errors.py +30 -0
- ansible/module_utils/_internal/_json/__init__.py +63 -0
- ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
- ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
- ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
- ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
- ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
- ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
- ansible/module_utils/_internal/_patches/__init__.py +66 -0
- ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
- ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
- ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
- ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
- ansible/module_utils/_internal/_testing.py +0 -0
- ansible/module_utils/_internal/_traceback.py +89 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +1 -2
- ansible/module_utils/basic.py +154 -120
- ansible/module_utils/common/_utils.py +24 -28
- ansible/module_utils/common/collections.py +1 -2
- ansible/module_utils/common/dict_transformations.py +2 -2
- ansible/module_utils/common/file.py +2 -2
- ansible/module_utils/common/json.py +90 -84
- ansible/module_utils/common/locale.py +2 -2
- ansible/module_utils/common/messages.py +108 -0
- ansible/module_utils/common/parameters.py +27 -24
- ansible/module_utils/common/process.py +2 -2
- ansible/module_utils/common/respawn.py +41 -19
- ansible/module_utils/common/sentinel.py +66 -0
- ansible/module_utils/common/sys_info.py +8 -8
- ansible/module_utils/common/text/converters.py +16 -37
- ansible/module_utils/common/validation.py +35 -24
- ansible/module_utils/common/warnings.py +86 -25
- ansible/module_utils/common/yaml.py +29 -3
- ansible/module_utils/compat/datetime.py +33 -21
- ansible/module_utils/compat/paramiko.py +21 -10
- ansible/module_utils/compat/typing.py +6 -5
- ansible/module_utils/connection.py +2 -2
- ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
- ansible/module_utils/csharp/Ansible.Become.cs +1 -0
- ansible/module_utils/csharp/Ansible._Async.cs +517 -0
- ansible/module_utils/datatag.py +46 -0
- ansible/module_utils/distro/__init__.py +2 -2
- ansible/module_utils/facts/ansible_collector.py +4 -5
- ansible/module_utils/facts/collector.py +13 -14
- ansible/module_utils/facts/compat.py +4 -4
- ansible/module_utils/facts/default_collectors.py +1 -1
- ansible/module_utils/facts/hardware/aix.py +34 -0
- ansible/module_utils/facts/hardware/base.py +1 -1
- ansible/module_utils/facts/hardware/darwin.py +1 -3
- ansible/module_utils/facts/hardware/freebsd.py +2 -2
- ansible/module_utils/facts/hardware/linux.py +4 -4
- ansible/module_utils/facts/namespace.py +1 -1
- ansible/module_utils/facts/network/base.py +1 -1
- ansible/module_utils/facts/network/fc_wwn.py +1 -2
- ansible/module_utils/facts/network/iscsi.py +1 -2
- ansible/module_utils/facts/network/nvme.py +1 -2
- ansible/module_utils/facts/other/facter.py +1 -2
- ansible/module_utils/facts/other/ohai.py +2 -3
- ansible/module_utils/facts/system/apparmor.py +1 -2
- ansible/module_utils/facts/system/caps.py +1 -1
- ansible/module_utils/facts/system/chroot.py +1 -2
- ansible/module_utils/facts/system/cmdline.py +1 -2
- ansible/module_utils/facts/system/date_time.py +5 -3
- ansible/module_utils/facts/system/distribution.py +9 -8
- ansible/module_utils/facts/system/dns.py +1 -1
- ansible/module_utils/facts/system/env.py +1 -2
- ansible/module_utils/facts/system/fips.py +7 -20
- ansible/module_utils/facts/system/loadavg.py +1 -2
- ansible/module_utils/facts/system/local.py +1 -2
- ansible/module_utils/facts/system/lsb.py +1 -2
- ansible/module_utils/facts/system/pkg_mgr.py +1 -2
- ansible/module_utils/facts/system/platform.py +1 -2
- ansible/module_utils/facts/system/python.py +1 -2
- ansible/module_utils/facts/system/selinux.py +1 -1
- ansible/module_utils/facts/system/service_mgr.py +1 -2
- ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
- ansible/module_utils/facts/system/systemd.py +1 -1
- ansible/module_utils/facts/system/user.py +1 -2
- ansible/module_utils/facts/utils.py +3 -3
- ansible/module_utils/facts/virtual/base.py +1 -1
- ansible/module_utils/facts/virtual/sunos.py +3 -15
- ansible/module_utils/facts/virtual/sysctl.py +3 -16
- ansible/module_utils/json_utils.py +2 -2
- ansible/module_utils/parsing/convert_bool.py +1 -1
- ansible/module_utils/service.py +18 -21
- ansible/module_utils/splitter.py +7 -7
- ansible/module_utils/testing.py +31 -0
- ansible/module_utils/urls.py +60 -31
- ansible/modules/add_host.py +4 -4
- ansible/modules/apt.py +60 -46
- ansible/modules/apt_key.py +19 -12
- ansible/modules/apt_repository.py +19 -16
- ansible/modules/assemble.py +6 -6
- ansible/modules/assert.py +4 -4
- ansible/modules/async_status.py +10 -12
- ansible/modules/async_wrapper.py +8 -3
- ansible/modules/blockinfile.py +6 -7
- ansible/modules/command.py +10 -17
- ansible/modules/copy.py +57 -144
- ansible/modules/cron.py +20 -15
- ansible/modules/deb822_repository.py +8 -9
- ansible/modules/debconf.py +5 -5
- ansible/modules/debug.py +4 -4
- ansible/modules/dnf.py +8 -8
- ansible/modules/dnf5.py +52 -17
- ansible/modules/dpkg_selections.py +4 -4
- ansible/modules/expect.py +8 -10
- ansible/modules/fail.py +4 -4
- ansible/modules/fetch.py +4 -4
- ansible/modules/file.py +174 -133
- ansible/modules/find.py +20 -18
- ansible/modules/gather_facts.py +3 -3
- ansible/modules/get_url.py +59 -53
- ansible/modules/getent.py +7 -9
- ansible/modules/git.py +28 -25
- ansible/modules/group.py +6 -6
- ansible/modules/group_by.py +4 -4
- ansible/modules/hostname.py +13 -29
- ansible/modules/import_playbook.py +6 -6
- ansible/modules/import_role.py +7 -7
- ansible/modules/import_tasks.py +6 -6
- ansible/modules/include_role.py +6 -6
- ansible/modules/include_tasks.py +6 -6
- ansible/modules/include_vars.py +6 -6
- ansible/modules/iptables.py +86 -73
- ansible/modules/known_hosts.py +10 -10
- ansible/modules/lineinfile.py +5 -5
- ansible/modules/meta.py +4 -4
- ansible/modules/mount_facts.py +2 -2
- ansible/modules/package.py +4 -4
- ansible/modules/package_facts.py +22 -10
- ansible/modules/pause.py +6 -6
- ansible/modules/ping.py +6 -6
- ansible/modules/pip.py +10 -11
- ansible/modules/raw.py +4 -4
- ansible/modules/reboot.py +6 -6
- ansible/modules/replace.py +9 -13
- ansible/modules/rpm_key.py +7 -8
- ansible/modules/script.py +4 -4
- ansible/modules/service.py +7 -8
- ansible/modules/service_facts.py +87 -10
- ansible/modules/set_fact.py +5 -5
- ansible/modules/set_stats.py +4 -4
- ansible/modules/setup.py +2 -2
- ansible/modules/shell.py +6 -6
- ansible/modules/slurp.py +6 -6
- ansible/modules/stat.py +9 -23
- ansible/modules/subversion.py +15 -15
- ansible/modules/systemd.py +6 -6
- ansible/modules/systemd_service.py +6 -6
- ansible/modules/sysvinit.py +6 -6
- ansible/modules/tempfile.py +5 -6
- ansible/modules/template.py +6 -6
- ansible/modules/unarchive.py +32 -11
- ansible/modules/uri.py +35 -49
- ansible/modules/user.py +53 -34
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +39 -32
- ansible/modules/wait_for_connection.py +6 -6
- ansible/modules/yum_repository.py +6 -6
- ansible/parsing/ajson.py +14 -32
- ansible/parsing/dataloader.py +99 -54
- ansible/parsing/mod_args.py +28 -44
- ansible/parsing/plugin_docs.py +21 -86
- ansible/parsing/quoting.py +1 -1
- ansible/parsing/splitter.py +27 -12
- ansible/parsing/utils/addresses.py +24 -24
- ansible/parsing/utils/yaml.py +32 -61
- ansible/parsing/vault/__init__.py +319 -87
- ansible/parsing/yaml/__init__.py +0 -18
- ansible/parsing/yaml/dumper.py +6 -120
- ansible/parsing/yaml/loader.py +6 -39
- ansible/parsing/yaml/objects.py +36 -339
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/attribute.py +8 -3
- ansible/playbook/base.py +182 -132
- ansible/playbook/block.py +26 -24
- ansible/playbook/collectionsearch.py +1 -15
- ansible/playbook/conditional.py +3 -77
- ansible/playbook/handler.py +8 -2
- ansible/playbook/helpers.py +41 -53
- ansible/playbook/included_file.py +6 -15
- ansible/playbook/loop_control.py +2 -2
- ansible/playbook/play.py +85 -44
- ansible/playbook/play_context.py +12 -17
- ansible/playbook/playbook_include.py +14 -15
- ansible/playbook/role/__init__.py +24 -26
- ansible/playbook/role/definition.py +15 -17
- ansible/playbook/role/include.py +2 -4
- ansible/playbook/role/metadata.py +10 -11
- ansible/playbook/role_include.py +3 -3
- ansible/playbook/taggable.py +13 -8
- ansible/playbook/task.py +188 -118
- ansible/playbook/task_include.py +5 -5
- ansible/plugins/__init__.py +68 -21
- ansible/plugins/action/__init__.py +209 -176
- ansible/plugins/action/add_host.py +1 -1
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +54 -66
- ansible/plugins/action/copy.py +7 -11
- ansible/plugins/action/debug.py +37 -31
- ansible/plugins/action/dnf.py +3 -4
- ansible/plugins/action/fail.py +1 -1
- ansible/plugins/action/fetch.py +4 -5
- ansible/plugins/action/gather_facts.py +8 -7
- ansible/plugins/action/group_by.py +1 -1
- ansible/plugins/action/include_vars.py +10 -11
- ansible/plugins/action/package.py +3 -6
- ansible/plugins/action/pause.py +2 -2
- ansible/plugins/action/script.py +15 -8
- ansible/plugins/action/service.py +6 -11
- ansible/plugins/action/set_fact.py +3 -12
- ansible/plugins/action/set_stats.py +3 -8
- ansible/plugins/action/template.py +35 -59
- ansible/plugins/action/unarchive.py +1 -1
- ansible/plugins/action/validate_argument_spec.py +5 -5
- ansible/plugins/action/wait_for_connection.py +1 -1
- ansible/plugins/become/__init__.py +31 -8
- ansible/plugins/become/runas.py +71 -0
- ansible/plugins/become/su.py +13 -8
- ansible/plugins/become/sudo.py +19 -0
- ansible/plugins/cache/__init__.py +35 -44
- ansible/plugins/cache/base.py +8 -0
- ansible/plugins/cache/jsonfile.py +10 -16
- ansible/plugins/cache/memory.py +6 -12
- ansible/plugins/callback/__init__.py +141 -123
- ansible/plugins/callback/default.py +30 -23
- ansible/plugins/callback/junit.py +28 -24
- ansible/plugins/callback/minimal.py +17 -14
- ansible/plugins/callback/oneline.py +13 -7
- ansible/plugins/callback/tree.py +10 -6
- ansible/plugins/connection/__init__.py +47 -34
- ansible/plugins/connection/local.py +150 -54
- ansible/plugins/connection/paramiko_ssh.py +21 -18
- ansible/plugins/connection/psrp.py +76 -165
- ansible/plugins/connection/ssh.py +301 -78
- ansible/plugins/connection/winrm.py +58 -140
- ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
- ansible/plugins/doc_fragments/action_core.py +6 -6
- ansible/plugins/doc_fragments/backup.py +2 -2
- ansible/plugins/doc_fragments/checksum_common.py +27 -0
- ansible/plugins/doc_fragments/constructed.py +6 -2
- ansible/plugins/doc_fragments/decrypt.py +2 -2
- ansible/plugins/doc_fragments/default_callback.py +2 -2
- ansible/plugins/doc_fragments/files.py +2 -2
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +2 -2
- ansible/plugins/doc_fragments/return_common.py +2 -2
- ansible/plugins/doc_fragments/template_common.py +4 -4
- ansible/plugins/doc_fragments/url.py +17 -1
- ansible/plugins/doc_fragments/url_windows.py +2 -2
- ansible/plugins/doc_fragments/validate.py +2 -2
- ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
- ansible/plugins/filter/__init__.py +6 -2
- ansible/plugins/filter/b64decode.yml +22 -0
- ansible/plugins/filter/b64encode.yml +22 -0
- ansible/plugins/filter/bool.yml +11 -4
- ansible/plugins/filter/core.py +218 -108
- ansible/plugins/filter/encryption.py +32 -32
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +2 -2
- ansible/plugins/filter/mathstuff.py +30 -37
- ansible/plugins/filter/password_hash.yml +8 -0
- ansible/plugins/filter/regex_search.yml +1 -4
- ansible/plugins/filter/split.yml +1 -1
- ansible/plugins/filter/to_nice_yaml.yml +0 -4
- ansible/plugins/filter/to_yaml.yml +0 -4
- ansible/plugins/filter/unvault.yml +1 -1
- ansible/plugins/filter/urls.py +1 -1
- ansible/plugins/filter/urlsplit.py +8 -9
- ansible/plugins/filter/vault.yml +14 -9
- ansible/plugins/filter/win_basename.yml +6 -1
- ansible/plugins/filter/win_dirname.yml +5 -0
- ansible/plugins/inventory/__init__.py +97 -77
- ansible/plugins/inventory/advanced_host_list.py +7 -5
- ansible/plugins/inventory/auto.py +11 -4
- ansible/plugins/inventory/constructed.py +21 -24
- ansible/plugins/inventory/generator.py +16 -11
- ansible/plugins/inventory/host_list.py +7 -5
- ansible/plugins/inventory/ini.py +78 -44
- ansible/plugins/inventory/script.py +189 -119
- ansible/plugins/inventory/toml.py +16 -126
- ansible/plugins/inventory/yaml.py +10 -8
- ansible/plugins/list.py +3 -3
- ansible/plugins/loader.py +197 -82
- ansible/plugins/lookup/__init__.py +21 -4
- ansible/plugins/lookup/config.py +21 -35
- ansible/plugins/lookup/csvfile.py +3 -2
- ansible/plugins/lookup/dict.py +1 -6
- ansible/plugins/lookup/env.py +12 -9
- ansible/plugins/lookup/file.py +5 -8
- ansible/plugins/lookup/first_found.py +86 -55
- ansible/plugins/lookup/indexed_items.py +1 -10
- ansible/plugins/lookup/ini.py +14 -13
- ansible/plugins/lookup/items.py +1 -1
- ansible/plugins/lookup/lines.py +8 -1
- ansible/plugins/lookup/list.py +1 -1
- ansible/plugins/lookup/nested.py +2 -18
- ansible/plugins/lookup/password.py +5 -5
- ansible/plugins/lookup/pipe.py +5 -7
- ansible/plugins/lookup/sequence.py +18 -8
- ansible/plugins/lookup/subelements.py +1 -4
- ansible/plugins/lookup/template.py +42 -36
- ansible/plugins/lookup/together.py +0 -12
- ansible/plugins/lookup/unvault.py +1 -5
- ansible/plugins/lookup/url.py +2 -8
- ansible/plugins/lookup/vars.py +16 -24
- ansible/plugins/shell/__init__.py +2 -2
- ansible/plugins/shell/cmd.py +2 -2
- ansible/plugins/shell/powershell.py +39 -22
- ansible/plugins/shell/sh.py +3 -2
- ansible/plugins/strategy/__init__.py +94 -113
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +13 -28
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +31 -33
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +54 -20
- ansible/plugins/test/files.py +1 -1
- ansible/plugins/test/mathstuff.py +3 -3
- ansible/plugins/test/uri.py +3 -3
- ansible/plugins/vars/host_group_vars.py +7 -14
- ansible/release.py +2 -2
- ansible/template/__init__.py +368 -944
- ansible/utils/__init__.py +0 -18
- ansible/utils/_ssh_agent.py +657 -0
- ansible/utils/collection_loader/__init__.py +52 -5
- ansible/utils/collection_loader/_collection_config.py +5 -6
- ansible/utils/collection_loader/_collection_finder.py +79 -93
- ansible/utils/collection_loader/_collection_meta.py +13 -8
- ansible/utils/display.py +428 -58
- ansible/utils/encrypt.py +27 -19
- ansible/utils/fqcn.py +2 -2
- ansible/utils/hashing.py +2 -2
- ansible/utils/helpers.py +2 -2
- ansible/utils/listify.py +8 -8
- ansible/utils/lock.py +2 -2
- ansible/utils/path.py +4 -4
- ansible/utils/plugin_docs.py +14 -13
- ansible/utils/sentinel.py +4 -62
- ansible/utils/singleton.py +2 -0
- ansible/utils/ssh_functions.py +1 -1
- ansible/utils/unsafe_proxy.py +23 -332
- ansible/utils/vars.py +28 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +4 -4
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +205 -264
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b1.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b1.dist-info/RECORD +1070 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/WHEEL +1 -1
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +6 -6
- ansible_test/_data/completion/windows.txt +1 -0
- ansible_test/_data/requirements/ansible.txt +2 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.txt +1 -1
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.pylint.txt +4 -4
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_data/requirements/units.txt +1 -0
- ansible_test/_internal/__init__.py +1 -0
- ansible_test/_internal/ansible_util.py +2 -0
- ansible_test/_internal/become.py +1 -0
- ansible_test/_internal/bootstrap.py +1 -0
- ansible_test/_internal/cache.py +1 -0
- ansible_test/_internal/cgroup.py +1 -0
- ansible_test/_internal/ci/__init__.py +1 -0
- ansible_test/_internal/ci/azp.py +1 -0
- ansible_test/_internal/ci/local.py +1 -0
- ansible_test/_internal/classification/__init__.py +1 -0
- ansible_test/_internal/classification/common.py +1 -0
- ansible_test/_internal/classification/csharp.py +1 -0
- ansible_test/_internal/classification/powershell.py +1 -0
- ansible_test/_internal/classification/python.py +1 -0
- ansible_test/_internal/cli/__init__.py +1 -0
- ansible_test/_internal/cli/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/__init__.py +1 -0
- ansible_test/_internal/cli/argparsing/actions.py +1 -0
- ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
- ansible_test/_internal/cli/argparsing/parsers.py +1 -0
- ansible_test/_internal/cli/commands/__init__.py +11 -0
- ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
- ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
- ansible_test/_internal/cli/commands/coverage/html.py +1 -0
- ansible_test/_internal/cli/commands/coverage/report.py +1 -0
- ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
- ansible_test/_internal/cli/commands/env.py +1 -0
- ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
- ansible_test/_internal/cli/commands/integration/network.py +1 -0
- ansible_test/_internal/cli/commands/integration/posix.py +1 -0
- ansible_test/_internal/cli/commands/integration/windows.py +1 -0
- ansible_test/_internal/cli/commands/sanity.py +9 -0
- ansible_test/_internal/cli/commands/shell.py +1 -0
- ansible_test/_internal/cli/commands/units.py +1 -0
- ansible_test/_internal/cli/compat.py +1 -0
- ansible_test/_internal/cli/completers.py +1 -0
- ansible_test/_internal/cli/converters.py +1 -0
- ansible_test/_internal/cli/environments.py +1 -0
- ansible_test/_internal/cli/epilog.py +1 -0
- ansible_test/_internal/cli/parsers/__init__.py +1 -0
- ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/helpers.py +1 -0
- ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
- ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
- ansible_test/_internal/commands/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/__init__.py +2 -1
- ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
- ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
- ansible_test/_internal/commands/coverage/combine.py +2 -1
- ansible_test/_internal/commands/coverage/erase.py +1 -0
- ansible_test/_internal/commands/coverage/html.py +1 -0
- ansible_test/_internal/commands/coverage/report.py +1 -0
- ansible_test/_internal/commands/coverage/xml.py +1 -0
- ansible_test/_internal/commands/env/__init__.py +2 -0
- ansible_test/_internal/commands/integration/__init__.py +4 -0
- ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
- ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
- ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
- ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
- ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
- ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
- ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
- ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
- ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
- ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
- ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
- ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
- ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
- ansible_test/_internal/commands/integration/coverage.py +1 -0
- ansible_test/_internal/commands/integration/filters.py +1 -0
- ansible_test/_internal/commands/integration/network.py +1 -0
- ansible_test/_internal/commands/integration/posix.py +1 -0
- ansible_test/_internal/commands/integration/windows.py +1 -0
- ansible_test/_internal/commands/sanity/__init__.py +16 -1
- ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
- ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
- ansible_test/_internal/commands/sanity/compile.py +1 -0
- ansible_test/_internal/commands/sanity/ignores.py +1 -0
- ansible_test/_internal/commands/sanity/import.py +1 -0
- ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
- ansible_test/_internal/commands/sanity/pep8.py +1 -0
- ansible_test/_internal/commands/sanity/pslint.py +1 -0
- ansible_test/_internal/commands/sanity/pylint.py +24 -26
- ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
- ansible_test/_internal/commands/sanity/yamllint.py +1 -0
- ansible_test/_internal/commands/shell/__init__.py +1 -0
- ansible_test/_internal/commands/units/__init__.py +1 -0
- ansible_test/_internal/compat/__init__.py +1 -0
- ansible_test/_internal/compat/packaging.py +1 -0
- ansible_test/_internal/compat/yaml.py +1 -0
- ansible_test/_internal/completion.py +1 -0
- ansible_test/_internal/config.py +2 -0
- ansible_test/_internal/connections.py +1 -0
- ansible_test/_internal/constants.py +1 -0
- ansible_test/_internal/containers.py +1 -0
- ansible_test/_internal/content_config.py +1 -0
- ansible_test/_internal/core_ci.py +1 -0
- ansible_test/_internal/coverage_util.py +11 -10
- ansible_test/_internal/data.py +1 -0
- ansible_test/_internal/delegation.py +1 -0
- ansible_test/_internal/dev/__init__.py +1 -0
- ansible_test/_internal/dev/container_probe.py +1 -0
- ansible_test/_internal/diff.py +3 -2
- ansible_test/_internal/docker_util.py +2 -1
- ansible_test/_internal/encoding.py +1 -0
- ansible_test/_internal/executor.py +1 -0
- ansible_test/_internal/git.py +1 -0
- ansible_test/_internal/host_configs.py +1 -0
- ansible_test/_internal/host_profiles.py +1 -0
- ansible_test/_internal/http.py +1 -0
- ansible_test/_internal/init.py +1 -0
- ansible_test/_internal/inventory.py +35 -3
- ansible_test/_internal/io.py +1 -0
- ansible_test/_internal/metadata.py +1 -0
- ansible_test/_internal/payload.py +1 -0
- ansible_test/_internal/provider/__init__.py +1 -0
- ansible_test/_internal/provider/layout/__init__.py +1 -0
- ansible_test/_internal/provider/layout/ansible.py +1 -0
- ansible_test/_internal/provider/layout/collection.py +1 -0
- ansible_test/_internal/provider/layout/unsupported.py +1 -0
- ansible_test/_internal/provider/source/__init__.py +1 -0
- ansible_test/_internal/provider/source/git.py +1 -0
- ansible_test/_internal/provider/source/installed.py +1 -0
- ansible_test/_internal/provider/source/unsupported.py +1 -0
- ansible_test/_internal/provider/source/unversioned.py +1 -0
- ansible_test/_internal/provisioning.py +1 -0
- ansible_test/_internal/pypi_proxy.py +6 -5
- ansible_test/_internal/python_requirements.py +1 -0
- ansible_test/_internal/ssh.py +1 -0
- ansible_test/_internal/target.py +1 -0
- ansible_test/_internal/test.py +3 -2
- ansible_test/_internal/thread.py +1 -0
- ansible_test/_internal/timeout.py +1 -0
- ansible_test/_internal/util.py +1 -0
- ansible_test/_internal/util_common.py +5 -2
- ansible_test/_internal/venv.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
- ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
- ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
- ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
- ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
- ansible_test/_util/controller/tools/collection_detail.py +1 -0
- ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
- ansible_test/_util/target/sanity/compile/compile.py +1 -0
- ansible_test/_util/target/sanity/import/importer.py +15 -16
- ansible_test/_util/target/setup/bootstrap.sh +9 -20
- ansible_test/_util/target/setup/probe_cgroups.py +1 -0
- ansible_test/_util/target/setup/quiet_pip.py +1 -0
- ansible_test/_util/target/setup/requirements.py +35 -27
- ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
- ansible_test/_util/target/tools/yamlcheck.py +2 -1
- ansible/compat/selectors.py +0 -32
- ansible/errors/yaml_strings.py +0 -138
- ansible/executor/action_write_locks.py +0 -44
- ansible/executor/discovery/python_target.py +0 -47
- ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
- ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
- ansible/module_utils/compat/importlib.py +0 -26
- ansible/module_utils/compat/selectors.py +0 -32
- ansible/module_utils/pycompat24.py +0 -73
- ansible/parsing/utils/jsonify.py +0 -36
- ansible/parsing/yaml/constructor.py +0 -178
- ansible/template/native_helpers.py +0 -251
- ansible/template/template.py +0 -43
- ansible/template/vars.py +0 -77
- ansible/utils/native_jinja.py +0 -11
- ansible/vars/fact_cache.py +0 -71
- ansible_core-2.18.4rc1.dist-info/RECORD +0 -992
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/COPYING +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/top_level.txt +0 -0
@@ -27,18 +27,22 @@ import multiprocessing.queues
|
|
27
27
|
|
28
28
|
from ansible import constants as C
|
29
29
|
from ansible import context
|
30
|
-
from ansible.errors import AnsibleError
|
30
|
+
from ansible.errors import AnsibleError, ExitCode, AnsibleCallbackError
|
31
|
+
from ansible._internal._errors._handler import ErrorHandler
|
31
32
|
from ansible.executor.play_iterator import PlayIterator
|
32
33
|
from ansible.executor.stats import AggregateStats
|
33
34
|
from ansible.executor.task_result import TaskResult
|
35
|
+
from ansible.inventory.data import InventoryData
|
34
36
|
from ansible.module_utils.six import string_types
|
35
|
-
from ansible.module_utils.common.text.converters import
|
37
|
+
from ansible.module_utils.common.text.converters import to_native
|
38
|
+
from ansible.parsing.dataloader import DataLoader
|
36
39
|
from ansible.playbook.play_context import PlayContext
|
37
40
|
from ansible.playbook.task import Task
|
38
41
|
from ansible.plugins.loader import callback_loader, strategy_loader, module_loader
|
39
42
|
from ansible.plugins.callback import CallbackBase
|
40
|
-
from ansible.
|
43
|
+
from ansible._internal._templating._engine import TemplateEngine
|
41
44
|
from ansible.vars.hostvars import HostVars
|
45
|
+
from ansible.vars.manager import VariableManager
|
42
46
|
from ansible.utils.display import Display
|
43
47
|
from ansible.utils.lock import lock_decorator
|
44
48
|
from ansible.utils.multiprocessing import context as multiprocessing_context
|
@@ -47,6 +51,10 @@ from dataclasses import dataclass
|
|
47
51
|
|
48
52
|
__all__ = ['TaskQueueManager']
|
49
53
|
|
54
|
+
STDIN_FILENO = 0
|
55
|
+
STDOUT_FILENO = 1
|
56
|
+
STDERR_FILENO = 2
|
57
|
+
|
50
58
|
display = Display()
|
51
59
|
|
52
60
|
|
@@ -111,7 +119,7 @@ class AnsibleEndPlay(Exception):
|
|
111
119
|
|
112
120
|
class TaskQueueManager:
|
113
121
|
|
114
|
-
|
122
|
+
"""
|
115
123
|
This class handles the multiprocessing requirements of Ansible by
|
116
124
|
creating a pool of worker forks, a result handler fork, and a
|
117
125
|
manager object with shared datastructures/queues for coordinating
|
@@ -119,29 +127,40 @@ class TaskQueueManager:
|
|
119
127
|
|
120
128
|
The queue manager is responsible for loading the play strategy plugin,
|
121
129
|
which dispatches the Play's tasks to hosts.
|
122
|
-
|
123
|
-
|
124
|
-
RUN_OK =
|
125
|
-
RUN_ERROR =
|
126
|
-
RUN_FAILED_HOSTS =
|
127
|
-
RUN_UNREACHABLE_HOSTS =
|
128
|
-
RUN_FAILED_BREAK_PLAY = 8
|
129
|
-
RUN_UNKNOWN_ERROR = 255
|
130
|
-
|
131
|
-
|
132
|
-
|
130
|
+
"""
|
131
|
+
|
132
|
+
RUN_OK = ExitCode.SUCCESS
|
133
|
+
RUN_ERROR = ExitCode.GENERIC_ERROR
|
134
|
+
RUN_FAILED_HOSTS = ExitCode.HOST_FAILED
|
135
|
+
RUN_UNREACHABLE_HOSTS = ExitCode.HOST_UNREACHABLE
|
136
|
+
RUN_FAILED_BREAK_PLAY = 8 # never leaves PlaybookExecutor.run
|
137
|
+
RUN_UNKNOWN_ERROR = 255 # never leaves PlaybookExecutor.run, intentionally includes the bit value for 8
|
138
|
+
|
139
|
+
_callback_dispatch_error_handler = ErrorHandler.from_config('_CALLBACK_DISPATCH_ERROR_BEHAVIOR')
|
140
|
+
|
141
|
+
def __init__(
|
142
|
+
self,
|
143
|
+
inventory: InventoryData,
|
144
|
+
variable_manager: VariableManager,
|
145
|
+
loader: DataLoader,
|
146
|
+
passwords: dict[str, str | None],
|
147
|
+
stdout_callback: str | None = None,
|
148
|
+
run_additional_callbacks: bool = True,
|
149
|
+
run_tree: bool = False,
|
150
|
+
forks: int | None = None,
|
151
|
+
) -> None:
|
133
152
|
self._inventory = inventory
|
134
153
|
self._variable_manager = variable_manager
|
135
154
|
self._loader = loader
|
136
155
|
self._stats = AggregateStats()
|
137
156
|
self.passwords = passwords
|
138
|
-
self._stdout_callback = stdout_callback
|
157
|
+
self._stdout_callback: str | None | CallbackBase = stdout_callback
|
139
158
|
self._run_additional_callbacks = run_additional_callbacks
|
140
159
|
self._run_tree = run_tree
|
141
160
|
self._forks = forks or 5
|
142
161
|
|
143
162
|
self._callbacks_loaded = False
|
144
|
-
self._callback_plugins = []
|
163
|
+
self._callback_plugins: list[CallbackBase] = []
|
145
164
|
self._start_at_done = False
|
146
165
|
|
147
166
|
# make sure any module paths (if specified) are added to the module_loader
|
@@ -154,14 +173,21 @@ class TaskQueueManager:
|
|
154
173
|
self._terminated = False
|
155
174
|
|
156
175
|
# dictionaries to keep track of failed/unreachable hosts
|
157
|
-
self._failed_hosts = dict()
|
158
|
-
self._unreachable_hosts = dict()
|
176
|
+
self._failed_hosts: dict[str, t.Literal[True]] = dict()
|
177
|
+
self._unreachable_hosts: dict[str, t.Literal[True]] = dict()
|
159
178
|
|
160
179
|
try:
|
161
180
|
self._final_q = FinalQueue()
|
162
181
|
except OSError as e:
|
163
182
|
raise AnsibleError("Unable to use multiprocessing, this is normally caused by lack of access to /dev/shm: %s" % to_native(e))
|
164
183
|
|
184
|
+
try:
|
185
|
+
# Done in tqm, and not display, because this is only needed for commands that execute tasks
|
186
|
+
for fd in (STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO):
|
187
|
+
os.set_inheritable(fd, False)
|
188
|
+
except Exception as ex:
|
189
|
+
self.warning(f"failed to set stdio as non inheritable: {ex}")
|
190
|
+
|
165
191
|
self._callback_lock = threading.Lock()
|
166
192
|
|
167
193
|
# A temporary file (opened pre-fork) used by connection
|
@@ -175,11 +201,11 @@ class TaskQueueManager:
|
|
175
201
|
self._workers.append(None)
|
176
202
|
|
177
203
|
def load_callbacks(self):
|
178
|
-
|
204
|
+
"""
|
179
205
|
Loads all available callbacks, with the exception of those which
|
180
206
|
utilize the CALLBACK_TYPE option. When CALLBACK_TYPE is set to 'stdout',
|
181
207
|
only one such callback plugin will be loaded.
|
182
|
-
|
208
|
+
"""
|
183
209
|
|
184
210
|
if self._callbacks_loaded:
|
185
211
|
return
|
@@ -268,19 +294,19 @@ class TaskQueueManager:
|
|
268
294
|
self._callbacks_loaded = True
|
269
295
|
|
270
296
|
def run(self, play):
|
271
|
-
|
297
|
+
"""
|
272
298
|
Iterates over the roles/tasks in a play, using the given (or default)
|
273
299
|
strategy for queueing tasks. The default is the linear strategy, which
|
274
300
|
operates like classic Ansible by keeping all hosts in lock-step with
|
275
301
|
a given task (meaning no hosts move on to the next task until all hosts
|
276
302
|
are done with the current task).
|
277
|
-
|
303
|
+
"""
|
278
304
|
|
279
305
|
if not self._callbacks_loaded:
|
280
306
|
self.load_callbacks()
|
281
307
|
|
282
308
|
all_vars = self._variable_manager.get_vars(play=play)
|
283
|
-
templar =
|
309
|
+
templar = TemplateEngine(loader=self._loader, variables=all_vars)
|
284
310
|
|
285
311
|
new_play = play.copy()
|
286
312
|
new_play.post_validate(templar)
|
@@ -383,25 +409,25 @@ class TaskQueueManager:
|
|
383
409
|
except AttributeError:
|
384
410
|
pass
|
385
411
|
|
386
|
-
def clear_failed_hosts(self):
|
412
|
+
def clear_failed_hosts(self) -> None:
|
387
413
|
self._failed_hosts = dict()
|
388
414
|
|
389
|
-
def get_inventory(self):
|
415
|
+
def get_inventory(self) -> InventoryData:
|
390
416
|
return self._inventory
|
391
417
|
|
392
|
-
def get_variable_manager(self):
|
418
|
+
def get_variable_manager(self) -> VariableManager:
|
393
419
|
return self._variable_manager
|
394
420
|
|
395
|
-
def get_loader(self):
|
421
|
+
def get_loader(self) -> DataLoader:
|
396
422
|
return self._loader
|
397
423
|
|
398
424
|
def get_workers(self):
|
399
425
|
return self._workers[:]
|
400
426
|
|
401
|
-
def terminate(self):
|
427
|
+
def terminate(self) -> None:
|
402
428
|
self._terminated = True
|
403
429
|
|
404
|
-
def has_dead_workers(self):
|
430
|
+
def has_dead_workers(self) -> bool:
|
405
431
|
|
406
432
|
# [<WorkerProcess(WorkerProcess-2, stopped[SIGKILL])>,
|
407
433
|
# <WorkerProcess(WorkerProcess-2, stopped[SIGTERM])>
|
@@ -414,6 +440,7 @@ class TaskQueueManager:
|
|
414
440
|
|
415
441
|
@lock_decorator(attr='_callback_lock')
|
416
442
|
def send_callback(self, method_name, *args, **kwargs):
|
443
|
+
# We always send events to stdout callback first, rest should follow config order
|
417
444
|
for callback_plugin in [self._stdout_callback] + self._callback_plugins:
|
418
445
|
# a plugin that set self.disabled to True will not be called
|
419
446
|
# see osx_say.py example for such a plugin
|
@@ -457,11 +484,8 @@ class TaskQueueManager:
|
|
457
484
|
continue
|
458
485
|
|
459
486
|
for method in methods:
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
from traceback import format_tb
|
466
|
-
from sys import exc_info
|
467
|
-
display.vvv('Callback Exception: \n' + ' '.join(format_tb(exc_info()[2])))
|
487
|
+
with self._callback_dispatch_error_handler.handle(AnsibleCallbackError):
|
488
|
+
try:
|
489
|
+
method(*new_args, **kwargs)
|
490
|
+
except Exception as ex:
|
491
|
+
raise AnsibleCallbackError(f"Callback dispatch {method_name!r} failed for plugin {callback_plugin._load_name!r}.") from ex
|
ansible/executor/task_result.py
CHANGED
@@ -4,12 +4,14 @@
|
|
4
4
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
7
|
+
import typing as t
|
8
|
+
|
7
9
|
from ansible import constants as C
|
8
10
|
from ansible.parsing.dataloader import DataLoader
|
9
11
|
from ansible.vars.clean import module_response_deepcopy, strip_internal_keys
|
10
12
|
|
11
13
|
_IGNORE = ('failed', 'skipped')
|
12
|
-
_PRESERVE = ('attempts', 'changed', 'retries')
|
14
|
+
_PRESERVE = ('attempts', 'changed', 'retries', '_ansible_no_log')
|
13
15
|
_SUB_PRESERVE = {'_ansible_delegated_vars': ('ansible_host', 'ansible_port', 'ansible_user', 'ansible_connection')}
|
14
16
|
|
15
17
|
# stuff callbacks need
|
@@ -22,11 +24,11 @@ CLEAN_EXCEPTIONS = (
|
|
22
24
|
|
23
25
|
|
24
26
|
class TaskResult:
|
25
|
-
|
27
|
+
"""
|
26
28
|
This class is responsible for interpreting the resulting data
|
27
29
|
from an executed task, and provides helper methods for determining
|
28
30
|
the result of a given task.
|
29
|
-
|
31
|
+
"""
|
30
32
|
|
31
33
|
def __init__(self, host, task, return_data, task_fields=None):
|
32
34
|
self._host = host
|
@@ -93,7 +95,7 @@ class TaskResult:
|
|
93
95
|
return ret
|
94
96
|
|
95
97
|
def _check_key(self, key):
|
96
|
-
|
98
|
+
"""get a specific key from the result or its items"""
|
97
99
|
|
98
100
|
if isinstance(self._result, dict) and key in self._result:
|
99
101
|
return self._result.get(key, False)
|
@@ -106,7 +108,7 @@ class TaskResult:
|
|
106
108
|
|
107
109
|
def clean_copy(self):
|
108
110
|
|
109
|
-
|
111
|
+
""" returns 'clean' taskresult object """
|
110
112
|
|
111
113
|
# FIXME: clean task_fields, _task and _host copies
|
112
114
|
result = TaskResult(self._host, self._task, {}, self._task_fields)
|
@@ -127,15 +129,15 @@ class TaskResult:
|
|
127
129
|
if key in self._result[sub]:
|
128
130
|
subset[sub][key] = self._result[sub][key]
|
129
131
|
|
130
|
-
|
131
|
-
|
132
|
+
# DTFIX-FUTURE: is checking no_log here redundant now that we use _ansible_no_log everywhere?
|
133
|
+
if isinstance(self._task.no_log, bool) and self._task.no_log or self._result.get('_ansible_no_log'):
|
134
|
+
censored_result = censor_result(self._result)
|
132
135
|
|
133
|
-
|
134
|
-
|
135
|
-
if
|
136
|
-
x[preserve] = self._result[preserve]
|
136
|
+
if results := self._result.get('results'):
|
137
|
+
# maintain shape for loop results so callback behavior recognizes a loop was performed
|
138
|
+
censored_result.update(results=[censor_result(item) if item.get('_ansible_no_log') else item for item in results])
|
137
139
|
|
138
|
-
result._result =
|
140
|
+
result._result = censored_result
|
139
141
|
elif self._result:
|
140
142
|
result._result = module_response_deepcopy(self._result)
|
141
143
|
|
@@ -151,3 +153,10 @@ class TaskResult:
|
|
151
153
|
result._result.update(subset)
|
152
154
|
|
153
155
|
return result
|
156
|
+
|
157
|
+
|
158
|
+
def censor_result(result: dict[str, t.Any]) -> dict[str, t.Any]:
|
159
|
+
censored_result = {key: value for key in _PRESERVE if (value := result.get(key, ...)) is not ...}
|
160
|
+
censored_result.update(censored="the output has been hidden due to the fact that 'no_log: true' was specified for this result")
|
161
|
+
|
162
|
+
return censored_result
|
ansible/galaxy/__init__.py
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
#
|
20
20
|
########################################################################
|
21
|
-
|
21
|
+
""" This manages remote shared Ansible objects, mainly roles"""
|
22
22
|
|
23
23
|
from __future__ import annotations
|
24
24
|
|
@@ -40,7 +40,7 @@ def get_collections_galaxy_meta_info():
|
|
40
40
|
|
41
41
|
|
42
42
|
class Galaxy(object):
|
43
|
-
|
43
|
+
""" Keeps global galaxy info """
|
44
44
|
|
45
45
|
def __init__(self):
|
46
46
|
# TODO: eventually remove this as it contains a mismash of properties that aren't really global
|
ansible/galaxy/api.py
CHANGED
@@ -57,13 +57,13 @@ def should_retry_error(exception):
|
|
57
57
|
if isinstance(exception, GalaxyError) and exception.http_code in RETRY_HTTP_ERROR_CODES:
|
58
58
|
return True
|
59
59
|
|
60
|
-
if isinstance(exception, AnsibleError) and (
|
60
|
+
if isinstance(exception, AnsibleError) and (cause := exception.__cause__):
|
61
61
|
# URLError is often a proxy for an underlying error, handle wrapped exceptions
|
62
|
-
if isinstance(
|
63
|
-
|
62
|
+
if isinstance(cause, URLError):
|
63
|
+
cause = cause.reason
|
64
64
|
|
65
65
|
# Handle common URL related errors
|
66
|
-
if isinstance(
|
66
|
+
if isinstance(cause, (TimeoutError, BadStatusLine, IncompleteRead)):
|
67
67
|
return True
|
68
68
|
|
69
69
|
return False
|
@@ -408,11 +408,8 @@ class GalaxyAPI:
|
|
408
408
|
method=method, timeout=self._server_timeout, http_agent=user_agent(), follow_redirects='safe')
|
409
409
|
except HTTPError as e:
|
410
410
|
raise GalaxyError(e, error_context_msg)
|
411
|
-
except Exception as
|
412
|
-
raise AnsibleError(
|
413
|
-
"Unknown error when attempting to call Galaxy at '%s': %s" % (url, to_native(e)),
|
414
|
-
orig_exc=e
|
415
|
-
)
|
411
|
+
except Exception as ex:
|
412
|
+
raise AnsibleError(f"Unknown error when attempting to call Galaxy at {url!r}.") from ex
|
416
413
|
|
417
414
|
resp_data = to_text(resp.read(), errors='surrogate_or_strict')
|
418
415
|
try:
|
@@ -471,8 +468,8 @@ class GalaxyAPI:
|
|
471
468
|
resp = open_url(url, data=args, validate_certs=self.validate_certs, method="POST", http_agent=user_agent(), timeout=self._server_timeout)
|
472
469
|
except HTTPError as e:
|
473
470
|
raise GalaxyError(e, 'Attempting to authenticate to galaxy')
|
474
|
-
except Exception as
|
475
|
-
raise AnsibleError('Unable to authenticate to galaxy
|
471
|
+
except Exception as ex:
|
472
|
+
raise AnsibleError('Unable to authenticate to galaxy.') from ex
|
476
473
|
|
477
474
|
data = json.loads(to_text(resp.read(), errors='surrogate_or_strict'))
|
478
475
|
return data
|
@@ -817,8 +814,17 @@ class GalaxyAPI:
|
|
817
814
|
|
818
815
|
signatures = data.get('signatures') or []
|
819
816
|
|
817
|
+
download_url_info = urlparse(data['download_url'])
|
818
|
+
if not download_url_info.scheme and not download_url_info.path.startswith('/'):
|
819
|
+
# galaxy does a lot of redirects, with much more complex pathing than we use
|
820
|
+
# within this codebase, without updating _call_galaxy to be able to return
|
821
|
+
# the final URL, we can't reliably build a relative URL.
|
822
|
+
raise AnsibleError(f'Invalid non absolute download_url: {data["download_url"]}')
|
823
|
+
|
824
|
+
download_url = urljoin(self.api_server, data['download_url'])
|
825
|
+
|
820
826
|
return CollectionVersionMetadata(data['namespace']['name'], data['collection']['name'], data['version'],
|
821
|
-
|
827
|
+
download_url, data['artifact']['sha256'],
|
822
828
|
data['metadata']['dependencies'], data['href'], signatures)
|
823
829
|
|
824
830
|
@g_connect(['v2', 'v3'])
|
@@ -896,12 +902,10 @@ class GalaxyAPI:
|
|
896
902
|
if not next_link:
|
897
903
|
break
|
898
904
|
elif relative_link:
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
versions_url = urljoin(versions_url, urlparse(versions_url).path)
|
904
|
-
next_link = versions_url.replace(versions_url_info.path, next_link)
|
905
|
+
next_link_info = urlparse(next_link)
|
906
|
+
if not next_link_info.scheme and not next_link_info.path.startswith('/'):
|
907
|
+
raise AnsibleError(f'Invalid non absolute pagination link: {next_link}')
|
908
|
+
next_link = urljoin(self.api_server, next_link)
|
905
909
|
|
906
910
|
data = self._call_galaxy(to_native(next_link, errors='surrogate_or_strict'),
|
907
911
|
error_context_msg=error_context_msg, cache=True, cache_key=cache_key)
|
@@ -126,13 +126,13 @@ from ansible.galaxy.dependency_resolution.dataclasses import (
|
|
126
126
|
from ansible.galaxy.dependency_resolution.versioning import meets_requirements
|
127
127
|
from ansible.plugins.loader import get_all_plugin_loaders
|
128
128
|
from ansible.module_utils.common.file import S_IRWU_RG_RO, S_IRWXU_RXG_RXO, S_IXANY
|
129
|
+
from ansible.module_utils.common.sentinel import Sentinel
|
129
130
|
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
130
131
|
from ansible.module_utils.common.collections import is_sequence
|
131
132
|
from ansible.module_utils.common.yaml import yaml_dump
|
132
133
|
from ansible.utils.collection_loader import AnsibleCollectionRef
|
133
134
|
from ansible.utils.display import Display
|
134
135
|
from ansible.utils.hashing import secure_hash, secure_hash_s
|
135
|
-
from ansible.utils.sentinel import Sentinel
|
136
136
|
|
137
137
|
|
138
138
|
display = Display()
|
@@ -35,10 +35,10 @@ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_
|
|
35
35
|
from ansible.module_utils.api import retry_with_delays_and_condition
|
36
36
|
from ansible.module_utils.api import generate_jittered_backoff
|
37
37
|
from ansible.module_utils.common.process import get_bin_path
|
38
|
+
from ansible.module_utils.common.sentinel import Sentinel
|
38
39
|
from ansible.module_utils.common.yaml import yaml_load
|
39
40
|
from ansible.module_utils.urls import open_url
|
40
41
|
from ansible.utils.display import Display
|
41
|
-
from ansible.utils.sentinel import Sentinel
|
42
42
|
|
43
43
|
import ansible.constants as C
|
44
44
|
|
@@ -485,16 +485,13 @@ def _download_file(url, b_path, expected_hash, validate_certs, token=None, timeo
|
|
485
485
|
display.display("Downloading %s to %s" % (url, to_text(b_tarball_dir)))
|
486
486
|
# NOTE: Galaxy redirects downloads to S3 which rejects the request
|
487
487
|
# NOTE: if an Authorization header is attached so don't redirect it
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
)
|
496
|
-
except Exception as err:
|
497
|
-
raise AnsibleError(to_native(err), orig_exc=err)
|
488
|
+
resp = open_url(
|
489
|
+
to_native(url, errors='surrogate_or_strict'),
|
490
|
+
validate_certs=validate_certs,
|
491
|
+
headers=None if token is None else token.headers(),
|
492
|
+
unredirected_headers=['Authorization'], http_agent=user_agent(),
|
493
|
+
timeout=timeout
|
494
|
+
)
|
498
495
|
|
499
496
|
with open(b_file_path, 'wb') as download_file: # type: t.BinaryIO
|
500
497
|
actual_hash = _consume_file(resp, write_to=download_file)
|
@@ -7,6 +7,7 @@
|
|
7
7
|
from __future__ import annotations
|
8
8
|
|
9
9
|
import os
|
10
|
+
import pathlib
|
10
11
|
import typing as t
|
11
12
|
|
12
13
|
from collections import namedtuple
|
@@ -25,6 +26,8 @@ if t.TYPE_CHECKING:
|
|
25
26
|
'_ComputedReqKindsMixin',
|
26
27
|
)
|
27
28
|
|
29
|
+
import ansible
|
30
|
+
import ansible.release
|
28
31
|
|
29
32
|
from ansible.errors import AnsibleError, AnsibleAssertionError
|
30
33
|
from ansible.galaxy.api import GalaxyAPI
|
@@ -39,6 +42,7 @@ _ALLOW_CONCRETE_POINTER_IN_SOURCE = False # NOTE: This is a feature flag
|
|
39
42
|
_GALAXY_YAML = b'galaxy.yml'
|
40
43
|
_MANIFEST_JSON = b'MANIFEST.json'
|
41
44
|
_SOURCE_METADATA_FILE = b'GALAXY.yml'
|
45
|
+
_ANSIBLE_PACKAGE_PATH = pathlib.Path(ansible.__file__).parent
|
42
46
|
|
43
47
|
display = Display()
|
44
48
|
|
@@ -224,6 +228,13 @@ class _ComputedReqKindsMixin:
|
|
224
228
|
if dir_path.endswith(to_bytes(os.path.sep)):
|
225
229
|
dir_path = dir_path.rstrip(to_bytes(os.path.sep))
|
226
230
|
if not _is_collection_dir(dir_path):
|
231
|
+
dir_pathlib = pathlib.Path(to_text(dir_path))
|
232
|
+
|
233
|
+
# special handling for bundled collections without manifests, e.g., ansible._protomatter
|
234
|
+
if dir_pathlib.is_relative_to(_ANSIBLE_PACKAGE_PATH):
|
235
|
+
req_name = f'{dir_pathlib.parent.name}.{dir_pathlib.name}'
|
236
|
+
return cls(req_name, ansible.release.__version__, dir_path, 'dir', None)
|
237
|
+
|
227
238
|
display.warning(
|
228
239
|
u"Collection at '{path!s}' does not have a {manifest_json!s} "
|
229
240
|
u'file, nor has it {galaxy_yml!s}: cannot detect version.'.
|
@@ -578,10 +589,9 @@ class _ComputedReqKindsMixin:
|
|
578
589
|
|
579
590
|
See https://github.com/ansible/ansible/pull/81606 for extra context.
|
580
591
|
"""
|
581
|
-
|
582
|
-
return
|
583
|
-
|
584
|
-
version_string.startswith(('<', '>', '!='))
|
592
|
+
version_spec_start_char = self.ver[0]
|
593
|
+
return version_spec_start_char.isdigit() or not (
|
594
|
+
version_spec_start_char.startswith(('<', '>', '!', '*'))
|
585
595
|
)
|
586
596
|
|
587
597
|
@property
|
@@ -39,7 +39,7 @@ except ImportError:
|
|
39
39
|
|
40
40
|
# TODO: add python requirements to ansible-test's ansible-core distribution info and remove the hardcoded lowerbound/upperbound fallback
|
41
41
|
RESOLVELIB_LOWERBOUND = SemanticVersion("0.5.3")
|
42
|
-
RESOLVELIB_UPPERBOUND = SemanticVersion("
|
42
|
+
RESOLVELIB_UPPERBOUND = SemanticVersion("2.0.0")
|
43
43
|
RESOLVELIB_VERSION = SemanticVersion.from_loose_version(LooseVersion(resolvelib_version))
|
44
44
|
|
45
45
|
|
@@ -5,12 +5,46 @@
|
|
5
5
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
|
+
from collections import defaultdict
|
9
|
+
|
8
10
|
try:
|
9
11
|
from resolvelib import BaseReporter
|
10
12
|
except ImportError:
|
11
13
|
class BaseReporter: # type: ignore[no-redef]
|
12
14
|
pass
|
13
15
|
|
16
|
+
try:
|
17
|
+
from resolvelib.resolvers import Criterion
|
18
|
+
except ImportError:
|
19
|
+
class Criterion: # type: ignore[no-redef]
|
20
|
+
pass
|
21
|
+
|
22
|
+
from ansible.utils.display import Display
|
23
|
+
from .dataclasses import Candidate, Requirement
|
24
|
+
|
25
|
+
|
26
|
+
display = Display()
|
27
|
+
|
28
|
+
|
29
|
+
_CLI_APP_NAME = 'ansible-galaxy'
|
30
|
+
_MESSAGES_AT_REJECT_COUNT = {
|
31
|
+
1: (
|
32
|
+
f'{_CLI_APP_NAME} is looking at multiple versions of {{fqcn}} to '
|
33
|
+
'determine which version is compatible with other '
|
34
|
+
'requirements. This could take a while.'
|
35
|
+
),
|
36
|
+
8: (
|
37
|
+
f'{_CLI_APP_NAME} is looking at multiple versions of {{fqcn}} to '
|
38
|
+
'determine which version is compatible with other '
|
39
|
+
'requirements. This could take a while.'
|
40
|
+
),
|
41
|
+
13: (
|
42
|
+
'This is taking longer than usual. You might need to provide '
|
43
|
+
'the dependency resolver with stricter constraints to reduce '
|
44
|
+
'runtime. If you want to abort this run, press Ctrl + C.'
|
45
|
+
),
|
46
|
+
}
|
47
|
+
|
14
48
|
|
15
49
|
class CollectionDependencyReporter(BaseReporter):
|
16
50
|
"""A dependency reporter for Ansible Collections.
|
@@ -18,3 +52,50 @@ class CollectionDependencyReporter(BaseReporter):
|
|
18
52
|
This is a proxy class allowing us to abstract away importing resolvelib
|
19
53
|
outside of the `ansible.galaxy.dependency_resolution` Python package.
|
20
54
|
"""
|
55
|
+
|
56
|
+
def __init__(self) -> None:
|
57
|
+
"""Initialize the collection rejection counter."""
|
58
|
+
super().__init__()
|
59
|
+
|
60
|
+
self.reject_count_by_fqcn: defaultdict[str, int] = defaultdict(int)
|
61
|
+
|
62
|
+
def _maybe_log_rejection_message(self, candidate: Candidate) -> bool:
|
63
|
+
"""Print out rejection messages on pre-defined limit hits."""
|
64
|
+
# Inspired by https://github.com/pypa/pip/commit/9731131
|
65
|
+
self.reject_count_by_fqcn[candidate.fqcn] += 1
|
66
|
+
|
67
|
+
collection_rejections_count = self.reject_count_by_fqcn[candidate.fqcn]
|
68
|
+
|
69
|
+
if collection_rejections_count not in _MESSAGES_AT_REJECT_COUNT:
|
70
|
+
return False
|
71
|
+
|
72
|
+
collection_rejection_message = _MESSAGES_AT_REJECT_COUNT[
|
73
|
+
collection_rejections_count
|
74
|
+
]
|
75
|
+
display.display(collection_rejection_message.format(fqcn=candidate.fqcn))
|
76
|
+
|
77
|
+
return True
|
78
|
+
|
79
|
+
def rejecting_candidate( # resolvelib >= 0.9.0
|
80
|
+
self,
|
81
|
+
criterion: Criterion[Candidate, Requirement],
|
82
|
+
candidate: Candidate,
|
83
|
+
) -> None:
|
84
|
+
"""Augment rejection messages with conflict details."""
|
85
|
+
if not self._maybe_log_rejection_message(candidate):
|
86
|
+
return
|
87
|
+
|
88
|
+
msg = 'Will try a different candidate, due to conflict:'
|
89
|
+
for req_info in criterion.information:
|
90
|
+
req, parent = req_info.requirement, req_info.parent
|
91
|
+
msg += '\n '
|
92
|
+
if parent:
|
93
|
+
msg += f'{parent !s} depends on '
|
94
|
+
else:
|
95
|
+
msg += 'The user requested '
|
96
|
+
msg += str(req)
|
97
|
+
display.v(msg)
|
98
|
+
|
99
|
+
def backtracking(self, candidate: Candidate) -> None: # resolvelib < 0.9.0
|
100
|
+
"""Print out rejection messages on pre-defined limit hits."""
|
101
|
+
self._maybe_log_rejection_message(candidate)
|
ansible/galaxy/role.py
CHANGED
@@ -185,13 +185,11 @@ class GalaxyRole(object):
|
|
185
185
|
info_path = os.path.join(self.path, self.META_INSTALL)
|
186
186
|
if os.path.isfile(info_path):
|
187
187
|
try:
|
188
|
-
|
189
|
-
|
188
|
+
with open(info_path, 'r') as f:
|
189
|
+
self._install_info = yaml_load(f)
|
190
190
|
except Exception:
|
191
191
|
display.vvvvv("Unable to load Galaxy install info for %s" % self.name)
|
192
192
|
return False
|
193
|
-
finally:
|
194
|
-
f.close()
|
195
193
|
return self._install_info
|
196
194
|
|
197
195
|
@property
|
@@ -470,12 +468,10 @@ class GalaxyRole(object):
|
|
470
468
|
meta_path = os.path.join(self.path, meta_requirements)
|
471
469
|
if os.path.isfile(meta_path):
|
472
470
|
try:
|
473
|
-
|
474
|
-
|
471
|
+
with open(meta_path, 'r') as f:
|
472
|
+
self._requirements = yaml_load(f)
|
475
473
|
except Exception:
|
476
474
|
display.vvvvv("Unable to load requirements for %s" % self.name)
|
477
|
-
finally:
|
478
|
-
f.close()
|
479
475
|
|
480
476
|
break
|
481
477
|
|