ansible-core 2.15.4rc1__py3-none-any.whl → 2.16.0b2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ansible-core might be problematic. Click here for more details.

Files changed (427) hide show
  1. ansible/cli/__init__.py +3 -3
  2. ansible/cli/adhoc.py +1 -1
  3. ansible/cli/arguments/option_helpers.py +15 -5
  4. ansible/cli/config.py +2 -2
  5. ansible/cli/console.py +21 -17
  6. ansible/cli/doc.py +8 -9
  7. ansible/cli/galaxy.py +60 -27
  8. ansible/cli/inventory.py +1 -1
  9. ansible/cli/playbook.py +1 -1
  10. ansible/cli/pull.py +2 -2
  11. ansible/cli/scripts/ansible_connection_cli_stub.py +1 -1
  12. ansible/cli/vault.py +11 -6
  13. ansible/collections/__init__.py +0 -29
  14. ansible/collections/list.py +23 -44
  15. ansible/config/ansible_builtin_runtime.yml +8 -4
  16. ansible/config/base.yml +34 -22
  17. ansible/config/manager.py +1 -1
  18. ansible/constants.py +3 -5
  19. ansible/errors/__init__.py +1 -1
  20. ansible/executor/interpreter_discovery.py +1 -1
  21. ansible/executor/module_common.py +39 -32
  22. ansible/executor/play_iterator.py +0 -15
  23. ansible/executor/playbook_executor.py +3 -3
  24. ansible/executor/powershell/module_manifest.py +1 -1
  25. ansible/executor/powershell/module_wrapper.ps1 +4 -1
  26. ansible/executor/process/worker.py +22 -7
  27. ansible/executor/task_executor.py +39 -40
  28. ansible/executor/task_queue_manager.py +8 -11
  29. ansible/galaxy/__init__.py +1 -1
  30. ansible/galaxy/api.py +8 -11
  31. ansible/galaxy/collection/__init__.py +17 -4
  32. ansible/galaxy/collection/concrete_artifact_manager.py +7 -2
  33. ansible/galaxy/collection/galaxy_api_proxy.py +1 -1
  34. ansible/galaxy/data/container/README.md +3 -5
  35. ansible/galaxy/dependency_resolution/__init__.py +1 -6
  36. ansible/galaxy/dependency_resolution/dataclasses.py +22 -1
  37. ansible/galaxy/dependency_resolution/providers.py +61 -69
  38. ansible/galaxy/role.py +31 -13
  39. ansible/galaxy/token.py +2 -2
  40. ansible/inventory/group.py +1 -1
  41. ansible/inventory/manager.py +1 -1
  42. ansible/module_utils/ansible_release.py +2 -2
  43. ansible/module_utils/basic.py +11 -41
  44. ansible/module_utils/common/file.py +0 -100
  45. ansible/module_utils/common/json.py +1 -1
  46. ansible/module_utils/common/locale.py +1 -1
  47. ansible/module_utils/common/text/converters.py +2 -2
  48. ansible/module_utils/common/validation.py +1 -1
  49. ansible/module_utils/compat/_selectors2.py +4 -4
  50. ansible/module_utils/compat/datetime.py +40 -0
  51. ansible/module_utils/compat/selinux.py +1 -1
  52. ansible/module_utils/compat/typing.py +1 -1
  53. ansible/module_utils/connection.py +1 -1
  54. ansible/module_utils/facts/hardware/linux.py +2 -2
  55. ansible/module_utils/facts/hardware/openbsd.py +1 -1
  56. ansible/module_utils/facts/network/linux.py +3 -3
  57. ansible/module_utils/facts/other/facter.py +8 -15
  58. ansible/module_utils/facts/sysctl.py +1 -1
  59. ansible/module_utils/facts/system/date_time.py +2 -2
  60. ansible/module_utils/facts/system/distribution.py +1 -1
  61. ansible/module_utils/facts/system/local.py +6 -2
  62. ansible/module_utils/facts/system/pkg_mgr.py +6 -1
  63. ansible/module_utils/facts/system/service_mgr.py +4 -2
  64. ansible/module_utils/parsing/convert_bool.py +1 -1
  65. ansible/module_utils/service.py +9 -6
  66. ansible/module_utils/urls.py +40 -22
  67. ansible/modules/add_host.py +2 -2
  68. ansible/modules/apt.py +48 -31
  69. ansible/modules/apt_key.py +4 -4
  70. ansible/modules/apt_repository.py +5 -5
  71. ansible/modules/assemble.py +7 -7
  72. ansible/modules/assert.py +1 -1
  73. ansible/modules/async_status.py +11 -7
  74. ansible/modules/async_wrapper.py +1 -1
  75. ansible/modules/blockinfile.py +60 -17
  76. ansible/modules/command.py +37 -15
  77. ansible/modules/copy.py +35 -30
  78. ansible/modules/cron.py +14 -14
  79. ansible/modules/deb822_repository.py +4 -3
  80. ansible/modules/debconf.py +35 -14
  81. ansible/modules/debug.py +1 -1
  82. ansible/modules/dnf.py +29 -27
  83. ansible/modules/dnf5.py +22 -22
  84. ansible/modules/dpkg_selections.py +9 -2
  85. ansible/modules/expect.py +4 -4
  86. ansible/modules/fetch.py +7 -7
  87. ansible/modules/file.py +30 -30
  88. ansible/modules/find.py +82 -22
  89. ansible/modules/gather_facts.py +6 -2
  90. ansible/modules/get_url.py +29 -29
  91. ansible/modules/getent.py +4 -4
  92. ansible/modules/git.py +27 -27
  93. ansible/modules/group.py +5 -12
  94. ansible/modules/hostname.py +21 -2
  95. ansible/modules/include_role.py +5 -5
  96. ansible/modules/include_tasks.py +2 -2
  97. ansible/modules/include_vars.py +5 -5
  98. ansible/modules/iptables.py +70 -65
  99. ansible/modules/known_hosts.py +7 -7
  100. ansible/modules/lineinfile.py +33 -33
  101. ansible/modules/meta.py +13 -13
  102. ansible/modules/package.py +8 -8
  103. ansible/modules/package_facts.py +3 -3
  104. ansible/modules/pause.py +2 -2
  105. ansible/modules/ping.py +5 -5
  106. ansible/modules/pip.py +80 -46
  107. ansible/modules/reboot.py +8 -4
  108. ansible/modules/replace.py +20 -15
  109. ansible/modules/rpm_key.py +2 -2
  110. ansible/modules/script.py +16 -10
  111. ansible/modules/service.py +26 -98
  112. ansible/modules/service_facts.py +36 -12
  113. ansible/modules/set_fact.py +2 -2
  114. ansible/modules/set_stats.py +2 -2
  115. ansible/modules/setup.py +18 -18
  116. ansible/modules/shell.py +3 -3
  117. ansible/modules/stat.py +9 -30
  118. ansible/modules/subversion.py +9 -9
  119. ansible/modules/systemd.py +20 -19
  120. ansible/modules/systemd_service.py +20 -19
  121. ansible/modules/sysvinit.py +26 -21
  122. ansible/modules/tempfile.py +5 -4
  123. ansible/modules/template.py +60 -6
  124. ansible/modules/unarchive.py +21 -18
  125. ansible/modules/uri.py +39 -39
  126. ansible/modules/user.py +81 -53
  127. ansible/modules/wait_for.py +22 -21
  128. ansible/modules/wait_for_connection.py +4 -4
  129. ansible/modules/yum.py +38 -38
  130. ansible/modules/yum_repository.py +58 -80
  131. ansible/parsing/dataloader.py +27 -27
  132. ansible/parsing/mod_args.py +1 -1
  133. ansible/parsing/plugin_docs.py +3 -3
  134. ansible/parsing/splitter.py +14 -16
  135. ansible/parsing/utils/yaml.py +1 -1
  136. ansible/parsing/vault/__init__.py +8 -6
  137. ansible/parsing/yaml/constructor.py +1 -1
  138. ansible/parsing/yaml/objects.py +1 -1
  139. ansible/playbook/__init__.py +1 -1
  140. ansible/playbook/base.py +2 -2
  141. ansible/playbook/block.py +0 -1
  142. ansible/playbook/conditional.py +40 -114
  143. ansible/playbook/helpers.py +5 -28
  144. ansible/playbook/included_file.py +8 -7
  145. ansible/playbook/play.py +1 -1
  146. ansible/playbook/play_context.py +2 -2
  147. ansible/playbook/playbook_include.py +2 -2
  148. ansible/playbook/role/__init__.py +1 -1
  149. ansible/playbook/role/include.py +1 -1
  150. ansible/playbook/role/metadata.py +1 -1
  151. ansible/playbook/role_include.py +1 -1
  152. ansible/playbook/task.py +2 -2
  153. ansible/playbook/task_include.py +1 -24
  154. ansible/plugins/__init__.py +13 -5
  155. ansible/plugins/action/__init__.py +17 -43
  156. ansible/plugins/action/add_host.py +2 -3
  157. ansible/plugins/action/assemble.py +1 -1
  158. ansible/plugins/action/assert.py +2 -1
  159. ansible/plugins/action/copy.py +2 -2
  160. ansible/plugins/action/debug.py +2 -1
  161. ansible/plugins/action/fail.py +1 -0
  162. ansible/plugins/action/fetch.py +3 -1
  163. ansible/plugins/action/gather_facts.py +37 -13
  164. ansible/plugins/action/group_by.py +1 -0
  165. ansible/plugins/action/include_vars.py +3 -2
  166. ansible/plugins/action/normal.py +3 -3
  167. ansible/plugins/action/pause.py +1 -1
  168. ansible/plugins/action/reboot.py +21 -16
  169. ansible/plugins/action/script.py +23 -8
  170. ansible/plugins/action/set_fact.py +1 -0
  171. ansible/plugins/action/set_stats.py +1 -0
  172. ansible/plugins/action/shell.py +6 -0
  173. ansible/plugins/action/template.py +1 -1
  174. ansible/plugins/action/unarchive.py +1 -1
  175. ansible/plugins/action/uri.py +1 -1
  176. ansible/plugins/action/validate_argument_spec.py +1 -0
  177. ansible/plugins/action/wait_for_connection.py +4 -4
  178. ansible/plugins/become/__init__.py +1 -1
  179. ansible/plugins/become/su.py +1 -1
  180. ansible/plugins/cache/__init__.py +1 -1
  181. ansible/plugins/callback/junit.py +1 -1
  182. ansible/plugins/callback/oneline.py +1 -1
  183. ansible/plugins/callback/tree.py +1 -1
  184. ansible/plugins/cliconf/__init__.py +2 -2
  185. ansible/plugins/connection/__init__.py +65 -37
  186. ansible/plugins/connection/local.py +9 -8
  187. ansible/plugins/connection/paramiko_ssh.py +34 -28
  188. ansible/plugins/connection/psrp.py +56 -43
  189. ansible/plugins/connection/ssh.py +67 -43
  190. ansible/plugins/connection/winrm.py +77 -30
  191. ansible/plugins/doc_fragments/constructed.py +4 -4
  192. ansible/plugins/doc_fragments/files.py +12 -12
  193. ansible/plugins/doc_fragments/inventory_cache.py +0 -6
  194. ansible/plugins/doc_fragments/result_format_callback.py +5 -5
  195. ansible/plugins/doc_fragments/shell_common.py +2 -2
  196. ansible/plugins/doc_fragments/shell_windows.py +1 -1
  197. ansible/plugins/doc_fragments/template_common.py +6 -6
  198. ansible/plugins/doc_fragments/url.py +10 -10
  199. ansible/plugins/doc_fragments/url_windows.py +15 -15
  200. ansible/plugins/doc_fragments/vars_plugin_staging.py +4 -4
  201. ansible/plugins/filter/b64decode.yml +1 -1
  202. ansible/plugins/filter/b64encode.yml +2 -2
  203. ansible/plugins/filter/bool.yml +5 -5
  204. ansible/plugins/filter/combine.yml +1 -1
  205. ansible/plugins/filter/commonpath.yml +2 -1
  206. ansible/plugins/filter/core.py +6 -8
  207. ansible/plugins/filter/dict2items.yml +11 -1
  208. ansible/plugins/filter/difference.yml +1 -0
  209. ansible/plugins/filter/encryption.py +1 -1
  210. ansible/plugins/filter/extract.yml +1 -1
  211. ansible/plugins/filter/flatten.yml +1 -1
  212. ansible/plugins/filter/from_yaml.yml +1 -1
  213. ansible/plugins/filter/from_yaml_all.yml +2 -2
  214. ansible/plugins/filter/hash.yml +1 -1
  215. ansible/plugins/filter/human_readable.yml +1 -1
  216. ansible/plugins/filter/human_to_bytes.yml +2 -2
  217. ansible/plugins/filter/intersect.yml +1 -0
  218. ansible/plugins/filter/mandatory.yml +7 -0
  219. ansible/plugins/filter/mathstuff.py +15 -17
  220. ansible/plugins/filter/normpath.yml +1 -1
  221. ansible/plugins/filter/path_join.yml +8 -1
  222. ansible/plugins/filter/realpath.yml +3 -2
  223. ansible/plugins/filter/regex_findall.yml +8 -2
  224. ansible/plugins/filter/regex_replace.yml +9 -3
  225. ansible/plugins/filter/regex_search.yml +8 -2
  226. ansible/plugins/filter/relpath.yml +2 -2
  227. ansible/plugins/filter/root.yml +1 -1
  228. ansible/plugins/filter/splitext.yml +1 -1
  229. ansible/plugins/filter/subelements.yml +2 -2
  230. ansible/plugins/filter/symmetric_difference.yml +1 -0
  231. ansible/plugins/filter/ternary.yml +5 -5
  232. ansible/plugins/filter/to_json.yml +7 -7
  233. ansible/plugins/filter/to_nice_json.yml +5 -5
  234. ansible/plugins/filter/to_yaml.yml +2 -2
  235. ansible/plugins/filter/type_debug.yml +1 -1
  236. ansible/plugins/filter/union.yml +1 -0
  237. ansible/plugins/filter/unvault.yml +2 -2
  238. ansible/plugins/filter/urldecode.yml +13 -32
  239. ansible/plugins/filter/urlsplit.py +1 -1
  240. ansible/plugins/filter/vault.yml +1 -1
  241. ansible/plugins/filter/zip.yml +1 -1
  242. ansible/plugins/filter/zip_longest.yml +1 -1
  243. ansible/plugins/inventory/__init__.py +1 -1
  244. ansible/plugins/inventory/advanced_host_list.py +1 -1
  245. ansible/plugins/inventory/constructed.py +2 -2
  246. ansible/plugins/inventory/host_list.py +1 -1
  247. ansible/plugins/inventory/ini.py +6 -3
  248. ansible/plugins/inventory/script.py +8 -2
  249. ansible/plugins/inventory/toml.py +1 -1
  250. ansible/plugins/inventory/yaml.py +1 -1
  251. ansible/plugins/list.py +21 -17
  252. ansible/plugins/loader.py +66 -88
  253. ansible/plugins/lookup/__init__.py +1 -1
  254. ansible/plugins/lookup/config.py +16 -6
  255. ansible/plugins/lookup/csvfile.py +7 -4
  256. ansible/plugins/lookup/env.py +1 -1
  257. ansible/plugins/lookup/file.py +5 -2
  258. ansible/plugins/lookup/fileglob.py +5 -2
  259. ansible/plugins/lookup/first_found.py +20 -14
  260. ansible/plugins/lookup/ini.py +6 -3
  261. ansible/plugins/lookup/lines.py +2 -1
  262. ansible/plugins/lookup/password.py +7 -7
  263. ansible/plugins/lookup/pipe.py +1 -0
  264. ansible/plugins/lookup/random_choice.py +2 -2
  265. ansible/plugins/lookup/sequence.py +1 -1
  266. ansible/plugins/lookup/subelements.py +2 -2
  267. ansible/plugins/lookup/template.py +4 -1
  268. ansible/plugins/lookup/unvault.py +4 -1
  269. ansible/plugins/lookup/url.py +6 -6
  270. ansible/plugins/lookup/varnames.py +1 -1
  271. ansible/plugins/netconf/__init__.py +3 -3
  272. ansible/plugins/shell/__init__.py +1 -1
  273. ansible/plugins/shell/cmd.py +7 -7
  274. ansible/plugins/shell/powershell.py +1 -1
  275. ansible/plugins/strategy/__init__.py +8 -10
  276. ansible/plugins/strategy/free.py +1 -1
  277. ansible/plugins/strategy/linear.py +3 -3
  278. ansible/plugins/terminal/__init__.py +2 -2
  279. ansible/plugins/test/abs.yml +1 -1
  280. ansible/plugins/test/all.yml +1 -1
  281. ansible/plugins/test/any.yml +1 -1
  282. ansible/plugins/test/change.yml +2 -2
  283. ansible/plugins/test/changed.yml +2 -2
  284. ansible/plugins/test/contains.yml +1 -1
  285. ansible/plugins/test/core.py +1 -1
  286. ansible/plugins/test/directory.yml +1 -1
  287. ansible/plugins/test/exists.yml +3 -2
  288. ansible/plugins/test/failed.yml +2 -2
  289. ansible/plugins/test/failure.yml +2 -2
  290. ansible/plugins/test/falsy.yml +2 -2
  291. ansible/plugins/test/file.yml +1 -1
  292. ansible/plugins/test/finished.yml +2 -2
  293. ansible/plugins/test/is_abs.yml +1 -1
  294. ansible/plugins/test/is_dir.yml +1 -1
  295. ansible/plugins/test/is_file.yml +1 -1
  296. ansible/plugins/test/is_link.yml +1 -1
  297. ansible/plugins/test/is_mount.yml +1 -1
  298. ansible/plugins/test/is_same_file.yml +1 -1
  299. ansible/plugins/test/isnan.yml +1 -1
  300. ansible/plugins/test/issubset.yml +1 -2
  301. ansible/plugins/test/issuperset.yml +1 -2
  302. ansible/plugins/test/link.yml +1 -1
  303. ansible/plugins/test/link_exists.yml +1 -1
  304. ansible/plugins/test/match.yml +2 -2
  305. ansible/plugins/test/mount.yml +1 -1
  306. ansible/plugins/test/nan.yml +1 -1
  307. ansible/plugins/test/reachable.yml +2 -2
  308. ansible/plugins/test/regex.yml +1 -1
  309. ansible/plugins/test/same_file.yml +1 -1
  310. ansible/plugins/test/search.yml +2 -2
  311. ansible/plugins/test/skip.yml +3 -3
  312. ansible/plugins/test/skipped.yml +3 -3
  313. ansible/plugins/test/started.yml +2 -2
  314. ansible/plugins/test/subset.yml +1 -2
  315. ansible/plugins/test/succeeded.yml +2 -2
  316. ansible/plugins/test/success.yml +2 -2
  317. ansible/plugins/test/successful.yml +2 -2
  318. ansible/plugins/test/superset.yml +1 -2
  319. ansible/plugins/test/truthy.yml +3 -3
  320. ansible/plugins/test/unreachable.yml +2 -2
  321. ansible/plugins/test/uri.yml +1 -1
  322. ansible/plugins/test/url.yml +1 -1
  323. ansible/plugins/test/urn.yml +1 -1
  324. ansible/plugins/test/vault_encrypted.yml +1 -1
  325. ansible/plugins/test/version.yml +7 -7
  326. ansible/plugins/test/version_compare.yml +7 -7
  327. ansible/plugins/vars/host_group_vars.py +1 -1
  328. ansible/release.py +2 -2
  329. ansible/template/__init__.py +24 -26
  330. ansible/template/native_helpers.py +1 -1
  331. ansible/template/vars.py +1 -1
  332. ansible/utils/_junit_xml.py +1 -1
  333. ansible/utils/cmd_functions.py +1 -1
  334. ansible/utils/collection_loader/_collection_finder.py +12 -1
  335. ansible/utils/display.py +113 -62
  336. ansible/utils/encrypt.py +11 -14
  337. ansible/utils/hashing.py +1 -1
  338. ansible/utils/jsonrpc.py +1 -1
  339. ansible/utils/path.py +1 -1
  340. ansible/utils/plugin_docs.py +1 -1
  341. ansible/utils/py3compat.py +1 -1
  342. ansible/utils/shlex.py +2 -10
  343. ansible/utils/ssh_functions.py +5 -4
  344. ansible/utils/unicode.py +1 -1
  345. ansible/utils/unsafe_proxy.py +1 -1
  346. ansible/utils/vars.py +4 -29
  347. ansible/vars/hostvars.py +1 -2
  348. ansible/vars/manager.py +13 -9
  349. ansible/vars/plugins.py +2 -2
  350. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/COPYING +4 -5
  351. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/METADATA +2 -4
  352. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/RECORD +424 -425
  353. ansible_test/_data/completion/docker.txt +9 -9
  354. ansible_test/_data/completion/remote.txt +4 -7
  355. ansible_test/_data/completion/windows.txt +0 -2
  356. ansible_test/_data/requirements/ansible-test.txt +2 -1
  357. ansible_test/_data/requirements/ansible.txt +0 -3
  358. ansible_test/_data/requirements/constraints.txt +0 -2
  359. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -5
  360. ansible_test/_data/requirements/sanity.changelog.in +1 -2
  361. ansible_test/_data/requirements/sanity.changelog.txt +4 -6
  362. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -4
  363. ansible_test/_data/requirements/sanity.import.txt +1 -3
  364. ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -3
  365. ansible_test/_data/requirements/sanity.mypy.txt +12 -12
  366. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  367. ansible_test/_data/requirements/sanity.pylint.txt +6 -12
  368. ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -3
  369. ansible_test/_data/requirements/sanity.validate-modules.in +1 -1
  370. ansible_test/_data/requirements/sanity.validate-modules.txt +3 -5
  371. ansible_test/_data/requirements/sanity.yamllint.txt +3 -5
  372. ansible_test/_data/requirements/units.txt +0 -1
  373. ansible_test/_internal/ci/azp.py +4 -4
  374. ansible_test/_internal/cli/environments.py +0 -13
  375. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +4 -4
  376. ansible_test/_internal/commands/coverage/combine.py +1 -1
  377. ansible_test/_internal/commands/integration/cloud/acme.py +6 -8
  378. ansible_test/_internal/commands/integration/cloud/cs.py +4 -9
  379. ansible_test/_internal/commands/integration/cloud/galaxy.py +103 -96
  380. ansible_test/_internal/commands/integration/cloud/httptester.py +0 -3
  381. ansible_test/_internal/commands/integration/cloud/nios.py +7 -9
  382. ansible_test/_internal/commands/integration/cloud/openshift.py +2 -7
  383. ansible_test/_internal/commands/integration/cloud/vcenter.py +11 -95
  384. ansible_test/_internal/commands/sanity/__init__.py +10 -0
  385. ansible_test/_internal/commands/sanity/import.py +8 -2
  386. ansible_test/_internal/commands/sanity/pylint.py +27 -1
  387. ansible_test/_internal/commands/units/__init__.py +2 -1
  388. ansible_test/_internal/config.py +0 -7
  389. ansible_test/_internal/containers.py +11 -56
  390. ansible_test/_internal/core_ci.py +0 -7
  391. ansible_test/_internal/coverage_util.py +8 -3
  392. ansible_test/_internal/delegation.py +0 -1
  393. ansible_test/_internal/diff.py +1 -1
  394. ansible_test/_internal/docker_util.py +9 -2
  395. ansible_test/_internal/host_profiles.py +6 -6
  396. ansible_test/_internal/http.py +1 -1
  397. ansible_test/_internal/junit_xml.py +1 -1
  398. ansible_test/_internal/pypi_proxy.py +1 -1
  399. ansible_test/_internal/python_requirements.py +3 -8
  400. ansible_test/_internal/util.py +1 -6
  401. ansible_test/_util/controller/sanity/code-smell/no-get-exception.json +4 -0
  402. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.json +4 -0
  403. ansible_test/_util/controller/sanity/code-smell/use-compat-six.json +4 -0
  404. ansible_test/_util/controller/sanity/mypy/ansible-core.ini +3 -0
  405. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +2 -0
  406. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +0 -1
  407. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +1 -0
  408. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +172 -10
  409. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +13 -2
  410. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +7 -1
  411. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +6 -6
  412. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +1 -1
  413. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -1
  414. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +3 -3
  415. ansible_test/_util/controller/tools/collection_detail.py +2 -2
  416. ansible_test/_util/target/common/constants.py +2 -2
  417. ansible_test/_util/target/pytest/plugins/ansible_forked.py +103 -0
  418. ansible_test/_util/target/sanity/import/importer.py +0 -8
  419. ansible_test/_util/target/setup/bootstrap.sh +36 -16
  420. ansible_test/_util/target/setup/quiet_pip.py +0 -4
  421. ansible/modules/_include.py +0 -80
  422. ansible_test/_internal/commands/integration/cloud/foreman.py +0 -102
  423. ansible_test/_util/target/setup/ConfigureRemotingForAnsible.ps1 +0 -435
  424. {ansible_core-2.15.4rc1.data → ansible_core-2.16.0b2.data}/scripts/ansible-test +0 -0
  425. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/WHEEL +0 -0
  426. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/entry_points.txt +0 -0
  427. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/top_level.txt +0 -0
