ansible-core 2.18.5rc1__py3-none-any.whl → 2.19.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.
- ansible/_internal/__init__.py +53 -0
- ansible/_internal/_ansiballz.py +265 -0
- ansible/_internal/_collection_proxy.py +47 -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 +203 -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 +197 -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 +345 -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 +159 -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 +62 -53
- 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 +166 -112
- 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 +161 -96
- ansible/executor/stats.py +5 -5
- ansible/executor/task_executor.py +268 -258
- ansible/executor/task_queue_manager.py +124 -90
- ansible/executor/task_result.py +183 -78
- 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 +78 -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 +152 -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 +39 -13
- 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 +19 -17
- 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 +6 -6
- 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 +33 -26
- ansible/modules/user.py +53 -34
- ansible/modules/validate_argument_spec.py +10 -7
- ansible/modules/wait_for.py +32 -27
- 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/jsonify.py +5 -1
- 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 +43 -335
- 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 +31 -27
- 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 +7 -6
- 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 +284 -179
- ansible/plugins/callback/default.py +99 -92
- ansible/plugins/callback/junit.py +44 -39
- ansible/plugins/callback/minimal.py +28 -25
- ansible/plugins/callback/oneline.py +28 -21
- ansible/plugins/callback/tree.py +16 -11
- 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 +225 -108
- ansible/plugins/filter/encryption.py +32 -32
- ansible/plugins/filter/flatten.yml +3 -2
- ansible/plugins/filter/human_to_bytes.yml +1 -1
- 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 +159 -184
- ansible/plugins/strategy/debug.py +2 -2
- ansible/plugins/strategy/free.py +16 -31
- ansible/plugins/strategy/host_pinned.py +2 -2
- ansible/plugins/strategy/linear.py +41 -41
- ansible/plugins/terminal/__init__.py +4 -4
- ansible/plugins/test/__init__.py +7 -2
- ansible/plugins/test/core.py +55 -21
- 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 +370 -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 +433 -63
- 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 +51 -8
- ansible/utils/version.py +2 -2
- ansible/vars/clean.py +5 -5
- ansible/vars/hostvars.py +60 -90
- ansible/vars/manager.py +206 -282
- ansible/vars/reserved.py +8 -9
- ansible_core-2.19.0b2.dist-info/BSD-3-Clause.txt +28 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/METADATA +5 -4
- ansible_core-2.19.0b2.dist-info/RECORD +1072 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.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/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.5rc1.dist-info/RECORD +0 -992
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/Apache-License.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/COPYING +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/MIT-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/PSF-license.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/simplified_bsd.txt +0 -0
- {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b2.dist-info}/top_level.txt +0 -0
@@ -26,36 +26,31 @@ import sys
|
|
26
26
|
import threading
|
27
27
|
import time
|
28
28
|
import typing as t
|
29
|
+
import collections.abc as _c
|
29
30
|
|
30
31
|
from collections import deque
|
31
32
|
|
32
33
|
|
33
|
-
from jinja2.exceptions import UndefinedError
|
34
|
-
|
35
34
|
from ansible import constants as C
|
36
35
|
from ansible import context
|
37
|
-
from ansible.errors import AnsibleError, AnsibleFileNotFound,
|
38
|
-
from ansible.executor import action_write_locks
|
36
|
+
from ansible.errors import AnsibleError, AnsibleFileNotFound, AnsibleParserError, AnsibleTemplateError
|
39
37
|
from ansible.executor.play_iterator import IteratingStates, PlayIterator
|
40
38
|
from ansible.executor.process.worker import WorkerProcess
|
41
|
-
from ansible.executor.task_result import
|
42
|
-
from ansible.executor.task_queue_manager import CallbackSend, DisplaySend, PromptSend
|
43
|
-
from ansible.module_utils.six import string_types
|
39
|
+
from ansible.executor.task_result import _RawTaskResult, _WireTaskResult
|
40
|
+
from ansible.executor.task_queue_manager import CallbackSend, DisplaySend, PromptSend, TaskQueueManager
|
44
41
|
from ansible.module_utils.common.text.converters import to_text
|
45
42
|
from ansible.module_utils.connection import Connection, ConnectionError
|
46
|
-
from ansible.playbook.conditional import Conditional
|
47
43
|
from ansible.playbook.handler import Handler
|
48
44
|
from ansible.playbook.helpers import load_list_of_blocks
|
45
|
+
from ansible.playbook.included_file import IncludedFile
|
49
46
|
from ansible.playbook.task import Task
|
50
47
|
from ansible.playbook.task_include import TaskInclude
|
51
48
|
from ansible.plugins import loader as plugin_loader
|
52
|
-
from ansible.
|
49
|
+
from ansible._internal._templating._engine import TemplateEngine
|
53
50
|
from ansible.utils.display import Display
|
54
51
|
from ansible.utils.fqcn import add_internal_fqcns
|
55
|
-
from ansible.utils.unsafe_proxy import wrap_var
|
56
52
|
from ansible.utils.sentinel import Sentinel
|
57
53
|
from ansible.utils.vars import combine_vars
|
58
|
-
from ansible.utils.multiprocessing import context as multiprocessing_context
|
59
54
|
from ansible.vars.clean import strip_internal_keys, module_response_deepcopy
|
60
55
|
|
61
56
|
display = Display()
|
@@ -75,22 +70,8 @@ class StrategySentinel:
|
|
75
70
|
|
76
71
|
_sentinel = StrategySentinel()
|
77
72
|
|
78
|
-
|
79
|
-
|
80
|
-
cond = None
|
81
|
-
if task.changed_when:
|
82
|
-
with templar.set_temporary_context(available_variables=task_vars):
|
83
|
-
cond = Conditional(loader=templar._loader)
|
84
|
-
cond.when = task.changed_when
|
85
|
-
result['changed'] = cond.evaluate_conditional(templar, templar.available_variables)
|
86
|
-
|
87
|
-
if task.failed_when:
|
88
|
-
with templar.set_temporary_context(available_variables=task_vars):
|
89
|
-
if cond is None:
|
90
|
-
cond = Conditional(loader=templar._loader)
|
91
|
-
cond.when = task.failed_when
|
92
|
-
failed_when_result = cond.evaluate_conditional(templar, templar.available_variables)
|
93
|
-
result['failed_when_result'] = result['failed'] = failed_when_result
|
73
|
+
if t.TYPE_CHECKING:
|
74
|
+
from ansible.inventory.host import Host
|
94
75
|
|
95
76
|
|
96
77
|
def _get_item_vars(result, task):
|
@@ -109,7 +90,9 @@ def _get_item_vars(result, task):
|
|
109
90
|
return item_vars
|
110
91
|
|
111
92
|
|
112
|
-
def results_thread_main(strategy):
|
93
|
+
def results_thread_main(strategy: StrategyBase) -> None:
|
94
|
+
value: object
|
95
|
+
|
113
96
|
while True:
|
114
97
|
try:
|
115
98
|
result = strategy._final_q.get()
|
@@ -119,13 +102,10 @@ def results_thread_main(strategy):
|
|
119
102
|
dmethod = getattr(display, result.method)
|
120
103
|
dmethod(*result.args, **result.kwargs)
|
121
104
|
elif isinstance(result, CallbackSend):
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
strategy._tqm.send_callback(result.method_name, *result.args, **result.kwargs)
|
127
|
-
elif isinstance(result, TaskResult):
|
128
|
-
strategy.normalize_task_result(result)
|
105
|
+
task_result = strategy._convert_wire_task_result_to_raw(result.wire_task_result)
|
106
|
+
strategy._tqm.send_callback(result.method_name, task_result)
|
107
|
+
elif isinstance(result, _WireTaskResult):
|
108
|
+
result = strategy._convert_wire_task_result_to_raw(result)
|
129
109
|
with strategy._results_lock:
|
130
110
|
strategy._results.append(result)
|
131
111
|
elif isinstance(result, PromptSend):
|
@@ -157,7 +137,7 @@ def results_thread_main(strategy):
|
|
157
137
|
def debug_closure(func):
|
158
138
|
"""Closure to wrap ``StrategyBase._process_pending_results`` and invoke the task debugger"""
|
159
139
|
@functools.wraps(func)
|
160
|
-
def inner(self, iterator, one_pass=False, max_passes=None):
|
140
|
+
def inner(self, iterator: PlayIterator, one_pass: bool = False, max_passes: int | None = None) -> list[_RawTaskResult]:
|
161
141
|
status_to_stats_map = (
|
162
142
|
('is_failed', 'failures'),
|
163
143
|
('is_unreachable', 'dark'),
|
@@ -168,12 +148,12 @@ def debug_closure(func):
|
|
168
148
|
# We don't know the host yet, copy the previous states, for lookup after we process new results
|
169
149
|
prev_host_states = iterator.host_states.copy()
|
170
150
|
|
171
|
-
results = func(self, iterator, one_pass=one_pass, max_passes=max_passes)
|
172
|
-
_processed_results = []
|
151
|
+
results: list[_RawTaskResult] = func(self, iterator, one_pass=one_pass, max_passes=max_passes)
|
152
|
+
_processed_results: list[_RawTaskResult] = []
|
173
153
|
|
174
154
|
for result in results:
|
175
|
-
task = result.
|
176
|
-
host = result.
|
155
|
+
task = result.task
|
156
|
+
host = result.host
|
177
157
|
_queued_task_args = self._queued_task_cache.pop((host.name, task._uuid), None)
|
178
158
|
task_vars = _queued_task_args['task_vars']
|
179
159
|
play_context = _queued_task_args['play_context']
|
@@ -223,17 +203,17 @@ def debug_closure(func):
|
|
223
203
|
|
224
204
|
class StrategyBase:
|
225
205
|
|
226
|
-
|
206
|
+
"""
|
227
207
|
This is the base class for strategy plugins, which contains some common
|
228
208
|
code useful to all strategies like running handlers, cleanup actions, etc.
|
229
|
-
|
209
|
+
"""
|
230
210
|
|
231
211
|
# by default, strategies should support throttling but we allow individual
|
232
212
|
# strategies to disable this and either forego supporting it or managing
|
233
213
|
# the throttling internally (as `free` does)
|
234
214
|
ALLOW_BASE_THROTTLING = True
|
235
215
|
|
236
|
-
def __init__(self, tqm):
|
216
|
+
def __init__(self, tqm: TaskQueueManager) -> None:
|
237
217
|
self._tqm = tqm
|
238
218
|
self._inventory = tqm.get_inventory()
|
239
219
|
self._workers = tqm._workers
|
@@ -246,7 +226,7 @@ class StrategyBase:
|
|
246
226
|
# the task cache is a dictionary of tuples of (host.name, task._uuid)
|
247
227
|
# used to find the original task object of in-flight tasks and to store
|
248
228
|
# the task args/vars and play context info used to queue the task.
|
249
|
-
self._queued_task_cache = {}
|
229
|
+
self._queued_task_cache: dict[tuple[str, str], dict[str, t.Any]] = {}
|
250
230
|
|
251
231
|
# Backwards compat: self._display isn't really needed, just import the global display and use that.
|
252
232
|
self._display = display
|
@@ -257,13 +237,11 @@ class StrategyBase:
|
|
257
237
|
|
258
238
|
# this dictionary is used to keep track of hosts that have
|
259
239
|
# outstanding tasks still in queue
|
260
|
-
self._blocked_hosts = dict()
|
240
|
+
self._blocked_hosts: dict[str, bool] = dict()
|
261
241
|
|
262
|
-
self._results = deque()
|
242
|
+
self._results: deque[_RawTaskResult] = deque()
|
263
243
|
self._results_lock = threading.Condition(threading.Lock())
|
264
244
|
|
265
|
-
self._worker_queues = dict()
|
266
|
-
|
267
245
|
# create the result processing thread for reading results in the background
|
268
246
|
self._results_thread = threading.Thread(target=results_thread_main, args=(self,))
|
269
247
|
self._results_thread.daemon = True
|
@@ -271,13 +249,13 @@ class StrategyBase:
|
|
271
249
|
|
272
250
|
# holds the list of active (persistent) connections to be shutdown at
|
273
251
|
# play completion
|
274
|
-
self._active_connections = dict()
|
252
|
+
self._active_connections: dict[Host, str] = dict()
|
275
253
|
|
276
254
|
# Caches for get_host calls, to avoid calling excessively
|
277
255
|
# These values should be set at the top of the ``run`` method of each
|
278
256
|
# strategy plugin. Use ``_set_hosts_cache`` to set these values
|
279
|
-
self._hosts_cache = []
|
280
|
-
self._hosts_cache_all = []
|
257
|
+
self._hosts_cache: list[str] = []
|
258
|
+
self._hosts_cache_all: list[str] = []
|
281
259
|
|
282
260
|
self.debugger_active = C.ENABLE_TASK_DEBUGGER
|
283
261
|
|
@@ -289,7 +267,7 @@ class StrategyBase:
|
|
289
267
|
if not refresh and all((self._hosts_cache, self._hosts_cache_all)):
|
290
268
|
return
|
291
269
|
|
292
|
-
if not play.finalized and
|
270
|
+
if not play.finalized and TemplateEngine().is_template(play.hosts):
|
293
271
|
_pattern = 'all'
|
294
272
|
else:
|
295
273
|
_pattern = play.hosts or 'all'
|
@@ -341,40 +319,25 @@ class StrategyBase:
|
|
341
319
|
return [host for host in self._hosts_cache if host in self._tqm._failed_hosts]
|
342
320
|
|
343
321
|
def add_tqm_variables(self, vars, play):
|
344
|
-
|
322
|
+
"""
|
345
323
|
Base class method to add extra variables/information to the list of task
|
346
324
|
vars sent through the executor engine regarding the task queue manager state.
|
347
|
-
|
325
|
+
"""
|
348
326
|
vars['ansible_current_hosts'] = self.get_hosts_remaining(play)
|
349
327
|
vars['ansible_failed_hosts'] = self.get_failed_hosts(play)
|
350
328
|
|
351
329
|
def _queue_task(self, host, task, task_vars, play_context):
|
352
|
-
|
330
|
+
""" handles queueing the task up to be sent to a worker """
|
353
331
|
|
354
332
|
display.debug("entering _queue_task() for %s/%s" % (host.name, task.action))
|
355
333
|
|
356
|
-
# Add a write lock for tasks.
|
357
|
-
# Maybe this should be added somewhere further up the call stack but
|
358
|
-
# this is the earliest in the code where we have task (1) extracted
|
359
|
-
# into its own variable and (2) there's only a single code path
|
360
|
-
# leading to the module being run. This is called by two
|
361
|
-
# functions: linear.py::run(), and
|
362
|
-
# free.py::run() so we'd have to add to both to do it there.
|
363
|
-
# The next common higher level is __init__.py::run() and that has
|
364
|
-
# tasks inside of play_iterator so we'd have to extract them to do it
|
365
|
-
# there.
|
366
|
-
|
367
|
-
if task.action not in action_write_locks.action_write_locks:
|
368
|
-
display.debug('Creating lock for %s' % task.action)
|
369
|
-
action_write_locks.action_write_locks[task.action] = multiprocessing_context.Lock()
|
370
|
-
|
371
334
|
# create a templar and template things we need later for the queuing process
|
372
|
-
templar =
|
335
|
+
templar = TemplateEngine(loader=self._loader, variables=task_vars)
|
373
336
|
|
374
337
|
try:
|
375
338
|
throttle = int(templar.template(task.throttle))
|
376
|
-
except Exception as
|
377
|
-
raise AnsibleError("Failed to convert the throttle value to an integer.", obj=task.
|
339
|
+
except Exception as ex:
|
340
|
+
raise AnsibleError("Failed to convert the throttle value to an integer.", obj=task.throttle) from ex
|
378
341
|
|
379
342
|
# and then queue the new task
|
380
343
|
try:
|
@@ -400,6 +363,8 @@ class StrategyBase:
|
|
400
363
|
|
401
364
|
worker_prc = self._workers[self._cur_worker]
|
402
365
|
if worker_prc is None or not worker_prc.is_alive():
|
366
|
+
if worker_prc:
|
367
|
+
worker_prc.close()
|
403
368
|
self._queued_task_cache[(host.name, task._uuid)] = {
|
404
369
|
'host': host,
|
405
370
|
'task': task,
|
@@ -409,7 +374,16 @@ class StrategyBase:
|
|
409
374
|
|
410
375
|
# Pass WorkerProcess its strategy worker number so it can send an identifier along with intra-task requests
|
411
376
|
worker_prc = WorkerProcess(
|
412
|
-
self._final_q,
|
377
|
+
final_q=self._final_q,
|
378
|
+
task_vars=task_vars,
|
379
|
+
host=host,
|
380
|
+
task=task,
|
381
|
+
play_context=play_context,
|
382
|
+
loader=self._loader,
|
383
|
+
variable_manager=self._variable_manager,
|
384
|
+
shared_loader_obj=plugin_loader.get_plugin_loader_namespace(),
|
385
|
+
worker_id=self._cur_worker,
|
386
|
+
cliargs=context.CLIARGS,
|
413
387
|
)
|
414
388
|
self._workers[self._cur_worker] = worker_prc
|
415
389
|
self._tqm.send_callback('v2_runner_on_start', host, task)
|
@@ -473,69 +447,67 @@ class StrategyBase:
|
|
473
447
|
for target_host in host_list:
|
474
448
|
_set_host_facts(target_host, always_facts)
|
475
449
|
|
476
|
-
def
|
477
|
-
"""
|
478
|
-
|
450
|
+
def _convert_wire_task_result_to_raw(self, wire_task_result: _WireTaskResult) -> _RawTaskResult:
|
451
|
+
"""Return a `_RawTaskResult` created from a `_WireTaskResult`."""
|
452
|
+
host = self._inventory.get_host(wire_task_result.host_name)
|
453
|
+
queue_cache_entry = (host.name, wire_task_result.task_uuid)
|
479
454
|
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
455
|
+
try:
|
456
|
+
found_task = self._queued_task_cache[queue_cache_entry]['task']
|
457
|
+
except KeyError:
|
458
|
+
# This should only happen due to an implicit task created by the
|
459
|
+
# TaskExecutor, restrict this behavior to the explicit use case
|
460
|
+
# of an implicit async_status task
|
461
|
+
if wire_task_result.task_fields.get('action') != 'async_status':
|
462
|
+
raise
|
463
|
+
|
464
|
+
task = Task()
|
465
|
+
else:
|
466
|
+
task = found_task.copy(exclude_parent=True, exclude_tasks=True)
|
467
|
+
task._parent = found_task._parent
|
489
468
|
|
490
|
-
|
491
|
-
# If the value is a string, it is ``Task._uuid``
|
492
|
-
queue_cache_entry = (task_result._host.name, task_result._task)
|
493
|
-
try:
|
494
|
-
found_task = self._queued_task_cache[queue_cache_entry]['task']
|
495
|
-
except KeyError:
|
496
|
-
# This should only happen due to an implicit task created by the
|
497
|
-
# TaskExecutor, restrict this behavior to the explicit use case
|
498
|
-
# of an implicit async_status task
|
499
|
-
if task_result._task_fields.get('action') != 'async_status':
|
500
|
-
raise
|
501
|
-
original_task = Task()
|
502
|
-
else:
|
503
|
-
original_task = found_task.copy(exclude_parent=True, exclude_tasks=True)
|
504
|
-
original_task._parent = found_task._parent
|
505
|
-
original_task.from_attrs(task_result._task_fields)
|
506
|
-
task_result._task = original_task
|
469
|
+
task.from_attrs(wire_task_result.task_fields)
|
507
470
|
|
508
|
-
return
|
471
|
+
return _RawTaskResult(
|
472
|
+
host=host,
|
473
|
+
task=task,
|
474
|
+
return_data=wire_task_result.return_data,
|
475
|
+
task_fields=wire_task_result.task_fields,
|
476
|
+
)
|
509
477
|
|
510
478
|
def search_handlers_by_notification(self, notification: str, iterator: PlayIterator) -> t.Generator[Handler, None, None]:
|
511
|
-
templar = Templar(None)
|
512
479
|
handlers = [h for b in reversed(iterator._play.handlers) for h in b.block]
|
513
480
|
# iterate in reversed order since last handler loaded with the same name wins
|
514
481
|
for handler in handlers:
|
515
482
|
if not handler.name:
|
516
483
|
continue
|
484
|
+
|
517
485
|
if not handler.cached_name:
|
518
|
-
|
519
|
-
|
486
|
+
def variables_factory() -> dict[str, t.Any]:
|
487
|
+
return self._variable_manager.get_vars(
|
520
488
|
play=iterator._play,
|
521
489
|
task=handler,
|
522
490
|
_hosts=self._hosts_cache,
|
523
491
|
_hosts_all=self._hosts_cache_all
|
524
492
|
)
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
493
|
+
|
494
|
+
templar = TemplateEngine(variables_factory=variables_factory)
|
495
|
+
|
496
|
+
try:
|
497
|
+
handler.name = templar.template(handler.name)
|
498
|
+
except AnsibleTemplateError as e:
|
499
|
+
# We skip this handler due to the fact that it may be using
|
500
|
+
# a variable in the name that was conditionally included via
|
501
|
+
# set_fact or some other method, and we don't want to error
|
502
|
+
# out unnecessarily
|
503
|
+
if not handler.listen:
|
504
|
+
display.warning(
|
505
|
+
"Handler '%s' is unusable because it has no listen topics and "
|
506
|
+
"the name could not be templated (host-specific variables are "
|
507
|
+
"not supported in handler names). The error: %s" % (handler.name, to_text(e))
|
508
|
+
)
|
509
|
+
continue
|
510
|
+
|
539
511
|
handler.cached_name = True
|
540
512
|
|
541
513
|
# first we check with the full result of get_name(), which may
|
@@ -559,11 +531,11 @@ class StrategyBase:
|
|
559
531
|
yield handler
|
560
532
|
|
561
533
|
@debug_closure
|
562
|
-
def _process_pending_results(self, iterator, one_pass=False, max_passes=None):
|
563
|
-
|
534
|
+
def _process_pending_results(self, iterator: PlayIterator, one_pass: bool = False, max_passes: int | None = None) -> list[_RawTaskResult]:
|
535
|
+
"""
|
564
536
|
Reads results off the final queue and takes appropriate action
|
565
537
|
based on the result (executing callbacks, updating state, etc.).
|
566
|
-
|
538
|
+
"""
|
567
539
|
ret_results = []
|
568
540
|
cur_pass = 0
|
569
541
|
while True:
|
@@ -575,8 +547,8 @@ class StrategyBase:
|
|
575
547
|
finally:
|
576
548
|
self._results_lock.release()
|
577
549
|
|
578
|
-
original_host = task_result.
|
579
|
-
original_task = task_result.
|
550
|
+
original_host = task_result.host
|
551
|
+
original_task: Task = task_result.task
|
580
552
|
|
581
553
|
# all host status messages contain 2 entries: (msg, task_result)
|
582
554
|
role_ran = False
|
@@ -609,8 +581,8 @@ class StrategyBase:
|
|
609
581
|
self._variable_manager.set_nonpersistent_facts(
|
610
582
|
original_host.name,
|
611
583
|
dict(
|
612
|
-
ansible_failed_task=
|
613
|
-
ansible_failed_result=task_result.
|
584
|
+
ansible_failed_task=original_task.serialize(),
|
585
|
+
ansible_failed_result=task_result._return_data,
|
614
586
|
),
|
615
587
|
)
|
616
588
|
else:
|
@@ -618,7 +590,7 @@ class StrategyBase:
|
|
618
590
|
else:
|
619
591
|
self._tqm._stats.increment('ok', original_host.name)
|
620
592
|
self._tqm._stats.increment('ignored', original_host.name)
|
621
|
-
if
|
593
|
+
if task_result.is_changed():
|
622
594
|
self._tqm._stats.increment('changed', original_host.name)
|
623
595
|
self._tqm.send_callback('v2_runner_on_failed', task_result, ignore_errors=ignore_errors)
|
624
596
|
elif task_result.is_unreachable():
|
@@ -640,9 +612,9 @@ class StrategyBase:
|
|
640
612
|
if original_task.loop:
|
641
613
|
# this task had a loop, and has more than one result, so
|
642
614
|
# loop over all of them instead of a single result
|
643
|
-
result_items = task_result.
|
615
|
+
result_items = task_result._loop_results
|
644
616
|
else:
|
645
|
-
result_items = [task_result.
|
617
|
+
result_items = [task_result._return_data]
|
646
618
|
|
647
619
|
for result_item in result_items:
|
648
620
|
if '_ansible_notify' in result_item and task_result.is_changed():
|
@@ -651,7 +623,7 @@ class StrategyBase:
|
|
651
623
|
# otherwise depending on the setting either error or warn
|
652
624
|
host_state = iterator.get_state_for_host(original_host.name)
|
653
625
|
for notification in result_item['_ansible_notify']:
|
654
|
-
handler = Sentinel
|
626
|
+
handler: type[Sentinel] | Handler = Sentinel
|
655
627
|
for handler in self.search_handlers_by_notification(notification, iterator):
|
656
628
|
if host_state.run_state == IteratingStates.HANDLERS:
|
657
629
|
# we're currently iterating handlers, so we need to expand this now
|
@@ -687,25 +659,32 @@ class StrategyBase:
|
|
687
659
|
|
688
660
|
if 'add_host' in result_item or 'add_group' in result_item:
|
689
661
|
item_vars = _get_item_vars(result_item, original_task)
|
690
|
-
found_task_vars = self._queued_task_cache.get((original_host.name, task_result.
|
662
|
+
found_task_vars = self._queued_task_cache.get((original_host.name, task_result.task._uuid))['task_vars']
|
691
663
|
if item_vars:
|
692
664
|
all_task_vars = combine_vars(found_task_vars, item_vars)
|
693
665
|
else:
|
694
666
|
all_task_vars = found_task_vars
|
695
|
-
all_task_vars[original_task.register] =
|
696
|
-
|
667
|
+
all_task_vars[original_task.register] = result_item
|
668
|
+
|
669
|
+
if original_task.changed_when:
|
670
|
+
result_item['changed'] = original_task._resolve_conditional(original_task.changed_when, all_task_vars)
|
671
|
+
|
672
|
+
if original_task.failed_when:
|
673
|
+
result_item['failed_when_result'] = result_item['failed'] = (
|
674
|
+
original_task._resolve_conditional(original_task.failed_when, all_task_vars))
|
675
|
+
|
697
676
|
if original_task.loop or original_task.loop_with:
|
698
|
-
new_item_result =
|
699
|
-
task_result.
|
700
|
-
task_result.
|
677
|
+
new_item_result = _RawTaskResult(
|
678
|
+
task_result.host,
|
679
|
+
task_result.task,
|
701
680
|
result_item,
|
702
|
-
task_result.
|
681
|
+
task_result.task_fields,
|
703
682
|
)
|
704
683
|
self._tqm.send_callback('v2_runner_item_on_ok', new_item_result)
|
705
684
|
if result_item.get('changed', False):
|
706
|
-
task_result.
|
685
|
+
task_result._return_data['changed'] = True
|
707
686
|
if result_item.get('failed', False):
|
708
|
-
task_result.
|
687
|
+
task_result._return_data['failed'] = True
|
709
688
|
|
710
689
|
if 'ansible_facts' in result_item and original_task.action not in C._ACTION_DEBUG:
|
711
690
|
# if delegated fact and we are delegating facts, we need to change target host for them
|
@@ -753,13 +732,13 @@ class StrategyBase:
|
|
753
732
|
else:
|
754
733
|
self._tqm._stats.set_custom_stats(k, data[k], myhost)
|
755
734
|
|
756
|
-
if 'diff' in task_result.
|
735
|
+
if 'diff' in task_result._return_data:
|
757
736
|
if self._diff or getattr(original_task, 'diff', False):
|
758
737
|
self._tqm.send_callback('v2_on_file_diff', task_result)
|
759
738
|
|
760
739
|
if not isinstance(original_task, TaskInclude):
|
761
740
|
self._tqm._stats.increment('ok', original_host.name)
|
762
|
-
if
|
741
|
+
if task_result.is_changed():
|
763
742
|
self._tqm._stats.increment('changed', original_host.name)
|
764
743
|
|
765
744
|
# finally, send the ok for this task
|
@@ -769,7 +748,7 @@ class StrategyBase:
|
|
769
748
|
if original_task.register:
|
770
749
|
host_list = self.get_task_hosts(iterator, original_host, original_task)
|
771
750
|
|
772
|
-
clean_copy = strip_internal_keys(module_response_deepcopy(task_result.
|
751
|
+
clean_copy = strip_internal_keys(module_response_deepcopy(task_result._return_data))
|
773
752
|
if 'invocation' in clean_copy:
|
774
753
|
del clean_copy['invocation']
|
775
754
|
|
@@ -798,10 +777,10 @@ class StrategyBase:
|
|
798
777
|
return ret_results
|
799
778
|
|
800
779
|
def _wait_on_pending_results(self, iterator):
|
801
|
-
|
780
|
+
"""
|
802
781
|
Wait for the shared counter to drop to zero, using a short sleep
|
803
782
|
between checks to ensure we don't spin lock
|
804
|
-
|
783
|
+
"""
|
805
784
|
|
806
785
|
ret_results = []
|
807
786
|
|
@@ -820,10 +799,10 @@ class StrategyBase:
|
|
820
799
|
|
821
800
|
return ret_results
|
822
801
|
|
823
|
-
def _copy_included_file(self, included_file):
|
824
|
-
|
802
|
+
def _copy_included_file(self, included_file: IncludedFile) -> IncludedFile:
|
803
|
+
"""
|
825
804
|
A proven safe and performant way to create a copy of an included file
|
826
|
-
|
805
|
+
"""
|
827
806
|
ti_copy = included_file._task.copy(exclude_parent=True)
|
828
807
|
ti_copy._parent = included_file._task._parent
|
829
808
|
|
@@ -833,14 +812,14 @@ class StrategyBase:
|
|
833
812
|
|
834
813
|
return ti_copy
|
835
814
|
|
836
|
-
def _load_included_file(self, included_file, iterator, is_handler=False, handle_stats_and_callbacks=True):
|
837
|
-
|
815
|
+
def _load_included_file(self, included_file: IncludedFile, iterator, is_handler=False, handle_stats_and_callbacks=True):
|
816
|
+
"""
|
838
817
|
Loads an included YAML file of tasks, applying the optional set of variables.
|
839
818
|
|
840
819
|
Raises AnsibleError exception in case of a failure during including a file,
|
841
820
|
in such case the caller is responsible for marking the host(s) as failed
|
842
821
|
using PlayIterator.mark_host_failed().
|
843
|
-
|
822
|
+
"""
|
844
823
|
if handle_stats_and_callbacks:
|
845
824
|
display.deprecated(
|
846
825
|
"Reporting play recap stats and running callbacks functionality for "
|
@@ -852,7 +831,7 @@ class StrategyBase:
|
|
852
831
|
)
|
853
832
|
display.debug("loading included file: %s" % included_file._filename)
|
854
833
|
try:
|
855
|
-
data = self._loader.load_from_file(included_file._filename)
|
834
|
+
data = self._loader.load_from_file(included_file._filename, trusted_as_template=True)
|
856
835
|
if data is None:
|
857
836
|
return []
|
858
837
|
elif not isinstance(data, list):
|
@@ -880,11 +859,11 @@ class StrategyBase:
|
|
880
859
|
else:
|
881
860
|
reason = to_text(e)
|
882
861
|
if handle_stats_and_callbacks:
|
883
|
-
for
|
884
|
-
|
862
|
+
for tr in included_file._results:
|
863
|
+
tr._return_data['failed'] = True
|
885
864
|
|
886
865
|
for host in included_file._hosts:
|
887
|
-
tr =
|
866
|
+
tr = _RawTaskResult(host=host, task=included_file._task, return_data=dict(failed=True, reason=reason), task_fields={})
|
888
867
|
self._tqm._stats.increment('failures', host.name)
|
889
868
|
self._tqm.send_callback('v2_runner_on_failed', tr)
|
890
869
|
raise AnsibleError(reason) from e
|
@@ -920,19 +899,19 @@ class StrategyBase:
|
|
920
899
|
def _cond_not_supported_warn(self, task_name):
|
921
900
|
display.warning("%s task does not support when conditional" % task_name)
|
922
901
|
|
923
|
-
def _execute_meta(self, task, play_context, iterator, target_host):
|
902
|
+
def _execute_meta(self, task: Task, play_context, iterator, target_host: Host):
|
903
|
+
task.resolved_action = 'ansible.builtin.meta' # _post_validate_args is never called for meta actions, so resolved_action hasn't been set
|
924
904
|
|
925
905
|
# meta tasks store their args in the _raw_params field of args,
|
926
906
|
# since they do not use k=v pairs, so get that
|
927
|
-
meta_action = task.
|
907
|
+
meta_action = task._get_meta()
|
928
908
|
|
929
|
-
def _evaluate_conditional(
|
909
|
+
def _evaluate_conditional(conditional_host: Host) -> bool:
|
930
910
|
if not task.when:
|
931
911
|
return True
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
return task.evaluate_conditional(templar, all_vars)
|
912
|
+
|
913
|
+
return task._resolve_conditional(task.when, self._variable_manager.get_vars(
|
914
|
+
play=iterator._play, host=conditional_host, task=task, _hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all))
|
936
915
|
|
937
916
|
skipped = False
|
938
917
|
msg = meta_action
|
@@ -1032,7 +1011,7 @@ class StrategyBase:
|
|
1032
1011
|
if _evaluate_conditional(target_host):
|
1033
1012
|
while True:
|
1034
1013
|
state, task = iterator.get_next_task_for_host(target_host, peek=True)
|
1035
|
-
if task.
|
1014
|
+
if task._get_meta() == "role_complete":
|
1036
1015
|
break
|
1037
1016
|
iterator.set_state_for_host(target_host.name, state)
|
1038
1017
|
display.debug("'%s' skipped because role has been ended via 'end_role'" % task)
|
@@ -1043,7 +1022,7 @@ class StrategyBase:
|
|
1043
1022
|
elif meta_action == 'reset_connection':
|
1044
1023
|
all_vars = self._variable_manager.get_vars(play=iterator._play, host=target_host, task=task,
|
1045
1024
|
_hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all)
|
1046
|
-
templar =
|
1025
|
+
templar = TemplateEngine(loader=self._loader, variables=all_vars)
|
1047
1026
|
|
1048
1027
|
# apply the given task's information to the connection info,
|
1049
1028
|
# which may override some fields already set by the play or
|
@@ -1085,33 +1064,29 @@ class StrategyBase:
|
|
1085
1064
|
else:
|
1086
1065
|
raise AnsibleError("invalid meta action requested: %s" % meta_action, obj=task._ds)
|
1087
1066
|
|
1088
|
-
result = {'msg': msg}
|
1067
|
+
result: dict[str, object] = {'msg': msg}
|
1089
1068
|
if skipped:
|
1090
1069
|
result['skipped'] = True
|
1091
1070
|
result['skip_reason'] = skip_reason
|
1092
1071
|
else:
|
1093
1072
|
result['changed'] = False
|
1094
1073
|
|
1095
|
-
if
|
1096
|
-
|
1074
|
+
header = skip_reason if skipped else msg
|
1075
|
+
if task.implicit:
|
1076
|
+
display.debug(f"META: {header}")
|
1077
|
+
else:
|
1097
1078
|
display.vv(f"META: {header}")
|
1098
1079
|
|
1099
|
-
res =
|
1080
|
+
res = _RawTaskResult(target_host, task, result, {})
|
1100
1081
|
if skipped:
|
1101
1082
|
self._tqm.send_callback('v2_runner_on_skipped', res)
|
1102
1083
|
return [res]
|
1103
1084
|
|
1104
1085
|
def _get_cached_role(self, task, play):
|
1105
|
-
|
1106
|
-
role_cache = play.role_cache[role_path]
|
1107
|
-
try:
|
1108
|
-
idx = role_cache.index(task._role)
|
1109
|
-
return role_cache[idx]
|
1110
|
-
except ValueError:
|
1111
|
-
raise AnsibleError(f'Cannot locate {task._role.get_name()} in role cache')
|
1086
|
+
return play._get_cached_role(task._role)
|
1112
1087
|
|
1113
1088
|
def get_hosts_left(self, iterator):
|
1114
|
-
|
1089
|
+
""" returns list of available hosts for this iterator by filtering out unreachables """
|
1115
1090
|
|
1116
1091
|
hosts_left = []
|
1117
1092
|
for host in self._hosts_cache:
|
@@ -1122,14 +1097,14 @@ class StrategyBase:
|
|
1122
1097
|
hosts_left.append(self._inventory.get_host(host))
|
1123
1098
|
return hosts_left
|
1124
1099
|
|
1125
|
-
def update_active_connections(self, results):
|
1126
|
-
|
1100
|
+
def update_active_connections(self, results: _c.Iterable[_RawTaskResult]) -> None:
|
1101
|
+
""" updates the current active persistent connections """
|
1127
1102
|
for r in results:
|
1128
|
-
if 'args' in r.
|
1129
|
-
socket_path = r.
|
1103
|
+
if 'args' in r.task_fields:
|
1104
|
+
socket_path = r.task_fields['args'].get('_ansible_socket')
|
1130
1105
|
if socket_path:
|
1131
|
-
if r.
|
1132
|
-
self._active_connections[r.
|
1106
|
+
if r.host not in self._active_connections:
|
1107
|
+
self._active_connections[r.host] = socket_path
|
1133
1108
|
|
1134
1109
|
|
1135
1110
|
class NextAction(object):
|
@@ -1195,7 +1170,7 @@ class Debugger(cmd.Cmd):
|
|
1195
1170
|
|
1196
1171
|
def do_update_task(self, args):
|
1197
1172
|
"""Recreate the task from ``task._ds``, and template with updated ``task_vars``"""
|
1198
|
-
templar =
|
1173
|
+
templar = TemplateEngine(variables=self.scope['task_vars'])
|
1199
1174
|
task = self.scope['task']
|
1200
1175
|
task = task.load_data(task._ds)
|
1201
1176
|
task.post_validate(templar)
|