ansible-core 2.18.5rc1__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.
Files changed (709) hide show
  1. ansible/_internal/__init__.py +53 -0
  2. ansible/_internal/_ansiballz.py +265 -0
  3. ansible/_internal/_datatag/__init__.py +0 -0
  4. ansible/_internal/_datatag/_tags.py +130 -0
  5. ansible/_internal/_datatag/_utils.py +19 -0
  6. ansible/_internal/_datatag/_wrappers.py +33 -0
  7. ansible/_internal/_errors/__init__.py +0 -0
  8. ansible/_internal/_errors/_captured.py +128 -0
  9. ansible/_internal/_errors/_handler.py +91 -0
  10. ansible/_internal/_errors/_utils.py +310 -0
  11. ansible/_internal/_json/__init__.py +160 -0
  12. ansible/_internal/_json/_legacy_encoder.py +34 -0
  13. ansible/_internal/_json/_profiles/__init__.py +0 -0
  14. ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
  15. ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
  16. ansible/_internal/_json/_profiles/_legacy.py +198 -0
  17. ansible/_internal/_locking.py +21 -0
  18. ansible/_internal/_plugins/__init__.py +0 -0
  19. ansible/_internal/_plugins/_cache.py +57 -0
  20. ansible/_internal/_task.py +78 -0
  21. ansible/_internal/_templating/__init__.py +10 -0
  22. ansible/_internal/_templating/_access.py +86 -0
  23. ansible/_internal/_templating/_chain_templar.py +63 -0
  24. ansible/_internal/_templating/_datatag.py +95 -0
  25. ansible/_internal/_templating/_engine.py +588 -0
  26. ansible/_internal/_templating/_errors.py +28 -0
  27. ansible/_internal/_templating/_jinja_bits.py +1066 -0
  28. ansible/_internal/_templating/_jinja_common.py +332 -0
  29. ansible/_internal/_templating/_jinja_patches.py +44 -0
  30. ansible/_internal/_templating/_jinja_plugins.py +351 -0
  31. ansible/_internal/_templating/_lazy_containers.py +633 -0
  32. ansible/_internal/_templating/_marker_behaviors.py +103 -0
  33. ansible/_internal/_templating/_transform.py +63 -0
  34. ansible/_internal/_templating/_utils.py +107 -0
  35. ansible/_internal/_wrapt.py +1052 -0
  36. ansible/_internal/_yaml/__init__.py +0 -0
  37. ansible/_internal/_yaml/_constructor.py +240 -0
  38. ansible/_internal/_yaml/_dumper.py +62 -0
  39. ansible/_internal/_yaml/_errors.py +166 -0
  40. ansible/_internal/_yaml/_loader.py +66 -0
  41. ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
  42. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
  43. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
  44. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
  45. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
  46. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
  47. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
  48. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
  49. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
  50. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
  51. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
  52. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
  53. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
  54. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
  55. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
  56. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
  57. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
  58. ansible/cli/__init__.py +153 -89
  59. ansible/cli/_ssh_askpass.py +47 -0
  60. ansible/cli/adhoc.py +14 -7
  61. ansible/cli/arguments/option_helpers.py +154 -7
  62. ansible/cli/config.py +43 -68
  63. ansible/cli/console.py +10 -8
  64. ansible/cli/doc.py +48 -46
  65. ansible/cli/galaxy.py +27 -20
  66. ansible/cli/inventory.py +28 -26
  67. ansible/cli/playbook.py +4 -12
  68. ansible/cli/pull.py +51 -11
  69. ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
  70. ansible/cli/vault.py +12 -11
  71. ansible/compat/__init__.py +2 -2
  72. ansible/config/base.yml +165 -108
  73. ansible/config/manager.py +52 -49
  74. ansible/constants.py +3 -4
  75. ansible/errors/__init__.py +277 -235
  76. ansible/executor/interpreter_discovery.py +28 -149
  77. ansible/executor/module_common.py +426 -493
  78. ansible/executor/play_iterator.py +22 -27
  79. ansible/executor/playbook_executor.py +11 -11
  80. ansible/executor/powershell/async_watchdog.ps1 +97 -102
  81. ansible/executor/powershell/async_wrapper.ps1 +202 -151
  82. ansible/executor/powershell/become_wrapper.ps1 +89 -144
  83. ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
  84. ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
  85. ansible/executor/powershell/exec_wrapper.ps1 +462 -196
  86. ansible/executor/powershell/module_manifest.py +417 -265
  87. ansible/executor/powershell/module_wrapper.ps1 +169 -186
  88. ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
  89. ansible/executor/powershell/psrp_put_file.ps1 +122 -0
  90. ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
  91. ansible/executor/powershell/winrm_put_file.ps1 +36 -0
  92. ansible/executor/process/worker.py +136 -76
  93. ansible/executor/stats.py +5 -5
  94. ansible/executor/task_executor.py +237 -236
  95. ansible/executor/task_queue_manager.py +62 -38
  96. ansible/executor/task_result.py +21 -12
  97. ansible/galaxy/__init__.py +2 -2
  98. ansible/galaxy/api.py +22 -18
  99. ansible/galaxy/collection/__init__.py +1 -1
  100. ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
  101. ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
  102. ansible/galaxy/dependency_resolution/providers.py +1 -1
  103. ansible/galaxy/dependency_resolution/reporters.py +81 -0
  104. ansible/galaxy/role.py +4 -8
  105. ansible/galaxy/token.py +28 -21
  106. ansible/inventory/data.py +47 -57
  107. ansible/inventory/group.py +44 -72
  108. ansible/inventory/helpers.py +9 -0
  109. ansible/inventory/host.py +32 -54
  110. ansible/inventory/manager.py +77 -34
  111. ansible/keyword_desc.yml +1 -1
  112. ansible/module_utils/_internal/__init__.py +55 -0
  113. ansible/module_utils/_internal/_ambient_context.py +58 -0
  114. ansible/module_utils/_internal/_ansiballz.py +133 -0
  115. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
  116. ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
  117. ansible/module_utils/_internal/_dataclass_validation.py +217 -0
  118. ansible/module_utils/_internal/_datatag/__init__.py +928 -0
  119. ansible/module_utils/_internal/_datatag/_tags.py +38 -0
  120. ansible/module_utils/_internal/_debugging.py +31 -0
  121. ansible/module_utils/_internal/_errors.py +30 -0
  122. ansible/module_utils/_internal/_json/__init__.py +63 -0
  123. ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
  124. ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
  125. ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
  126. ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
  127. ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
  128. ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
  129. ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
  130. ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
  131. ansible/module_utils/_internal/_patches/__init__.py +66 -0
  132. ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
  133. ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
  134. ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
  135. ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
  136. ansible/module_utils/_internal/_testing.py +0 -0
  137. ansible/module_utils/_internal/_traceback.py +89 -0
  138. ansible/module_utils/ansible_release.py +2 -2
  139. ansible/module_utils/api.py +1 -2
  140. ansible/module_utils/basic.py +154 -120
  141. ansible/module_utils/common/_utils.py +24 -28
  142. ansible/module_utils/common/collections.py +1 -2
  143. ansible/module_utils/common/dict_transformations.py +2 -2
  144. ansible/module_utils/common/file.py +2 -2
  145. ansible/module_utils/common/json.py +90 -84
  146. ansible/module_utils/common/locale.py +2 -2
  147. ansible/module_utils/common/messages.py +108 -0
  148. ansible/module_utils/common/parameters.py +27 -24
  149. ansible/module_utils/common/process.py +2 -2
  150. ansible/module_utils/common/respawn.py +41 -19
  151. ansible/module_utils/common/sentinel.py +66 -0
  152. ansible/module_utils/common/sys_info.py +8 -8
  153. ansible/module_utils/common/text/converters.py +16 -37
  154. ansible/module_utils/common/validation.py +35 -24
  155. ansible/module_utils/common/warnings.py +86 -25
  156. ansible/module_utils/common/yaml.py +29 -3
  157. ansible/module_utils/compat/datetime.py +33 -21
  158. ansible/module_utils/compat/paramiko.py +21 -10
  159. ansible/module_utils/compat/typing.py +6 -5
  160. ansible/module_utils/connection.py +2 -2
  161. ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
  162. ansible/module_utils/csharp/Ansible.Become.cs +1 -0
  163. ansible/module_utils/csharp/Ansible._Async.cs +517 -0
  164. ansible/module_utils/datatag.py +46 -0
  165. ansible/module_utils/distro/__init__.py +2 -2
  166. ansible/module_utils/facts/ansible_collector.py +4 -5
  167. ansible/module_utils/facts/collector.py +13 -14
  168. ansible/module_utils/facts/compat.py +4 -4
  169. ansible/module_utils/facts/default_collectors.py +1 -1
  170. ansible/module_utils/facts/hardware/aix.py +34 -0
  171. ansible/module_utils/facts/hardware/base.py +1 -1
  172. ansible/module_utils/facts/hardware/darwin.py +1 -3
  173. ansible/module_utils/facts/hardware/freebsd.py +2 -2
  174. ansible/module_utils/facts/hardware/linux.py +4 -4
  175. ansible/module_utils/facts/namespace.py +1 -1
  176. ansible/module_utils/facts/network/base.py +1 -1
  177. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  178. ansible/module_utils/facts/network/iscsi.py +1 -2
  179. ansible/module_utils/facts/network/nvme.py +1 -2
  180. ansible/module_utils/facts/other/facter.py +1 -2
  181. ansible/module_utils/facts/other/ohai.py +2 -3
  182. ansible/module_utils/facts/system/apparmor.py +1 -2
  183. ansible/module_utils/facts/system/caps.py +1 -1
  184. ansible/module_utils/facts/system/chroot.py +1 -2
  185. ansible/module_utils/facts/system/cmdline.py +1 -2
  186. ansible/module_utils/facts/system/date_time.py +5 -3
  187. ansible/module_utils/facts/system/distribution.py +9 -8
  188. ansible/module_utils/facts/system/dns.py +1 -1
  189. ansible/module_utils/facts/system/env.py +1 -2
  190. ansible/module_utils/facts/system/fips.py +7 -20
  191. ansible/module_utils/facts/system/loadavg.py +1 -2
  192. ansible/module_utils/facts/system/local.py +1 -2
  193. ansible/module_utils/facts/system/lsb.py +1 -2
  194. ansible/module_utils/facts/system/pkg_mgr.py +1 -2
  195. ansible/module_utils/facts/system/platform.py +1 -2
  196. ansible/module_utils/facts/system/python.py +1 -2
  197. ansible/module_utils/facts/system/selinux.py +1 -1
  198. ansible/module_utils/facts/system/service_mgr.py +1 -2
  199. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
  200. ansible/module_utils/facts/system/systemd.py +1 -1
  201. ansible/module_utils/facts/system/user.py +1 -2
  202. ansible/module_utils/facts/utils.py +3 -3
  203. ansible/module_utils/facts/virtual/base.py +1 -1
  204. ansible/module_utils/facts/virtual/sunos.py +3 -15
  205. ansible/module_utils/facts/virtual/sysctl.py +3 -16
  206. ansible/module_utils/json_utils.py +2 -2
  207. ansible/module_utils/parsing/convert_bool.py +1 -1
  208. ansible/module_utils/service.py +18 -21
  209. ansible/module_utils/splitter.py +7 -7
  210. ansible/module_utils/testing.py +31 -0
  211. ansible/module_utils/urls.py +60 -31
  212. ansible/modules/add_host.py +4 -4
  213. ansible/modules/apt.py +60 -46
  214. ansible/modules/apt_key.py +19 -12
  215. ansible/modules/apt_repository.py +19 -16
  216. ansible/modules/assemble.py +6 -6
  217. ansible/modules/assert.py +4 -4
  218. ansible/modules/async_status.py +10 -12
  219. ansible/modules/async_wrapper.py +8 -3
  220. ansible/modules/blockinfile.py +6 -7
  221. ansible/modules/command.py +10 -17
  222. ansible/modules/copy.py +57 -144
  223. ansible/modules/cron.py +20 -15
  224. ansible/modules/deb822_repository.py +8 -9
  225. ansible/modules/debconf.py +5 -5
  226. ansible/modules/debug.py +4 -4
  227. ansible/modules/dnf.py +8 -8
  228. ansible/modules/dnf5.py +39 -13
  229. ansible/modules/dpkg_selections.py +4 -4
  230. ansible/modules/expect.py +8 -10
  231. ansible/modules/fail.py +4 -4
  232. ansible/modules/fetch.py +4 -4
  233. ansible/modules/file.py +174 -133
  234. ansible/modules/find.py +19 -17
  235. ansible/modules/gather_facts.py +3 -3
  236. ansible/modules/get_url.py +59 -53
  237. ansible/modules/getent.py +7 -9
  238. ansible/modules/git.py +28 -25
  239. ansible/modules/group.py +6 -6
  240. ansible/modules/group_by.py +4 -4
  241. ansible/modules/hostname.py +13 -29
  242. ansible/modules/import_playbook.py +6 -6
  243. ansible/modules/import_role.py +6 -6
  244. ansible/modules/import_tasks.py +6 -6
  245. ansible/modules/include_role.py +6 -6
  246. ansible/modules/include_tasks.py +6 -6
  247. ansible/modules/include_vars.py +6 -6
  248. ansible/modules/iptables.py +86 -73
  249. ansible/modules/known_hosts.py +10 -10
  250. ansible/modules/lineinfile.py +5 -5
  251. ansible/modules/meta.py +4 -4
  252. ansible/modules/mount_facts.py +2 -2
  253. ansible/modules/package.py +4 -4
  254. ansible/modules/package_facts.py +22 -10
  255. ansible/modules/pause.py +6 -6
  256. ansible/modules/ping.py +6 -6
  257. ansible/modules/pip.py +10 -11
  258. ansible/modules/raw.py +4 -4
  259. ansible/modules/reboot.py +6 -6
  260. ansible/modules/replace.py +9 -13
  261. ansible/modules/rpm_key.py +7 -8
  262. ansible/modules/script.py +4 -4
  263. ansible/modules/service.py +7 -8
  264. ansible/modules/service_facts.py +87 -10
  265. ansible/modules/set_fact.py +5 -5
  266. ansible/modules/set_stats.py +4 -4
  267. ansible/modules/setup.py +2 -2
  268. ansible/modules/shell.py +6 -6
  269. ansible/modules/slurp.py +6 -6
  270. ansible/modules/stat.py +9 -23
  271. ansible/modules/subversion.py +15 -15
  272. ansible/modules/systemd.py +6 -6
  273. ansible/modules/systemd_service.py +6 -6
  274. ansible/modules/sysvinit.py +6 -6
  275. ansible/modules/tempfile.py +5 -6
  276. ansible/modules/template.py +6 -6
  277. ansible/modules/unarchive.py +32 -11
  278. ansible/modules/uri.py +33 -26
  279. ansible/modules/user.py +53 -34
  280. ansible/modules/validate_argument_spec.py +10 -7
  281. ansible/modules/wait_for.py +32 -27
  282. ansible/modules/wait_for_connection.py +6 -6
  283. ansible/modules/yum_repository.py +6 -6
  284. ansible/parsing/ajson.py +14 -32
  285. ansible/parsing/dataloader.py +99 -54
  286. ansible/parsing/mod_args.py +28 -44
  287. ansible/parsing/plugin_docs.py +21 -86
  288. ansible/parsing/quoting.py +1 -1
  289. ansible/parsing/splitter.py +27 -12
  290. ansible/parsing/utils/addresses.py +24 -24
  291. ansible/parsing/utils/yaml.py +32 -61
  292. ansible/parsing/vault/__init__.py +319 -87
  293. ansible/parsing/yaml/__init__.py +0 -18
  294. ansible/parsing/yaml/dumper.py +6 -120
  295. ansible/parsing/yaml/loader.py +6 -39
  296. ansible/parsing/yaml/objects.py +36 -339
  297. ansible/playbook/__init__.py +1 -1
  298. ansible/playbook/attribute.py +8 -3
  299. ansible/playbook/base.py +182 -132
  300. ansible/playbook/block.py +26 -24
  301. ansible/playbook/collectionsearch.py +1 -15
  302. ansible/playbook/conditional.py +3 -77
  303. ansible/playbook/handler.py +8 -2
  304. ansible/playbook/helpers.py +41 -53
  305. ansible/playbook/included_file.py +6 -15
  306. ansible/playbook/loop_control.py +2 -2
  307. ansible/playbook/play.py +85 -44
  308. ansible/playbook/play_context.py +12 -17
  309. ansible/playbook/playbook_include.py +14 -15
  310. ansible/playbook/role/__init__.py +24 -26
  311. ansible/playbook/role/definition.py +15 -17
  312. ansible/playbook/role/include.py +2 -4
  313. ansible/playbook/role/metadata.py +10 -11
  314. ansible/playbook/role_include.py +3 -3
  315. ansible/playbook/taggable.py +13 -8
  316. ansible/playbook/task.py +188 -118
  317. ansible/playbook/task_include.py +5 -5
  318. ansible/plugins/__init__.py +68 -21
  319. ansible/plugins/action/__init__.py +209 -176
  320. ansible/plugins/action/add_host.py +1 -1
  321. ansible/plugins/action/assemble.py +1 -1
  322. ansible/plugins/action/assert.py +54 -66
  323. ansible/plugins/action/copy.py +7 -11
  324. ansible/plugins/action/debug.py +37 -31
  325. ansible/plugins/action/dnf.py +3 -4
  326. ansible/plugins/action/fail.py +1 -1
  327. ansible/plugins/action/fetch.py +4 -5
  328. ansible/plugins/action/gather_facts.py +7 -6
  329. ansible/plugins/action/group_by.py +1 -1
  330. ansible/plugins/action/include_vars.py +10 -11
  331. ansible/plugins/action/package.py +3 -6
  332. ansible/plugins/action/pause.py +2 -2
  333. ansible/plugins/action/script.py +15 -8
  334. ansible/plugins/action/service.py +6 -11
  335. ansible/plugins/action/set_fact.py +3 -12
  336. ansible/plugins/action/set_stats.py +3 -8
  337. ansible/plugins/action/template.py +35 -59
  338. ansible/plugins/action/unarchive.py +1 -1
  339. ansible/plugins/action/validate_argument_spec.py +5 -5
  340. ansible/plugins/action/wait_for_connection.py +1 -1
  341. ansible/plugins/become/__init__.py +31 -8
  342. ansible/plugins/become/runas.py +71 -0
  343. ansible/plugins/become/su.py +13 -8
  344. ansible/plugins/become/sudo.py +19 -0
  345. ansible/plugins/cache/__init__.py +35 -44
  346. ansible/plugins/cache/base.py +8 -0
  347. ansible/plugins/cache/jsonfile.py +10 -16
  348. ansible/plugins/cache/memory.py +6 -12
  349. ansible/plugins/callback/__init__.py +141 -123
  350. ansible/plugins/callback/default.py +30 -23
  351. ansible/plugins/callback/junit.py +28 -24
  352. ansible/plugins/callback/minimal.py +17 -14
  353. ansible/plugins/callback/oneline.py +13 -7
  354. ansible/plugins/callback/tree.py +10 -6
  355. ansible/plugins/connection/__init__.py +47 -34
  356. ansible/plugins/connection/local.py +150 -54
  357. ansible/plugins/connection/paramiko_ssh.py +21 -18
  358. ansible/plugins/connection/psrp.py +76 -165
  359. ansible/plugins/connection/ssh.py +301 -78
  360. ansible/plugins/connection/winrm.py +58 -140
  361. ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
  362. ansible/plugins/doc_fragments/action_core.py +6 -6
  363. ansible/plugins/doc_fragments/backup.py +2 -2
  364. ansible/plugins/doc_fragments/checksum_common.py +27 -0
  365. ansible/plugins/doc_fragments/constructed.py +6 -2
  366. ansible/plugins/doc_fragments/decrypt.py +2 -2
  367. ansible/plugins/doc_fragments/default_callback.py +2 -2
  368. ansible/plugins/doc_fragments/files.py +2 -2
  369. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  370. ansible/plugins/doc_fragments/result_format_callback.py +2 -2
  371. ansible/plugins/doc_fragments/return_common.py +2 -2
  372. ansible/plugins/doc_fragments/template_common.py +4 -4
  373. ansible/plugins/doc_fragments/url.py +17 -1
  374. ansible/plugins/doc_fragments/url_windows.py +2 -2
  375. ansible/plugins/doc_fragments/validate.py +2 -2
  376. ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
  377. ansible/plugins/filter/__init__.py +6 -2
  378. ansible/plugins/filter/b64decode.yml +22 -0
  379. ansible/plugins/filter/b64encode.yml +22 -0
  380. ansible/plugins/filter/bool.yml +11 -4
  381. ansible/plugins/filter/core.py +218 -108
  382. ansible/plugins/filter/encryption.py +32 -32
  383. ansible/plugins/filter/flatten.yml +3 -2
  384. ansible/plugins/filter/human_to_bytes.yml +1 -1
  385. ansible/plugins/filter/mathstuff.py +30 -37
  386. ansible/plugins/filter/password_hash.yml +8 -0
  387. ansible/plugins/filter/regex_search.yml +1 -4
  388. ansible/plugins/filter/split.yml +1 -1
  389. ansible/plugins/filter/to_nice_yaml.yml +0 -4
  390. ansible/plugins/filter/to_yaml.yml +0 -4
  391. ansible/plugins/filter/unvault.yml +1 -1
  392. ansible/plugins/filter/urls.py +1 -1
  393. ansible/plugins/filter/urlsplit.py +8 -9
  394. ansible/plugins/filter/vault.yml +14 -9
  395. ansible/plugins/filter/win_basename.yml +6 -1
  396. ansible/plugins/filter/win_dirname.yml +5 -0
  397. ansible/plugins/inventory/__init__.py +97 -77
  398. ansible/plugins/inventory/advanced_host_list.py +7 -5
  399. ansible/plugins/inventory/auto.py +11 -4
  400. ansible/plugins/inventory/constructed.py +21 -24
  401. ansible/plugins/inventory/generator.py +16 -11
  402. ansible/plugins/inventory/host_list.py +7 -5
  403. ansible/plugins/inventory/ini.py +78 -44
  404. ansible/plugins/inventory/script.py +189 -119
  405. ansible/plugins/inventory/toml.py +16 -126
  406. ansible/plugins/inventory/yaml.py +10 -8
  407. ansible/plugins/list.py +3 -3
  408. ansible/plugins/loader.py +197 -82
  409. ansible/plugins/lookup/__init__.py +21 -4
  410. ansible/plugins/lookup/config.py +21 -35
  411. ansible/plugins/lookup/csvfile.py +3 -2
  412. ansible/plugins/lookup/dict.py +1 -6
  413. ansible/plugins/lookup/env.py +12 -9
  414. ansible/plugins/lookup/file.py +5 -8
  415. ansible/plugins/lookup/first_found.py +86 -55
  416. ansible/plugins/lookup/indexed_items.py +1 -10
  417. ansible/plugins/lookup/ini.py +14 -13
  418. ansible/plugins/lookup/items.py +1 -1
  419. ansible/plugins/lookup/lines.py +8 -1
  420. ansible/plugins/lookup/list.py +1 -1
  421. ansible/plugins/lookup/nested.py +2 -18
  422. ansible/plugins/lookup/password.py +5 -5
  423. ansible/plugins/lookup/pipe.py +5 -7
  424. ansible/plugins/lookup/sequence.py +18 -8
  425. ansible/plugins/lookup/subelements.py +1 -4
  426. ansible/plugins/lookup/template.py +42 -36
  427. ansible/plugins/lookup/together.py +0 -12
  428. ansible/plugins/lookup/unvault.py +1 -5
  429. ansible/plugins/lookup/url.py +2 -8
  430. ansible/plugins/lookup/vars.py +16 -24
  431. ansible/plugins/shell/__init__.py +2 -2
  432. ansible/plugins/shell/cmd.py +2 -2
  433. ansible/plugins/shell/powershell.py +39 -22
  434. ansible/plugins/shell/sh.py +3 -2
  435. ansible/plugins/strategy/__init__.py +94 -113
  436. ansible/plugins/strategy/debug.py +2 -2
  437. ansible/plugins/strategy/free.py +13 -28
  438. ansible/plugins/strategy/host_pinned.py +2 -2
  439. ansible/plugins/strategy/linear.py +31 -33
  440. ansible/plugins/terminal/__init__.py +4 -4
  441. ansible/plugins/test/__init__.py +7 -2
  442. ansible/plugins/test/core.py +54 -20
  443. ansible/plugins/test/files.py +1 -1
  444. ansible/plugins/test/mathstuff.py +3 -3
  445. ansible/plugins/test/uri.py +3 -3
  446. ansible/plugins/vars/host_group_vars.py +7 -14
  447. ansible/release.py +2 -2
  448. ansible/template/__init__.py +368 -944
  449. ansible/utils/__init__.py +0 -18
  450. ansible/utils/_ssh_agent.py +657 -0
  451. ansible/utils/collection_loader/__init__.py +52 -5
  452. ansible/utils/collection_loader/_collection_config.py +5 -6
  453. ansible/utils/collection_loader/_collection_finder.py +79 -93
  454. ansible/utils/collection_loader/_collection_meta.py +13 -8
  455. ansible/utils/display.py +428 -58
  456. ansible/utils/encrypt.py +27 -19
  457. ansible/utils/fqcn.py +2 -2
  458. ansible/utils/hashing.py +2 -2
  459. ansible/utils/helpers.py +2 -2
  460. ansible/utils/listify.py +8 -8
  461. ansible/utils/lock.py +2 -2
  462. ansible/utils/path.py +4 -4
  463. ansible/utils/plugin_docs.py +14 -13
  464. ansible/utils/sentinel.py +4 -62
  465. ansible/utils/singleton.py +2 -0
  466. ansible/utils/ssh_functions.py +1 -1
  467. ansible/utils/unsafe_proxy.py +23 -332
  468. ansible/utils/vars.py +28 -8
  469. ansible/utils/version.py +2 -2
  470. ansible/vars/clean.py +4 -4
  471. ansible/vars/hostvars.py +60 -90
  472. ansible/vars/manager.py +205 -264
  473. ansible/vars/reserved.py +8 -9
  474. ansible_core-2.19.0b1.dist-info/BSD-3-Clause.txt +28 -0
  475. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/METADATA +5 -4
  476. ansible_core-2.19.0b1.dist-info/RECORD +1070 -0
  477. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/WHEEL +1 -1
  478. ansible_test/_data/completion/docker.txt +7 -7
  479. ansible_test/_data/completion/remote.txt +6 -6
  480. ansible_test/_data/completion/windows.txt +1 -0
  481. ansible_test/_data/requirements/ansible.txt +2 -2
  482. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  483. ansible_test/_data/requirements/sanity.changelog.txt +1 -1
  484. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  485. ansible_test/_data/requirements/sanity.pylint.txt +4 -4
  486. ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
  487. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  488. ansible_test/_data/requirements/units.txt +1 -0
  489. ansible_test/_internal/__init__.py +1 -0
  490. ansible_test/_internal/ansible_util.py +2 -0
  491. ansible_test/_internal/become.py +1 -0
  492. ansible_test/_internal/bootstrap.py +1 -0
  493. ansible_test/_internal/cache.py +1 -0
  494. ansible_test/_internal/cgroup.py +1 -0
  495. ansible_test/_internal/ci/__init__.py +1 -0
  496. ansible_test/_internal/ci/azp.py +1 -0
  497. ansible_test/_internal/ci/local.py +1 -0
  498. ansible_test/_internal/classification/__init__.py +1 -0
  499. ansible_test/_internal/classification/common.py +1 -0
  500. ansible_test/_internal/classification/csharp.py +1 -0
  501. ansible_test/_internal/classification/powershell.py +1 -0
  502. ansible_test/_internal/classification/python.py +1 -0
  503. ansible_test/_internal/cli/__init__.py +1 -0
  504. ansible_test/_internal/cli/actions.py +1 -0
  505. ansible_test/_internal/cli/argparsing/__init__.py +1 -0
  506. ansible_test/_internal/cli/argparsing/actions.py +1 -0
  507. ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
  508. ansible_test/_internal/cli/argparsing/parsers.py +1 -0
  509. ansible_test/_internal/cli/commands/__init__.py +11 -0
  510. ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
  511. ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
  512. ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
  513. ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
  514. ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
  515. ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
  516. ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
  517. ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
  518. ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
  519. ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
  520. ansible_test/_internal/cli/commands/coverage/html.py +1 -0
  521. ansible_test/_internal/cli/commands/coverage/report.py +1 -0
  522. ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
  523. ansible_test/_internal/cli/commands/env.py +1 -0
  524. ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
  525. ansible_test/_internal/cli/commands/integration/network.py +1 -0
  526. ansible_test/_internal/cli/commands/integration/posix.py +1 -0
  527. ansible_test/_internal/cli/commands/integration/windows.py +1 -0
  528. ansible_test/_internal/cli/commands/sanity.py +9 -0
  529. ansible_test/_internal/cli/commands/shell.py +1 -0
  530. ansible_test/_internal/cli/commands/units.py +1 -0
  531. ansible_test/_internal/cli/compat.py +1 -0
  532. ansible_test/_internal/cli/completers.py +1 -0
  533. ansible_test/_internal/cli/converters.py +1 -0
  534. ansible_test/_internal/cli/environments.py +1 -0
  535. ansible_test/_internal/cli/epilog.py +1 -0
  536. ansible_test/_internal/cli/parsers/__init__.py +1 -0
  537. ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
  538. ansible_test/_internal/cli/parsers/helpers.py +1 -0
  539. ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
  540. ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
  541. ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
  542. ansible_test/_internal/commands/__init__.py +1 -0
  543. ansible_test/_internal/commands/coverage/__init__.py +2 -1
  544. ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
  545. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
  546. ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
  547. ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
  548. ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
  549. ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
  550. ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
  551. ansible_test/_internal/commands/coverage/combine.py +2 -1
  552. ansible_test/_internal/commands/coverage/erase.py +1 -0
  553. ansible_test/_internal/commands/coverage/html.py +1 -0
  554. ansible_test/_internal/commands/coverage/report.py +1 -0
  555. ansible_test/_internal/commands/coverage/xml.py +1 -0
  556. ansible_test/_internal/commands/env/__init__.py +2 -0
  557. ansible_test/_internal/commands/integration/__init__.py +4 -0
  558. ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
  559. ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
  560. ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
  561. ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
  562. ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
  563. ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
  564. ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
  565. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
  566. ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
  567. ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
  568. ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
  569. ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
  570. ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
  571. ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
  572. ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
  573. ansible_test/_internal/commands/integration/coverage.py +1 -0
  574. ansible_test/_internal/commands/integration/filters.py +1 -0
  575. ansible_test/_internal/commands/integration/network.py +1 -0
  576. ansible_test/_internal/commands/integration/posix.py +1 -0
  577. ansible_test/_internal/commands/integration/windows.py +1 -0
  578. ansible_test/_internal/commands/sanity/__init__.py +16 -1
  579. ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
  580. ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
  581. ansible_test/_internal/commands/sanity/compile.py +1 -0
  582. ansible_test/_internal/commands/sanity/ignores.py +1 -0
  583. ansible_test/_internal/commands/sanity/import.py +1 -0
  584. ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
  585. ansible_test/_internal/commands/sanity/pep8.py +1 -0
  586. ansible_test/_internal/commands/sanity/pslint.py +1 -0
  587. ansible_test/_internal/commands/sanity/pylint.py +24 -26
  588. ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
  589. ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
  590. ansible_test/_internal/commands/sanity/yamllint.py +1 -0
  591. ansible_test/_internal/commands/shell/__init__.py +1 -0
  592. ansible_test/_internal/commands/units/__init__.py +1 -0
  593. ansible_test/_internal/compat/__init__.py +1 -0
  594. ansible_test/_internal/compat/packaging.py +1 -0
  595. ansible_test/_internal/compat/yaml.py +1 -0
  596. ansible_test/_internal/completion.py +1 -0
  597. ansible_test/_internal/config.py +2 -0
  598. ansible_test/_internal/connections.py +1 -0
  599. ansible_test/_internal/constants.py +1 -0
  600. ansible_test/_internal/containers.py +1 -0
  601. ansible_test/_internal/content_config.py +1 -0
  602. ansible_test/_internal/core_ci.py +1 -0
  603. ansible_test/_internal/coverage_util.py +11 -10
  604. ansible_test/_internal/data.py +1 -0
  605. ansible_test/_internal/delegation.py +1 -0
  606. ansible_test/_internal/dev/__init__.py +1 -0
  607. ansible_test/_internal/dev/container_probe.py +1 -0
  608. ansible_test/_internal/diff.py +3 -2
  609. ansible_test/_internal/docker_util.py +2 -1
  610. ansible_test/_internal/encoding.py +1 -0
  611. ansible_test/_internal/executor.py +1 -0
  612. ansible_test/_internal/git.py +1 -0
  613. ansible_test/_internal/host_configs.py +1 -0
  614. ansible_test/_internal/host_profiles.py +1 -0
  615. ansible_test/_internal/http.py +1 -0
  616. ansible_test/_internal/init.py +1 -0
  617. ansible_test/_internal/inventory.py +35 -3
  618. ansible_test/_internal/io.py +1 -0
  619. ansible_test/_internal/metadata.py +1 -0
  620. ansible_test/_internal/payload.py +1 -0
  621. ansible_test/_internal/provider/__init__.py +1 -0
  622. ansible_test/_internal/provider/layout/__init__.py +1 -0
  623. ansible_test/_internal/provider/layout/ansible.py +1 -0
  624. ansible_test/_internal/provider/layout/collection.py +1 -0
  625. ansible_test/_internal/provider/layout/unsupported.py +1 -0
  626. ansible_test/_internal/provider/source/__init__.py +1 -0
  627. ansible_test/_internal/provider/source/git.py +1 -0
  628. ansible_test/_internal/provider/source/installed.py +1 -0
  629. ansible_test/_internal/provider/source/unsupported.py +1 -0
  630. ansible_test/_internal/provider/source/unversioned.py +1 -0
  631. ansible_test/_internal/provisioning.py +1 -0
  632. ansible_test/_internal/pypi_proxy.py +6 -5
  633. ansible_test/_internal/python_requirements.py +1 -0
  634. ansible_test/_internal/ssh.py +1 -0
  635. ansible_test/_internal/target.py +1 -0
  636. ansible_test/_internal/test.py +3 -2
  637. ansible_test/_internal/thread.py +1 -0
  638. ansible_test/_internal/timeout.py +1 -0
  639. ansible_test/_internal/util.py +1 -0
  640. ansible_test/_internal/util_common.py +5 -2
  641. ansible_test/_internal/venv.py +1 -0
  642. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
  643. ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
  644. ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
  645. ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
  646. ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
  647. ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
  648. ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
  649. ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
  650. ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
  651. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
  652. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
  653. ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
  654. ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
  655. ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
  656. ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
  657. ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
  658. ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
  659. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
  660. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
  661. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
  662. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
  663. ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
  664. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
  665. ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
  666. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
  667. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
  668. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
  669. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
  670. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
  671. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
  672. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
  673. ansible_test/_util/controller/tools/collection_detail.py +1 -0
  674. ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
  675. ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
  676. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
  677. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
  678. ansible_test/_util/target/sanity/compile/compile.py +1 -0
  679. ansible_test/_util/target/sanity/import/importer.py +15 -16
  680. ansible_test/_util/target/setup/bootstrap.sh +9 -20
  681. ansible_test/_util/target/setup/probe_cgroups.py +1 -0
  682. ansible_test/_util/target/setup/quiet_pip.py +1 -0
  683. ansible_test/_util/target/setup/requirements.py +35 -27
  684. ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
  685. ansible_test/_util/target/tools/yamlcheck.py +2 -1
  686. ansible/compat/selectors.py +0 -32
  687. ansible/errors/yaml_strings.py +0 -138
  688. ansible/executor/action_write_locks.py +0 -44
  689. ansible/executor/discovery/python_target.py +0 -47
  690. ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
  691. ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
  692. ansible/module_utils/compat/importlib.py +0 -26
  693. ansible/module_utils/compat/selectors.py +0 -32
  694. ansible/module_utils/pycompat24.py +0 -73
  695. ansible/parsing/utils/jsonify.py +0 -36
  696. ansible/parsing/yaml/constructor.py +0 -178
  697. ansible/template/native_helpers.py +0 -251
  698. ansible/template/template.py +0 -43
  699. ansible/template/vars.py +0 -77
  700. ansible/utils/native_jinja.py +0 -11
  701. ansible/vars/fact_cache.py +0 -71
  702. ansible_core-2.18.5rc1.dist-info/RECORD +0 -992
  703. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/Apache-License.txt +0 -0
  704. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/COPYING +0 -0
  705. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/MIT-license.txt +0 -0
  706. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/PSF-license.txt +0 -0
  707. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/entry_points.txt +0 -0
  708. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/simplified_bsd.txt +0 -0
  709. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,7 @@