@@ -253,7 +253,6 @@ def command_units(args: UnitsConfig) -> None:
253
253
 
254
254
  cmd = [
255
255
  'pytest',
256
- '--forked',
257
256
  '-r', 'a',
258
257
  '-n', str(args.num_workers) if args.num_workers else 'auto',
259
258
  '--color', 'yes' if args.color else 'no',
@@ -275,6 +274,8 @@ def command_units(args: UnitsConfig) -> None:
275
274
  if data_context().content.collection:
276
275
  plugins.append('ansible_pytest_collections')
277
276
 
277
+ plugins.append('ansible_forked')
278
+
278
279
  if plugins:
279
280
  env['PYTHONPATH'] += ':%s' % os.path.join(ANSIBLE_TEST_TARGET_ROOT, 'pytest/plugins')
280
281
  env['PYTEST_PLUGINS'] = ','.join(plugins)
@@ -8,7 +8,6 @@ import sys
8
8
  import typing as t
9
9
 
10
10
  from .util import (
11
- display,
12
11
  verify_sys_executable,
13
12
  version_to_str,
14
13
  type_guard,
@@ -136,12 +135,6 @@ class EnvironmentConfig(CommonConfig):
136
135
 
137
136
  data_context().register_payload_callback(host_callback)
138
137
 
139
- if args.docker_no_pull:
140
- display.warning('The --docker-no-pull option is deprecated and has no effect. It will be removed in a future version of ansible-test.')
141
-
142
- if args.no_pip_check:
143
- display.warning('The --no-pip-check option is deprecated and has no effect. It will be removed in a future version of ansible-test.')
144
-
145
138
  @property
146
139
  def controller(self) -> ControllerHostConfig:
147
140
  """Host configuration for the controller."""
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
 
4
4
  import collections.abc as c
5
5
  import contextlib
6
- import enum
7
6
  import json
8
7
  import random
9
8
  import time
@@ -46,6 +45,7 @@ from .docker_util import (
46
45
  get_docker_container_id,
47
46
  get_docker_host_ip,
48
47
  get_podman_host_ip,
48
+ get_session_container_name,
49
49
  require_docker,
50
50
  detect_host_properties,
51
51
  )
@@ -101,14 +101,6 @@ class HostType:
101
101
  managed = 'managed'
102
102
 
103
103
 
104
- class CleanupMode(enum.Enum):
105
- """How container cleanup should be handled."""
106
-
107
- YES = enum.auto()
108
- NO = enum.auto()
109
- INFO = enum.auto()
110
-
111
-
112
104
  def run_support_container(
113
105
  args: EnvironmentConfig,
114
106
  context: str,
@@ -117,8 +109,7 @@ def run_support_container(
117
109
  ports: list[int],
118
110
  aliases: t.Optional[list[str]] = None,
119
111
  start: bool = True,
120
- allow_existing: bool = False,
121
- cleanup: t.Optional[CleanupMode] = None,
112
+ cleanup: bool = True,
122
113
  cmd: t.Optional[list[str]] = None,
123
114
  env: t.Optional[dict[str, str]] = None,
124
115
  options: t.Optional[list[str]] = None,
@@ -128,6 +119,8 @@ def run_support_container(
128
119
  Start a container used to support tests, but not run them.
129
120
  Containers created this way will be accessible from tests.
130
121
  """
122
+ name = get_session_container_name(args, name)
123
+
131
124
  if args.prime_containers:
132
125
  docker_pull(args, image)
133
126
  return None
@@ -165,46 +158,13 @@ def run_support_container(
165
158
 
166
159
  options.extend(['--ulimit', 'nofile=%s' % max_open_files])
167
160
 
168
- support_container_id = None
169
-
170
- if allow_existing:
171
- try:
172
- container = docker_inspect(args, name)
173
- except ContainerNotFoundError:
174
- container = None
175
-
176
- if container:
177
- support_container_id = container.id
178
-
179
- if not container.running:
180
- display.info('Ignoring existing "%s" container which is not running.' % name, verbosity=1)
181
- support_container_id = None
182
- elif not container.image:
183
- display.info('Ignoring existing "%s" container which has the wrong image.' % name, verbosity=1)
184
- support_container_id = None
185
- elif publish_ports and not all(port and len(port) == 1 for port in [container.get_tcp_port(port) for port in ports]):
186
- display.info('Ignoring existing "%s" container which does not have the required published ports.' % name, verbosity=1)
187
- support_container_id = None
188
-
189
- if not support_container_id:
190
- docker_rm(args, name)
191
-
192
161
  if args.dev_systemd_debug:
193
162
  options.extend(('--env', 'SYSTEMD_LOG_LEVEL=debug'))
194
163
 
195
- if support_container_id:
196
- display.info('Using existing "%s" container.' % name)
197
- running = True
198
- existing = True
199
- else:
200
- display.info('Starting new "%s" container.' % name)
201
- docker_pull(args, image)
202
- support_container_id = run_container(args, image, name, options, create_only=not start, cmd=cmd)
203
- running = start
204
- existing = False
205
-
206
- if cleanup is None:
207
- cleanup = CleanupMode.INFO if existing else CleanupMode.YES
164
+ display.info('Starting new "%s" container.' % name)
165
+ docker_pull(args, image)
166
+ support_container_id = run_container(args, image, name, options, create_only=not start, cmd=cmd)
167
+ running = start
208
168
 
209
169
  descriptor = ContainerDescriptor(
210
170
  image,
@@ -215,7 +175,6 @@ def run_support_container(
215
175
  aliases,
216
176
  publish_ports,
217
177
  running,
218
- existing,
219
178
  cleanup,
220
179
  env,
221
180
  )
@@ -694,8 +653,7 @@ class ContainerDescriptor:
694
653
  aliases: list[str],
695
654
  publish_ports: bool,
696
655
  running: bool,
697
- existing: bool,
698
- cleanup: CleanupMode,
656
+ cleanup: bool,
699
657
  env: t.Optional[dict[str, str]],
700
658
  ) -> None:
701
659
  self.image = image
@@ -706,7 +664,6 @@ class ContainerDescriptor:
706
664
  self.aliases = aliases
707
665
  self.publish_ports = publish_ports
708
666
  self.running = running
709
- self.existing = existing
710
667
  self.cleanup = cleanup
711
668
  self.env = env
712
669
  self.details: t.Optional[SupportContainer] = None
@@ -805,10 +762,8 @@ def wait_for_file(
805
762
  def cleanup_containers(args: EnvironmentConfig) -> None:
806
763
  """Clean up containers."""
807
764
  for container in support_containers.values():
808
- if container.cleanup == CleanupMode.YES:
809
- docker_rm(args, container.container_id)
810
- elif container.cleanup == CleanupMode.INFO:
811
- display.notice(f'Remember to run `{require_docker().command} rm -f {container.name}` when finished testing.')
765
+ if container.cleanup:
766
+ docker_rm(args, container.name)
812
767
 
813
768
 
814
769
  def create_hosts_entries(context: dict[str, ContainerAccess]) -> list[str]:
@@ -28,7 +28,6 @@ from .io import (
28
28
  from .util import (
29
29
  ApplicationError,
30
30
  display,
31
- ANSIBLE_TEST_TARGET_ROOT,
32
31
  mutex,
33
32
  )
34
33
 
@@ -292,18 +291,12 @@ class AnsibleCoreCI:
292
291
  """Start instance."""
293
292
  display.info(f'Initializing new {self.label} instance using: {self._uri}', verbosity=1)
294
293
 
295
- if self.platform == 'windows':
296
- winrm_config = read_text_file(os.path.join(ANSIBLE_TEST_TARGET_ROOT, 'setup', 'ConfigureRemotingForAnsible.ps1'))
297
- else:
298
- winrm_config = None
299
-
300
294
  data = dict(
301
295
  config=dict(
302
296
  platform=self.platform,
303
297
  version=self.version,
304
298
  architecture=self.arch,
305
299
  public_key=self.ssh_key.pub_contents,
306
- winrm_config=winrm_config,
307
300
  )
308
301
  )
309
302
 
@@ -69,7 +69,8 @@ class CoverageVersion:
69
69
 
70
70
  COVERAGE_VERSIONS = (
71
71
  # IMPORTANT: Keep this in sync with the ansible-test.txt requirements file.
72
- CoverageVersion('6.5.0', 7, (3, 7), (3, 11)),
72
+ CoverageVersion('7.3.2', 7, (3, 8), (3, 12)),
73
+ CoverageVersion('6.5.0', 7, (3, 7), (3, 7)),
73
74
  CoverageVersion('4.5.4', 0, (2, 6), (3, 6)),
74
75
  )
75
76
  """
@@ -250,7 +251,9 @@ def generate_ansible_coverage_config() -> str:
250
251
  coverage_config = '''
251
252
  [run]
252
253
  branch = True
253
- concurrency = multiprocessing
254
+ concurrency =
255
+ multiprocessing
256
+ thread
254
257
  parallel = True
255
258
 
256
259
  omit =
@@ -271,7 +274,9 @@ def generate_collection_coverage_config(args: TestConfig) -> str:
271
274
  coverage_config = '''
272
275
  [run]
273
276
  branch = True
274
- concurrency = multiprocessing
277
+ concurrency =
278
+ multiprocessing
279
+ thread
275
280
  parallel = True
276
281
  disable_warnings =
277
282
  no-data-collected
@@ -328,7 +328,6 @@ def filter_options(
328
328
  ) -> c.Iterable[str]:
329
329
  """Return an iterable that filters out unwanted CLI options and injects new ones as requested."""
330
330
  replace: list[tuple[str, int, t.Optional[t.Union[bool, str, list[str]]]]] = [
331
- ('--docker-no-pull', 0, False),
332
331
  ('--truncate', 1, str(args.truncate)),
333
332
  ('--color', 1, 'yes' if args.color else 'no'),
334
333
  ('--redact', 0, False),
@@ -143,7 +143,7 @@ class DiffParser:
143
143
  traceback.format_exc(),
144
144
  )
145
145
 
146
- raise ApplicationError(message.strip())
146
+ raise ApplicationError(message.strip()) from None
147
147
 
148
148
  self.previous_line = self.line
149
149
 
@@ -300,7 +300,7 @@ def detect_host_properties(args: CommonConfig) -> ContainerHostProperties:
300
300
  options = ['--volume', '/sys/fs/cgroup:/probe:ro']
301
301
  cmd = ['sh', '-c', ' && echo "-" && '.join(multi_line_commands)]
302
302
 
303
- stdout = run_utility_container(args, f'ansible-test-probe-{args.session_name}', cmd, options)[0]
303
+ stdout = run_utility_container(args, 'ansible-test-probe', cmd, options)[0]
304
304
 
305
305
  if args.explain:
306
306
  return ContainerHostProperties(
@@ -336,7 +336,7 @@ def detect_host_properties(args: CommonConfig) -> ContainerHostProperties:
336
336
  cmd = ['sh', '-c', 'ulimit -Hn']
337
337
 
338
338
  try:
339
- stdout = run_utility_container(args, f'ansible-test-ulimit-{args.session_name}', cmd, options)[0]
339
+ stdout = run_utility_container(args, 'ansible-test-ulimit', cmd, options)[0]
340
340
  except SubprocessError as ex:
341
341
  display.warning(str(ex))
342
342
  else:
@@ -402,6 +402,11 @@ def detect_host_properties(args: CommonConfig) -> ContainerHostProperties:
402
402
  return properties
403
403
 
404
404
 
405
+ def get_session_container_name(args: CommonConfig, name: str) -> str:
406
+ """Return the given container name with the current test session name applied to it."""
407
+ return f'{name}-{args.session_name}'
408
+
409
+
405
410
  def run_utility_container(
406
411
  args: CommonConfig,
407
412
  name: str,
@@ -410,6 +415,8 @@ def run_utility_container(
410
415
  data: t.Optional[str] = None,
411
416
  ) -> tuple[t.Optional[str], t.Optional[str]]:
412
417
  """Run the specified command using the ansible-test utility container, returning stdout and stderr."""
418
+ name = get_session_container_name(args, name)
419
+
413
420
  options = options + [
414
421
  '--name', name,
415
422
  '--rm',
@@ -99,7 +99,6 @@ from .ansible_util import (
99
99
  )
100
100
 
101
101
  from .containers import (
102
- CleanupMode,
103
102
  HostType,
104
103
  get_container_database,
105
104
  run_support_container,
@@ -447,7 +446,7 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
447
446
  @property
448
447
  def label(self) -> str:
449
448
  """Label to apply to resources related to this profile."""
450
- return f'{"controller" if self.controller else "target"}-{self.args.session_name}'
449
+ return f'{"controller" if self.controller else "target"}'
451
450
 
452
451
  def provision(self) -> None:
453
452
  """Provision the host before delegation."""
@@ -462,7 +461,7 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
462
461
  ports=[22],
463
462
  publish_ports=not self.controller, # connections to the controller over SSH are not required
464
463
  options=init_config.options,
465
- cleanup=CleanupMode.NO,
464
+ cleanup=False,
466
465
  cmd=self.build_init_command(init_config, init_probe),
467
466
  )
468
467
 
@@ -807,6 +806,7 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
807
806
  - Avoid hanging indefinitely or for an unreasonably long time.
808
807
 
809
808
  NOTE: The container must have a POSIX-compliant default shell "sh" with a non-builtin "sleep" command.
809
+ The "sleep" command is invoked through "env" to avoid using a shell builtin "sleep" (if present).
810
810
  """
811
811
  command = ''
812
812
 
@@ -814,7 +814,7 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
814
814
  command += f'{init_config.command} && '
815
815
 
816
816
  if sleep or init_config.command_privileged:
817
- command += 'sleep 60 ; '
817
+ command += 'env sleep 60 ; '
818
818
 
819
819
  if not command:
820
820
  return None
@@ -838,7 +838,7 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
838
838
  """Check the cgroup v1 systemd hierarchy to verify it is writeable for our container."""
839
839
  probe_script = (read_text_file(os.path.join(ANSIBLE_TEST_TARGET_ROOT, 'setup', 'check_systemd_cgroup_v1.sh'))
840
840
  .replace('@MARKER@', self.MARKER)
841
- .replace('@LABEL@', self.label))
841
+ .replace('@LABEL@', f'{self.label}-{self.args.session_name}'))
842
842
 
843
843
  cmd = ['sh']
844
844
 
@@ -853,7 +853,7 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
853
853
 
854
854
  def create_systemd_cgroup_v1(self) -> str:
855
855
  """Create a unique ansible-test cgroup in the v1 systemd hierarchy and return its path."""
856
- self.cgroup_path = f'/sys/fs/cgroup/systemd/ansible-test-{self.label}'
856
+ self.cgroup_path = f'/sys/fs/cgroup/systemd/ansible-test-{self.label}-{self.args.session_name}'
857
857
 
858
858
  # Privileged mode is required to create the cgroup directories on some hosts, such as Fedora 36 and RHEL 9.0.
859
859
  # The mkdir command will fail with "Permission denied" otherwise.
@@ -126,7 +126,7 @@ class HttpResponse:
126
126
  try:
127
127
  return json.loads(self.response)
128
128
  except ValueError:
129
- raise HttpError(self.status_code, 'Cannot parse response to %s %s as JSON:\n%s' % (self.method, self.url, self.response))
129
+ raise HttpError(self.status_code, 'Cannot parse response to %s %s as JSON:\n%s' % (self.method, self.url, self.response)) from None
130
130
 
131
131
 
132
132
  class HttpError(ApplicationError):
@@ -15,7 +15,7 @@ from xml.dom import minidom
15
15
  from xml.etree import ElementTree as ET
16
16
 
17
17
 
18
- @dataclasses.dataclass # type: ignore[misc] # https://github.com/python/mypy/issues/5374
18
+ @dataclasses.dataclass
19
19
  class TestResult(metaclass=abc.ABCMeta):
20
20
  """Base class for the result of a test case."""
21
21
 
@@ -76,7 +76,7 @@ def run_pypi_proxy(args: EnvironmentConfig, targets_use_pypi: bool) -> None:
76
76
  args=args,
77
77
  context='__pypi_proxy__',
78
78
  image=image,
79
- name=f'pypi-test-container-{args.session_name}',
79
+ name='pypi-test-container',
80
80
  ports=[port],
81
81
  )
82
82
 
@@ -297,7 +297,7 @@ def run_pip(
297
297
  connection.run([python.path], data=script, capture=True)
298
298
  except SubprocessError as ex:
299
299
  if 'pip is unavailable:' in ex.stdout + ex.stderr:
300
- raise PipUnavailableError(python)
300
+ raise PipUnavailableError(python) from None
301
301
 
302
302
  raise
303
303
 
@@ -441,8 +441,8 @@ def get_venv_packages(python: PythonConfig) -> dict[str, str]:
441
441
  # See: https://github.com/ansible/base-test-container/blob/main/files/installer.py
442
442
 
443
443
  default_packages = dict(
444
- pip='21.3.1',
445
- setuptools='60.8.2',
444
+ pip='23.1.2',
445
+ setuptools='67.7.2',
446
446
  wheel='0.37.1',
447
447
  )
448
448
 
@@ -452,11 +452,6 @@ def get_venv_packages(python: PythonConfig) -> dict[str, str]:
452
452
  setuptools='44.1.1', # 45.0.0 requires Python 3.5+
453
453
  wheel=None,
454
454
  ),
455
- '3.5': dict(
456
- pip='20.3.4', # 21.0 requires Python 3.6+
457
- setuptools='50.3.2', # 51.0.0 requires Python 3.6+
458
- wheel=None,
459
- ),
460
455
  '3.6': dict(
461
456
  pip='21.3.1', # 22.0 requires Python 3.7+
462
457
  setuptools='59.6.0', # 59.7.0 requires Python 3.7+
@@ -31,11 +31,6 @@ from termios import TIOCGWINSZ
31
31
  # CAUTION: Avoid third-party imports in this module whenever possible.
32
32
  # Any third-party imports occurring here will result in an error if they are vendored by ansible-core.
33
33
 
34
- try:
35
- from typing_extensions import TypeGuard # TypeGuard was added in Python 3.10
36
- except ImportError:
37
- TypeGuard = None
38
-
39
34
  from .locale_util import (
40
35
  LOCALE_WARNING,
41
36
  CONFIGURED_LOCALE,
@@ -1155,7 +1150,7 @@ def verify_sys_executable(path: str) -> t.Optional[str]:
1155
1150
  return expected_executable
1156
1151
 
1157
1152
 
1158
- def type_guard(sequence: c.Sequence[t.Any], guard_type: t.Type[C]) -> TypeGuard[c.Sequence[C]]:
1153
+ def type_guard(sequence: c.Sequence[t.Any], guard_type: t.Type[C]) -> t.TypeGuard[c.Sequence[C]]:
1159
1154
  """
1160
1155
  Raises an exception if any item in the given sequence does not match the specified guard type.
1161
1156
  Use with assert so that type checkers are aware of the type guard.
@@ -2,6 +2,10 @@
2
2
  "extensions": [
3
3
  ".py"
4
4
  ],
5
+ "prefixes": [
6
+ "lib/ansible/",
7
+ "plugins/"
8
+ ],
5
9
  "ignore_self": true,
6
10
  "output": "path-line-column-message"
7
11
  }
@@ -2,6 +2,10 @@
2
2
  "extensions": [
3
3
  ".py"
4
4
  ],
5
+ "prefixes": [
6
+ "lib/ansible/",
7
+ "plugins/"
8
+ ],
5
9
  "ignore_self": true,
6
10
  "output": "path-line-column-message"
7
11
  }
@@ -2,5 +2,9 @@
2
2
  "extensions": [
3
3
  ".py"
4
4
  ],
5
+ "prefixes": [
6
+ "lib/ansible/",
7
+ "plugins/"
8
+ ],
5
9
  "output": "path-line-column-message"
6
10
  }
@@ -34,6 +34,9 @@ ignore_missing_imports = True
34
34
  [mypy-md5.*]
35
35
  ignore_missing_imports = True
36
36
 
37
+ [mypy-imp.*]
38
+ ignore_missing_imports = True
39
+
37
40
  [mypy-scp.*]
38
41
  ignore_missing_imports = True
39
42
 
@@ -57,3 +57,5 @@ preferred-modules =
57
57
  # Listing them here makes it possible to enable the import-error check.
58
58
  ignored-modules =
59
59
  py,
60
+ pytest,
61
+ _pytest.runner,
@@ -7,7 +7,6 @@ disable=
7
7
  deprecated-module, # results vary by Python version
8
8
  duplicate-code, # consistent results require running with --jobs 1 and testing all files
9
9
  import-outside-toplevel, # common pattern in ansible related code
10
- raise-missing-from, # Python 2.x does not support raise from
11
10
  broad-exception-raised, # many exceptions with no need for a custom type
12
11
  too-few-public-methods,
13
12
  too-many-public-methods,
@@ -30,6 +30,7 @@ disable=
30
30
  consider-using-max-builtin,
31
31
  consider-using-min-builtin,
32
32
  cyclic-import, # consistent results require running with --jobs 1 and testing all files
33
+ deprecated-comment, # custom plugin only used by ansible-core, not collections
33
34
  deprecated-method, # results vary by Python version
34
35
  deprecated-module, # results vary by Python version
35
36
  duplicate-code, # consistent results require running with --jobs 1 and testing all files