3
3
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  from __future__ import annotations
5
5
 
6
- DOCUMENTATION = '''
6
+ DOCUMENTATION = """
7
7
  name: sh
8
8
  short_description: "POSIX shell (/bin/sh)"
9
9
  version_added: historical
@@ -11,7 +11,7 @@ description:
11
11
  - This shell plugin is the one you want to use on most Unix systems, it is the most compatible and widely installed shell.
12
12
  extends_documentation_fragment:
13
13
  - shell_common
14
- '''
14
+ """
15
15
 
16
16
  from ansible.plugins.shell import ShellBase
17
17
 
@@ -29,6 +29,7 @@ class ShellModule(ShellBase):
29
29
 
30
30
  # commonly used
31
31
  ECHO = 'echo'
32
+ CD = 'cd'
32
33
  COMMAND_SEP = ';'
33
34
 
34
35
  # How to end lines in a python script one-liner
@@ -30,32 +30,26 @@ import typing as t
30
30
  from collections import deque
31
31
 
32
32
 
33
- from jinja2.exceptions import UndefinedError
34
-
35
33
  from ansible import constants as C
36
34
  from ansible import context
37
- from ansible.errors import AnsibleError, AnsibleFileNotFound, AnsibleUndefinedVariable, AnsibleParserError
38
- from ansible.executor import action_write_locks
35
+ from ansible.errors import AnsibleError, AnsibleFileNotFound, AnsibleParserError, AnsibleTemplateError
39
36
  from ansible.executor.play_iterator import IteratingStates, PlayIterator
40
37
  from ansible.executor.process.worker import WorkerProcess
41
38
  from ansible.executor.task_result import TaskResult
42
- from ansible.executor.task_queue_manager import CallbackSend, DisplaySend, PromptSend
39
+ from ansible.executor.task_queue_manager import CallbackSend, DisplaySend, PromptSend, TaskQueueManager
43
40
  from ansible.module_utils.six import string_types
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
49
45
  from ansible.playbook.task import Task
50
46
  from ansible.playbook.task_include import TaskInclude
51
47
  from ansible.plugins import loader as plugin_loader
52
- from ansible.template import Templar
48
+ from ansible._internal._templating._engine import TemplateEngine
53
49
  from ansible.utils.display import Display
54
50
  from ansible.utils.fqcn import add_internal_fqcns
55
- from ansible.utils.unsafe_proxy import wrap_var
56
51
  from ansible.utils.sentinel import Sentinel
57
52
  from ansible.utils.vars import combine_vars
58
- from ansible.utils.multiprocessing import context as multiprocessing_context
59
53
  from ansible.vars.clean import strip_internal_keys, module_response_deepcopy
60
54
 
61
55
  display = Display()
@@ -75,22 +69,8 @@ class StrategySentinel:
75
69
 
76
70
  _sentinel = StrategySentinel()
77
71
 
78
-
79
- def post_process_whens(result, task, templar, task_vars):
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
72
+ if t.TYPE_CHECKING:
73
+ from ansible.inventory.host import Host
94
74
 
95
75
 
96
76
  def _get_item_vars(result, task):
@@ -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[TaskResult] = 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[str, 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 Templar(None).is_template(play.hosts):
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
- ''' handles queueing the task up to be sent to a worker '''
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 = Templar(loader=self._loader, variables=task_vars)
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 e:
377
- raise AnsibleError("Failed to convert the throttle value to an integer.", obj=task._ds, orig_exc=e)
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, task_vars, host, task, play_context, self._loader, self._variable_manager, plugin_loader, self._cur_worker,
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)
@@ -508,34 +482,38 @@ class StrategyBase:
508
482
  return task_result
509
483
 
510
484
  def search_handlers_by_notification(self, notification: str, iterator: PlayIterator) -> t.Generator[Handler, None, None]:
511
- templar = Templar(None)
512
485
  handlers = [h for b in reversed(iterator._play.handlers) for h in b.block]
513
486
  # iterate in reversed order since last handler loaded with the same name wins
514
487
  for handler in handlers:
515
488
  if not handler.name:
516
489
  continue
490
+
517
491
  if not handler.cached_name:
518
- if templar.is_template(handler.name):
519
- templar.available_variables = self._variable_manager.get_vars(
492
+ def variables_factory() -> dict[str, t.Any]:
493
+ return self._variable_manager.get_vars(
520
494
  play=iterator._play,
521
495
  task=handler,
522
496
  _hosts=self._hosts_cache,
523
497
  _hosts_all=self._hosts_cache_all
524
498
  )
525
- try:
526
- handler.name = templar.template(handler.name)
527
- except (UndefinedError, AnsibleUndefinedVariable) as e:
528
- # We skip this handler due to the fact that it may be using
529
- # a variable in the name that was conditionally included via
530
- # set_fact or some other method, and we don't want to error
531
- # out unnecessarily
532
- if not handler.listen:
533
- display.warning(
534
- "Handler '%s' is unusable because it has no listen topics and "
535
- "the name could not be templated (host-specific variables are "
536
- "not supported in handler names). The error: %s" % (handler.name, to_text(e))
537
- )
538
- continue
499
+
500
+ templar = TemplateEngine(variables_factory=variables_factory)
501
+
502
+ try:
503
+ handler.name = templar.template(handler.name)
504
+ except AnsibleTemplateError as e:
505
+ # We skip this handler due to the fact that it may be using
506
+ # a variable in the name that was conditionally included via
507
+ # set_fact or some other method, and we don't want to error
508
+ # out unnecessarily
509
+ if not handler.listen:
510
+ display.warning(
511
+ "Handler '%s' is unusable because it has no listen topics and "
512
+ "the name could not be templated (host-specific variables are "
513
+ "not supported in handler names). The error: %s" % (handler.name, to_text(e))
514
+ )
515
+ continue
516
+
539
517
  handler.cached_name = True
540
518
 
541
519
  # first we check with the full result of get_name(), which may
@@ -559,11 +537,11 @@ class StrategyBase:
559
537
  yield handler
560
538
 
561
539
  @debug_closure
562
- def _process_pending_results(self, iterator, one_pass=False, max_passes=None):
563
- '''
540
+ def _process_pending_results(self, iterator: PlayIterator, one_pass: bool = False, max_passes: int | None = None) -> list[TaskResult]:
541
+ """
564
542
  Reads results off the final queue and takes appropriate action
565
543
  based on the result (executing callbacks, updating state, etc.).
566
- '''
544
+ """
567
545
  ret_results = []
568
546
  cur_pass = 0
569
547
  while True:
@@ -576,7 +554,7 @@ class StrategyBase:
576
554
  self._results_lock.release()
577
555
 
578
556
  original_host = task_result._host
579
- original_task = task_result._task
557
+ original_task: Task = task_result._task
580
558
 
581
559
  # all host status messages contain 2 entries: (msg, task_result)
582
560
  role_ran = False
@@ -609,7 +587,7 @@ class StrategyBase:
609
587
  self._variable_manager.set_nonpersistent_facts(
610
588
  original_host.name,
611
589
  dict(
612
- ansible_failed_task=wrap_var(original_task.serialize()),
590
+ ansible_failed_task=original_task.serialize(),
613
591
  ansible_failed_result=task_result._result,
614
592
  ),
615
593
  )
@@ -651,7 +629,7 @@ class StrategyBase:
651
629
  # otherwise depending on the setting either error or warn
652
630
  host_state = iterator.get_state_for_host(original_host.name)
653
631
  for notification in result_item['_ansible_notify']:
654
- handler = Sentinel
632
+ handler: type[Sentinel] | Handler = Sentinel
655
633
  for handler in self.search_handlers_by_notification(notification, iterator):
656
634
  if host_state.run_state == IteratingStates.HANDLERS:
657
635
  # we're currently iterating handlers, so we need to expand this now
@@ -692,8 +670,15 @@ class StrategyBase:
692
670
  all_task_vars = combine_vars(found_task_vars, item_vars)
693
671
  else:
694
672
  all_task_vars = found_task_vars
695
- all_task_vars[original_task.register] = wrap_var(result_item)
696
- post_process_whens(result_item, original_task, Templar(self._loader), all_task_vars)
673
+ all_task_vars[original_task.register] = result_item
674
+
675
+ if original_task.changed_when:
676
+ result_item['changed'] = original_task._resolve_conditional(original_task.changed_when, all_task_vars)
677
+
678
+ if original_task.failed_when:
679
+ result_item['failed_when_result'] = result_item['failed'] = (
680
+ original_task._resolve_conditional(original_task.failed_when, all_task_vars))
681
+
697
682
  if original_task.loop or original_task.loop_with:
698
683
  new_item_result = TaskResult(
699
684
  task_result._host,
@@ -798,10 +783,10 @@ class StrategyBase:
798
783
  return ret_results
799
784
 
800
785
  def _wait_on_pending_results(self, iterator):
801
- '''
786
+ """
802
787
  Wait for the shared counter to drop to zero, using a short sleep
803
788
  between checks to ensure we don't spin lock
804
- '''
789
+ """
805
790
 
806
791
  ret_results = []
807
792
 
@@ -821,9 +806,9 @@ class StrategyBase:
821
806
  return ret_results
822
807
 
823
808
  def _copy_included_file(self, included_file):
824
- '''
809
+ """
825
810
  A proven safe and performant way to create a copy of an included file
826
- '''
811
+ """
827
812
  ti_copy = included_file._task.copy(exclude_parent=True)
828
813
  ti_copy._parent = included_file._task._parent
829
814
 
@@ -834,13 +819,13 @@ class StrategyBase:
834
819
  return ti_copy
835
820
 
836
821
  def _load_included_file(self, included_file, iterator, is_handler=False, handle_stats_and_callbacks=True):
837
- '''
822
+ """
838
823
  Loads an included YAML file of tasks, applying the optional set of variables.
839
824
 
840
825
  Raises AnsibleError exception in case of a failure during including a file,
841
826
  in such case the caller is responsible for marking the host(s) as failed
842
827
  using PlayIterator.mark_host_failed().
843
- '''
828
+ """
844
829
  if handle_stats_and_callbacks:
845
830
  display.deprecated(
846
831
  "Reporting play recap stats and running callbacks functionality for "
@@ -852,7 +837,7 @@ class StrategyBase:
852
837
  )
853
838
  display.debug("loading included file: %s" % included_file._filename)
854
839
  try:
855
- data = self._loader.load_from_file(included_file._filename)
840
+ data = self._loader.load_from_file(included_file._filename, trusted_as_template=True)
856
841
  if data is None:
857
842
  return []
858
843
  elif not isinstance(data, list):
@@ -920,19 +905,19 @@ class StrategyBase:
920
905
  def _cond_not_supported_warn(self, task_name):
921
906
  display.warning("%s task does not support when conditional" % task_name)
922
907
 
923
- def _execute_meta(self, task, play_context, iterator, target_host):
908
+ def _execute_meta(self, task: Task, play_context, iterator, target_host):
909
+ task.resolved_action = 'ansible.builtin.meta' # _post_validate_args is never called for meta actions, so resolved_action hasn't been set
924
910
 
925
911
  # meta tasks store their args in the _raw_params field of args,
926
912
  # since they do not use k=v pairs, so get that
927
- meta_action = task.args.get('_raw_params')
913
+ meta_action = task._get_meta()
928
914
 
929
- def _evaluate_conditional(h):
915
+ def _evaluate_conditional(conditional_host: Host) -> bool:
930
916
  if not task.when:
931
917
  return True
932
- all_vars = self._variable_manager.get_vars(play=iterator._play, host=h, task=task,
933
- _hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all)
934
- templar = Templar(loader=self._loader, variables=all_vars)
935
- return task.evaluate_conditional(templar, all_vars)
918
+
919
+ return task._resolve_conditional(task.when, self._variable_manager.get_vars(
920
+ play=iterator._play, host=conditional_host, task=task, _hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all))
936
921
 
937
922
  skipped = False
938
923
  msg = meta_action
@@ -1032,7 +1017,7 @@ class StrategyBase:
1032
1017
  if _evaluate_conditional(target_host):
1033
1018
  while True:
1034
1019
  state, task = iterator.get_next_task_for_host(target_host, peek=True)
1035
- if task.action in C._ACTION_META and task.args.get("_raw_params") == "role_complete":
1020
+ if task._get_meta() == "role_complete":
1036
1021
  break
1037
1022
  iterator.set_state_for_host(target_host.name, state)
1038
1023
  display.debug("'%s' skipped because role has been ended via 'end_role'" % task)
@@ -1043,7 +1028,7 @@ class StrategyBase:
1043
1028
  elif meta_action == 'reset_connection':
1044
1029
  all_vars = self._variable_manager.get_vars(play=iterator._play, host=target_host, task=task,
1045
1030
  _hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all)
1046
- templar = Templar(loader=self._loader, variables=all_vars)
1031
+ templar = TemplateEngine(loader=self._loader, variables=all_vars)
1047
1032
 
1048
1033
  # apply the given task's information to the connection info,
1049
1034
  # which may override some fields already set by the play or
@@ -1085,15 +1070,17 @@ class StrategyBase:
1085
1070
  else:
1086
1071
  raise AnsibleError("invalid meta action requested: %s" % meta_action, obj=task._ds)
1087
1072
 
1088
- result = {'msg': msg}
1073
+ result: dict[str, object] = {'msg': msg}
1089
1074
  if skipped:
1090
1075
  result['skipped'] = True
1091
1076
  result['skip_reason'] = skip_reason
1092
1077
  else:
1093
1078
  result['changed'] = False
1094
1079
 
1095
- if not task.implicit:
1096
- header = skip_reason if skipped else msg
1080
+ header = skip_reason if skipped else msg
1081
+ if task.implicit:
1082
+ display.debug(f"META: {header}")
1083
+ else:
1097
1084
  display.vv(f"META: {header}")
1098
1085
 
1099
1086
  res = TaskResult(target_host, task, result)
@@ -1102,16 +1089,10 @@ class StrategyBase:
1102
1089
  return [res]
1103
1090
 
1104
1091
  def _get_cached_role(self, task, play):
1105
- role_path = task._role.get_role_path()
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')
1092
+ return play._get_cached_role(task._role)
1112
1093
 
1113
1094
  def get_hosts_left(self, iterator):
1114
- ''' returns list of available hosts for this iterator by filtering out unreachables '''
1095
+ """ returns list of available hosts for this iterator by filtering out unreachables """
1115
1096
 
1116
1097
  hosts_left = []
1117
1098
  for host in self._hosts_cache:
@@ -1123,7 +1104,7 @@ class StrategyBase:
1123
1104
  return hosts_left
1124
1105
 
1125
1106
  def update_active_connections(self, results):
1126
- ''' updates the current active persistent connections '''
1107
+ """ updates the current active persistent connections """
1127
1108
  for r in results:
1128
1109
  if 'args' in r._task_fields:
1129
1110
  socket_path = r._task_fields['args'].get('_ansible_socket')
@@ -1195,7 +1176,7 @@ class Debugger(cmd.Cmd):
1195
1176
 
1196
1177
  def do_update_task(self, args):
1197
1178
  """Recreate the task from ``task._ds``, and template with updated ``task_vars``"""
1198
- templar = Templar(None, variables=self.scope['task_vars'])
1179
+ templar = TemplateEngine(variables=self.scope['task_vars'])
1199
1180
  task = self.scope['task']
1200
1181
  task = task.load_data(task._ds)
1201
1182
  task.post_validate(templar)
@@ -14,14 +14,14 @@
14
14
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
15
15
  from __future__ import annotations
16
16
 
17
- DOCUMENTATION = '''
17
+ DOCUMENTATION = """
18
18
  name: debug
19
19
  short_description: Executes tasks in interactive debug session.
20
20
  description:
21
21
  - Task execution is 'linear' but controlled by an interactive debug session.
22
22
  version_added: "2.1"
23
23
  author: Kishin Yagami (!UNKNOWN)
24
- '''
24
+ """
25
25
 
26
26
  from ansible.plugins.strategy.linear import StrategyModule as LinearStrategyModule
27
27
 
@@ -16,7 +16,7 @@
16
16
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
17
17
  from __future__ import annotations
18
18
 
19
- DOCUMENTATION = '''
19
+ DOCUMENTATION = """
20
20
  name: free
21
21
  short_description: Executes tasks without waiting for all hosts
22
22
  description:
@@ -27,7 +27,7 @@ DOCUMENTATION = '''
27
27
  won't hold up the rest of the hosts and tasks.
28
28
  version_added: "2.0"
29
29
  author: Ansible Core Team
30
- '''
30
+ """
31
31
 
32
32
  import time
33
33
 
@@ -37,8 +37,7 @@ from ansible.playbook.handler import Handler
37
37
  from ansible.playbook.included_file import IncludedFile
38
38
  from ansible.plugins.loader import action_loader
39
39
  from ansible.plugins.strategy import StrategyBase
40
- from ansible.template import Templar
41
- from ansible.module_utils.common.text.converters import to_text
40
+ from ansible._internal._templating._engine import TemplateEngine
42
41
  from ansible.utils.display import Display
43
42
 
44
43
  display = Display()
@@ -54,7 +53,7 @@ class StrategyModule(StrategyBase):
54
53
  self._host_pinned = False
55
54
 
56
55
  def run(self, iterator, play_context):
57
- '''
56
+ """
58
57
  The "free" strategy is a bit more complex, in that it allows tasks to
59
58
  be sent to hosts as quickly as they can be processed. This means that
60
59
  some hosts may finish very quickly if run tasks result in little or no
@@ -65,7 +64,7 @@ class StrategyModule(StrategyBase):
65
64
  and starting the search from there as opposed to the top of the hosts
66
65
  list again, which would end up favoring hosts near the beginning of the
67
66
  list.
68
- '''
67
+ """
69
68
 
70
69
  # the last host to be given a task
71
70
  last_host = 0
@@ -124,13 +123,13 @@ class StrategyModule(StrategyBase):
124
123
  _hosts=self._hosts_cache,
125
124
  _hosts_all=self._hosts_cache_all)
126
125
  self.add_tqm_variables(task_vars, play=iterator._play)
127
- templar = Templar(loader=self._loader, variables=task_vars)
126
+ templar = TemplateEngine(loader=self._loader, variables=task_vars)
128
127
  display.debug("done getting variables", host=host_name)
129
128
 
130
129
  try:
131
130
  throttle = int(templar.template(task.throttle))
132
- except Exception as e:
133
- raise AnsibleError("Failed to convert the throttle value to an integer.", obj=task._ds, orig_exc=e)
131
+ except Exception as ex:
132
+ raise AnsibleError("Failed to convert the throttle value to an integer.", obj=task.throttle) from ex
134
133
 
135
134
  if throttle > 0:
136
135
  same_tasks = 0
@@ -155,13 +154,7 @@ class StrategyModule(StrategyBase):
155
154
  # corresponding action plugin
156
155
  action = None
157
156
 
158
- try:
159
- task.name = to_text(templar.template(task.name, fail_on_undefined=False), nonstring='empty')
160
- display.debug("done templating", host=host_name)
161
- except Exception:
162
- # just ignore any errors during task name templating,
163
- # we don't care if it just shows the raw name
164
- display.debug("templating failed for some reason", host=host_name)
157
+ task.post_validate_attribute("name", templar=templar)
165
158
 
166
159
  run_once = templar.template(task.run_once) or action and getattr(action, 'BYPASS_HOST_LOOP', False)
167
160
  if run_once:
@@ -172,15 +165,6 @@ class StrategyModule(StrategyBase):
172
165
  display.warning("Using run_once with the free strategy is not currently supported. This task will still be "
173
166
  "executed for every host in the inventory list.")
174
167
 
175
- # check to see if this task should be skipped, due to it being a member of a
176
- # role which has already run (and whether that role allows duplicate execution)
177
- if not isinstance(task, Handler) and task._role:
178
- role_obj = self._get_cached_role(task, iterator._play)
179
- if role_obj.has_run(host) and task._role._metadata.allow_duplicates is False:
180
- display.debug("'%s' skipped because role has already run" % task, host=host_name)
181
- del self._blocked_hosts[host_name]
182
- continue
183
-
184
168
  if task.action in C._ACTION_META:
185
169
  if self._host_pinned:
186
170
  meta_task_dummy_results_count += 1
@@ -264,11 +248,12 @@ class StrategyModule(StrategyBase):
264
248
  iterator.handlers = [h for b in iterator._play.handlers for h in b.block]
265
249
  except AnsibleParserError:
266
250
  raise
267
- except AnsibleError as e:
268
- display.error(to_text(e), wrap_text=False)
251
+ except AnsibleError as ex:
252
+ # FIXME: send the error to the callback; don't directly write to display here
253
+ display.error(ex)
269
254
  for r in included_file._results:
270
255
  r._result['failed'] = True
271
- r._result['reason'] = str(e)
256
+ r._result['reason'] = str(ex)
272
257
  self._tqm._stats.increment('failures', r._host.name)
273
258
  self._tqm.send_callback('v2_runner_on_failed', r)
274
259
  failed_includes_hosts.add(r._host)
@@ -16,7 +16,7 @@
16
16
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
17
17
  from __future__ import annotations
18
18
 
19
- DOCUMENTATION = '''
19
+ DOCUMENTATION = """
20
20
  name: host_pinned
21
21
  short_description: Executes tasks on each host without interruption
22
22
  description:
@@ -28,7 +28,7 @@ DOCUMENTATION = '''
28
28
  Other than that, it behaves just like the "free" strategy.
29
29
  version_added: "2.7"
30
30
  author: Ansible Core Team
31
- '''
31
+ """
32
32
 
33
33
  from ansible.plugins.strategy.free import StrategyModule as FreeStrategyModule
34
34
  from ansible.utils.display import Display