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
@@ -51,7 +51,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
51
51
  self, # type: CollectionDependencyProviderBase
52
52
  apis, # type: MultiGalaxyAPIProxy
53
53
  concrete_artifacts_manager=None, # type: ConcreteArtifactsManager
54
- user_requirements=None, # type: t.Iterable[Requirement]
55
54
  preferred_candidates=None, # type: t.Iterable[Candidate]
56
55
  with_deps=True, # type: bool
57
56
  with_pre_releases=False, # type: bool
@@ -87,58 +86,12 @@ class CollectionDependencyProviderBase(AbstractProvider):
87
86
  Requirement.from_requirement_dict,
88
87
  art_mgr=concrete_artifacts_manager,
89
88
  )
90
- self._pinned_candidate_requests = set(
91
- # NOTE: User-provided signatures are supplemental, so signatures
92
- # NOTE: are not used to determine if a candidate is user-requested
93
- Candidate(req.fqcn, req.ver, req.src, req.type, None)
94
- for req in (user_requirements or ())
95
- if req.is_concrete_artifact or (
96
- req.ver != '*' and
97
- not req.ver.startswith(('<', '>', '!='))
98
- )
99
- )
100
89
  self._preferred_candidates = set(preferred_candidates or ())
101
90
  self._with_deps = with_deps
102
91
  self._with_pre_releases = with_pre_releases
103
92
  self._upgrade = upgrade
104
93
  self._include_signatures = include_signatures
105
94
 
106
- def _is_user_requested(self, candidate): # type: (Candidate) -> bool
107
- """Check if the candidate is requested by the user."""
108
- if candidate in self._pinned_candidate_requests:
109
- return True
110
-
111
- if candidate.is_online_index_pointer and candidate.src is not None:
112
- # NOTE: Candidate is a namedtuple, it has a source server set
113
- # NOTE: to a specific GalaxyAPI instance or `None`. When the
114
- # NOTE: user runs
115
- # NOTE:
116
- # NOTE: $ ansible-galaxy collection install ns.coll
117
- # NOTE:
118
- # NOTE: then it's saved in `self._pinned_candidate_requests`
119
- # NOTE: as `('ns.coll', '*', None, 'galaxy')` but then
120
- # NOTE: `self.find_matches()` calls `self.is_satisfied_by()`
121
- # NOTE: with Candidate instances bound to each specific
122
- # NOTE: server available, those look like
123
- # NOTE: `('ns.coll', '*', GalaxyAPI(...), 'galaxy')` and
124
- # NOTE: wouldn't match the user requests saved in
125
- # NOTE: `self._pinned_candidate_requests`. This is why we
126
- # NOTE: normalize the collection to have `src=None` and try
127
- # NOTE: again.
128
- # NOTE:
129
- # NOTE: When the user request comes from `requirements.yml`
130
- # NOTE: with the `source:` set, it'll match the first check
131
- # NOTE: but it still can have entries with `src=None` so this
132
- # NOTE: normalized check is still necessary.
133
- # NOTE:
134
- # NOTE: User-provided signatures are supplemental, so signatures
135
- # NOTE: are not used to determine if a candidate is user-requested
136
- return Candidate(
137
- candidate.fqcn, candidate.ver, None, candidate.type, None
138
- ) in self._pinned_candidate_requests
139
-
140
- return False
141
-
142
95
  def identify(self, requirement_or_candidate):
143
96
  # type: (t.Union[Candidate, Requirement]) -> str
144
97
  """Given requirement or candidate, return an identifier for it.
@@ -342,25 +295,79 @@ class CollectionDependencyProviderBase(AbstractProvider):
342
295
  latest_matches = []
343
296
  signatures = []
344
297
  extra_signature_sources = [] # type: list[str]
298
+
299
+ discarding_pre_releases_acceptable = any(
300
+ not is_pre_release(candidate_version)
301
+ for candidate_version, _src_server in coll_versions
302
+ )
303
+
304
+ # NOTE: The optimization of conditionally looping over the requirements
305
+ # NOTE: is used to skip having to compute the pinned status of all
306
+ # NOTE: requirements and apply version normalization to the found ones.
307
+ all_pinned_requirement_version_numbers = {
308
+ # NOTE: Pinned versions can start with a number, but also with an
309
+ # NOTE: equals sign. Stripping it at the beginning should be
310
+ # NOTE: enough. If there's a space after equals, the second strip
311
+ # NOTE: will take care of it.
312
+ # NOTE: Without this conversion, requirements versions like
313
+ # NOTE: '1.2.3-alpha.4' work, but '=1.2.3-alpha.4' don't.
314
+ requirement.ver.lstrip('=').strip()
315
+ for requirement in requirements
316
+ if requirement.is_pinned
317
+ } if discarding_pre_releases_acceptable else set()
318
+
345
319
  for version, src_server in coll_versions:
346
320
  tmp_candidate = Candidate(fqcn, version, src_server, 'galaxy', None)
347
321
 
348
- unsatisfied = False
349
322
  for requirement in requirements:
350
- unsatisfied |= not self.is_satisfied_by(requirement, tmp_candidate)
323
+ candidate_satisfies_requirement = self.is_satisfied_by(
324
+ requirement, tmp_candidate,
325
+ )
326
+ if not candidate_satisfies_requirement:
327
+ break
328
+
329
+ should_disregard_pre_release_candidate = (
330
+ # NOTE: Do not discard pre-release candidates in the
331
+ # NOTE: following cases:
332
+ # NOTE: * the end-user requested pre-releases explicitly;
333
+ # NOTE: * the candidate is a concrete artifact (e.g. a
334
+ # NOTE: Git repository, subdirs, a tarball URL, or a
335
+ # NOTE: local dir or file etc.);
336
+ # NOTE: * the candidate's pre-release version exactly
337
+ # NOTE: matches a version specifically requested by one
338
+ # NOTE: of the requirements in the current match
339
+ # NOTE: discovery round (i.e. matching a requirement
340
+ # NOTE: that is not a range but an explicit specific
341
+ # NOTE: version pin). This works when some requirements
342
+ # NOTE: request version ranges but others (possibly on
343
+ # NOTE: different dependency tree level depths) demand
344
+ # NOTE: pre-release dependency versions, even if those
345
+ # NOTE: dependencies are transitive.
346
+ is_pre_release(tmp_candidate.ver)
347
+ and discarding_pre_releases_acceptable
348
+ and not (
349
+ self._with_pre_releases
350
+ or tmp_candidate.is_concrete_artifact
351
+ or version in all_pinned_requirement_version_numbers
352
+ )
353
+ )
354
+ if should_disregard_pre_release_candidate:
355
+ break
356
+
351
357
  # FIXME
352
- # unsatisfied |= not self.is_satisfied_by(requirement, tmp_candidate) or not (
353
- # requirement.src is None or # if this is true for some candidates but not all it will break key param - Nonetype can't be compared to str
358
+ # candidate_is_from_requested_source = (
359
+ # requirement.src is None # if this is true for some candidates but not all it will break key param - Nonetype can't be compared to str
354
360
  # or requirement.src == candidate.src
355
361
  # )
356
- if unsatisfied:
357
- break
362
+ # if not candidate_is_from_requested_source:
363
+ # break
364
+
358
365
  if not self._include_signatures:
359
366
  continue
360
367
 
361
368
  extra_signature_sources.extend(requirement.signature_sources or [])
362
369
 
363
- if not unsatisfied:
370
+ else: # candidate satisfies requirements, `break` never happened
364
371
  if self._include_signatures:
365
372
  for extra_source in extra_signature_sources:
366
373
  signatures.append(get_signature_from_source(extra_source))
@@ -405,21 +412,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
405
412
  :returns: Indication whether the `candidate` is a viable \
406
413
  solution to the `requirement`.
407
414
  """
408
- # NOTE: Only allow pre-release candidates if we want pre-releases
409
- # NOTE: or the req ver was an exact match with the pre-release
410
- # NOTE: version. Another case where we'd want to allow
411
- # NOTE: pre-releases is when there are several user requirements
412
- # NOTE: and one of them is a pre-release that also matches a
413
- # NOTE: transitive dependency of another requirement.
414
- allow_pre_release = self._with_pre_releases or not (
415
- requirement.ver == '*' or
416
- requirement.ver.startswith('<') or
417
- requirement.ver.startswith('>') or
418
- requirement.ver.startswith('!=')
419
- ) or self._is_user_requested(candidate)
420
- if is_pre_release(candidate.ver) and not allow_pre_release:
421
- return False
422
-
423
415
  # NOTE: This is a set of Pipenv-inspired optimizations. Ref:
424
416
  # https://github.com/sarugaku/passa/blob/2ac00f1/src/passa/models/providers.py#L58-L74
425
417
  if (
ansible/galaxy/role.py CHANGED
@@ -36,7 +36,7 @@ from ansible import context
36
36
  from ansible.errors import AnsibleError, AnsibleParserError
37
37
  from ansible.galaxy.api import GalaxyAPI
38
38
  from ansible.galaxy.user_agent import user_agent
39
- from ansible.module_utils._text import to_native, to_text
39
+ from ansible.module_utils.common.text.converters import to_native, to_text
40
40
  from ansible.module_utils.common.yaml import yaml_dump, yaml_load
41
41
  from ansible.module_utils.compat.version import LooseVersion
42
42
  from ansible.module_utils.urls import open_url
@@ -211,7 +211,7 @@ class GalaxyRole(object):
211
211
 
212
212
  info = dict(
213
213
  version=self.version,
214
- install_date=datetime.datetime.utcnow().strftime("%c"),
214
+ install_date=datetime.datetime.now(datetime.timezone.utc).strftime("%c"),
215
215
  )
216
216
  if not os.path.exists(os.path.join(self.path, 'meta')):
217
217
  os.makedirs(os.path.join(self.path, 'meta'))
@@ -394,18 +394,36 @@ class GalaxyRole(object):
394
394
  # bits that might be in the file for security purposes
395
395
  # and drop any containing directory, as mentioned above
396
396
  if member.isreg() or member.issym():
397
- n_member_name = to_native(member.name)
398
- n_archive_parent_dir = to_native(archive_parent_dir)
399
- n_parts = n_member_name.replace(n_archive_parent_dir, "", 1).split(os.sep)
400
- n_final_parts = []
401
- for n_part in n_parts:
402
- # TODO if the condition triggers it produces a broken installation.
403
- # It will create the parent directory as an empty file and will
404
- # explode if the directory contains valid files.
405
- # Leaving this as is since the whole module needs a rewrite.
406
- if n_part != '..' and not n_part.startswith('~') and '$' not in n_part:
397
+ for attr in ('name', 'linkname'):
398
+ attr_value = getattr(member, attr, None)
399
+ if not attr_value:
400
+ continue
401
+ n_attr_value = to_native(attr_value)
402
+ n_archive_parent_dir = to_native(archive_parent_dir)
403
+ n_parts = n_attr_value.replace(n_archive_parent_dir, "", 1).split(os.sep)
404
+ n_final_parts = []
405
+ for n_part in n_parts:
406
+ # TODO if the condition triggers it produces a broken installation.
407
+ # It will create the parent directory as an empty file and will
408
+ # explode if the directory contains valid files.
409
+ # Leaving this as is since the whole module needs a rewrite.
410
+ #
411
+ # Check if we have any files with illegal names,
412
+ # and display a warning if so. This could help users
413
+ # to debug a broken installation.
414
+ if not n_part:
415
+ continue
416
+ if n_part == '..':
417
+ display.warning(f"Illegal filename '{n_part}': '..' is not allowed")
418
+ continue
419
+ if n_part.startswith('~'):
420
+ display.warning(f"Illegal filename '{n_part}': names cannot start with '~'")
421
+ continue
422
+ if '$' in n_part:
423
+ display.warning(f"Illegal filename '{n_part}': names cannot contain '$'")
424
+ continue
407
425
  n_final_parts.append(n_part)
408
- member.name = os.path.join(*n_final_parts)
426
+ setattr(member, attr, os.path.join(*n_final_parts))
409
427
 
410
428
  if _check_working_data_filter():
411
429
  # deprecated: description='extract fallback without filter' python_version='3.11'
ansible/galaxy/token.py CHANGED
@@ -28,7 +28,7 @@ from stat import S_IRUSR, S_IWUSR
28
28
 
29
29
  from ansible import constants as C
30
30
  from ansible.galaxy.user_agent import user_agent
31
- from ansible.module_utils._text import to_bytes, to_native, to_text
31
+ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
32
32
  from ansible.module_utils.common.yaml import yaml_dump, yaml_load
33
33
  from ansible.module_utils.urls import open_url
34
34
  from ansible.utils.display import Display
@@ -69,7 +69,7 @@ class KeycloakToken(object):
69
69
 
70
70
  # - build a request to POST to auth_url
71
71
  # - body is form encoded
72
- # - 'request_token' is the offline token stored in ansible.cfg
72
+ # - 'refresh_token' is the offline token stored in ansible.cfg
73
73
  # - 'grant_type' is 'refresh_token'
74
74
  # - 'client_id' is 'cloud-services'
75
75
  # - should probably be based on the contents of the
@@ -22,7 +22,7 @@ from itertools import chain
22
22
 
23
23
  from ansible import constants as C
24
24
  from ansible.errors import AnsibleError
25
- from ansible.module_utils._text import to_native, to_text
25
+ from ansible.module_utils.common.text.converters import to_native, to_text
26
26
  from ansible.utils.display import Display
27
27
  from ansible.utils.vars import combine_vars
28
28
 
@@ -33,7 +33,7 @@ from ansible import constants as C
33
33
  from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
34
34
  from ansible.inventory.data import InventoryData
35
35
  from ansible.module_utils.six import string_types
36
- from ansible.module_utils._text import to_bytes, to_text
36
+ from ansible.module_utils.common.text.converters import to_bytes, to_text
37
37
  from ansible.parsing.utils.addresses import parse_address
38
38
  from ansible.plugins.loader import inventory_loader
39
39
  from ansible.utils.helpers import deduplicate_list
@@ -19,6 +19,6 @@
19
19
  from __future__ import (absolute_import, division, print_function)
20
20
  __metaclass__ = type
21
21
 
22
- __version__ = '2.15.4rc1'
22
+ __version__ = '2.16.0b2'
23
23
  __author__ = 'Ansible, Inc.'
24
- __codename__ = "Ten Years Gone"
24
+ __codename__ = "All My Love"
@@ -9,40 +9,17 @@ import sys
9
9
 
10
10
  # Used for determining if the system is running a new enough python version
11
11
  # and should only restrict on our documented minimum versions
12
- _PY3_MIN = sys.version_info >= (3, 5)
12
+ _PY3_MIN = sys.version_info >= (3, 6)
13
13
  _PY2_MIN = (2, 7) <= sys.version_info < (3,)
14
14
  _PY_MIN = _PY3_MIN or _PY2_MIN
15
15
 
16
16
  if not _PY_MIN:
17
17
  print(
18
18
  '\n{"failed": true, '
19
- '"msg": "ansible-core requires a minimum of Python2 version 2.7 or Python3 version 3.5. Current version: %s"}' % ''.join(sys.version.splitlines())
19
+ '"msg": "ansible-core requires a minimum of Python2 version 2.7 or Python3 version 3.6. Current version: %s"}' % ''.join(sys.version.splitlines())
20
20
  )
21
21
  sys.exit(1)
22
22
 
23
- FILE_ATTRIBUTES = {
24
- 'A': 'noatime',
25
- 'a': 'append',
26
- 'c': 'compressed',
27
- 'C': 'nocow',
28
- 'd': 'nodump',
29
- 'D': 'dirsync',
30
- 'e': 'extents',
31
- 'E': 'encrypted',
32
- 'h': 'blocksize',
33
- 'i': 'immutable',
34
- 'I': 'indexed',
35
- 'j': 'journalled',
36
- 'N': 'inline',
37
- 's': 'zero',
38
- 'S': 'synchronous',
39
- 't': 'notail',
40
- 'T': 'blockroot',
41
- 'u': 'undelete',
42
- 'X': 'compressedraw',
43
- 'Z': 'compresseddirty',
44
- }
45
-
46
23
  # Ansible modules can be written in any language.
47
24
  # The functions available here can be used to do many common tasks,
48
25
  # to simplify development of Python modules.
@@ -172,6 +149,7 @@ from ansible.module_utils.common.file import (
172
149
  is_executable,
173
150
  format_attributes,
174
151
  get_flags_from_attributes,
152
+ FILE_ATTRIBUTES,
175
153
  )
176
154
  from ansible.module_utils.common.sys_info import (
177
155
  get_distribution,
@@ -265,8 +243,8 @@ PASSWD_ARG_RE = re.compile(r'^[-]{0,2}pass[-]?(word|wd)?')
265
243
 
266
244
  # Used for parsing symbolic file perms
267
245
  MODE_OPERATOR_RE = re.compile(r'[+=-]')
268
- USERS_RE = re.compile(r'[^ugo]')
269
- PERMS_RE = re.compile(r'[^rwxXstugo]')
246
+ USERS_RE = re.compile(r'^[ugo]+$')
247
+ PERMS_RE = re.compile(r'^[rwxXstugo]*$')
270
248
 
271
249
 
272
250
  #
@@ -1063,18 +1041,18 @@ class AnsibleModule(object):
1063
1041
 
1064
1042
  # Check if there are illegal characters in the user list
1065
1043
  # They can end up in 'users' because they are not split
1066
- if USERS_RE.match(users):
1044
+ if not USERS_RE.match(users):
1067
1045
  raise ValueError("bad symbolic permission for mode: %s" % mode)
1068
1046
 
1069
1047
  # Now we have two list of equal length, one contains the requested
1070
1048
  # permissions and one with the corresponding operators.
1071
1049
  for idx, perms in enumerate(permlist):
1072
1050
  # Check if there are illegal characters in the permissions
1073
- if PERMS_RE.match(perms):
1051
+ if not PERMS_RE.match(perms):
1074
1052
  raise ValueError("bad symbolic permission for mode: %s" % mode)
1075
1053
 
1076
1054
  for user in users:
1077
- mode_to_apply = cls._get_octal_mode_from_symbolic_perms(path_stat, user, perms, use_umask)
1055
+ mode_to_apply = cls._get_octal_mode_from_symbolic_perms(path_stat, user, perms, use_umask, new_mode)
1078
1056
  new_mode = cls._apply_operation_to_mode(user, opers[idx], mode_to_apply, new_mode)
1079
1057
 
1080
1058
  return new_mode
@@ -1099,9 +1077,9 @@ class AnsibleModule(object):
1099
1077
  return new_mode
1100
1078
 
1101
1079
  @staticmethod
1102
- def _get_octal_mode_from_symbolic_perms(path_stat, user, perms, use_umask):
1103
- prev_mode = stat.S_IMODE(path_stat.st_mode)
1104
-
1080
+ def _get_octal_mode_from_symbolic_perms(path_stat, user, perms, use_umask, prev_mode=None):
1081
+ if prev_mode is None:
1082
+ prev_mode = stat.S_IMODE(path_stat.st_mode)
1105
1083
  is_directory = stat.S_ISDIR(path_stat.st_mode)
1106
1084
  has_x_permissions = (prev_mode & EXEC_PERM_BITS) > 0
1107
1085
  apply_X_permission = is_directory or has_x_permissions
@@ -1715,14 +1693,6 @@ class AnsibleModule(object):
1715
1693
  tmp_dest_fd, tmp_dest_name = tempfile.mkstemp(prefix=b'.ansible_tmp', dir=b_dest_dir, suffix=b_suffix)
1716
1694
  except (OSError, IOError) as e:
1717
1695
  error_msg = 'The destination directory (%s) is not writable by the current user. Error was: %s' % (os.path.dirname(dest), to_native(e))
1718
- except TypeError:
1719
- # We expect that this is happening because python3.4.x and
1720
- # below can't handle byte strings in mkstemp().
1721
- # Traceback would end in something like:
1722
- # file = _os.path.join(dir, pre + name + suf)
1723
- # TypeError: can't concat bytes to str
1724
- error_msg = ('Failed creating tmp file for atomic move. This usually happens when using Python3 less than Python3.5. '
1725
- 'Please use Python2.x or Python3.5 or greater.')
1726
1696
  finally:
1727
1697
  if error_msg:
1728
1698
  if unsafe_writes:
@@ -7,12 +7,6 @@ __metaclass__ = type
7
7
  import os
8
8
  import stat
9
9
  import re
10
- import time
11
- import fcntl
12
- import sys
13
-
14
- from contextlib import contextmanager
15
- from ansible.module_utils.common.warnings import deprecate
16
10
 
17
11
  try:
18
12
  import selinux # pylint: disable=unused-import
@@ -102,97 +96,3 @@ def get_file_arg_spec():
102
96
  attributes=dict(aliases=['attr']),
103
97
  )
104
98
  return arg_spec
105
-
106
-
107
- class LockTimeout(Exception):
108
- pass
109
-
110
-
111
- class FileLock:
112
- '''
113
- Currently FileLock is implemented via fcntl.flock on a lock file, however this
114
- behaviour may change in the future. Avoid mixing lock types fcntl.flock,
115
- fcntl.lockf and module_utils.common.file.FileLock as it will certainly cause
116
- unwanted and/or unexpected behaviour
117
- '''
118
- def __init__(self):
119
- deprecate("FileLock is not reliable and has never been used in core for that reason. There is no current alternative that works across POSIX targets",
120
- version='2.16')
121
- self.lockfd = None
122
-
123
- @contextmanager
124
- def lock_file(self, path, tmpdir, lock_timeout=None):
125
- '''
126
- Context for lock acquisition
127
- '''
128
- try:
129
- self.set_lock(path, tmpdir, lock_timeout)
130
- yield
131
- finally:
132
- self.unlock()
133
-
134
- def set_lock(self, path, tmpdir, lock_timeout=None):
135
- '''
136
- Create a lock file based on path with flock to prevent other processes
137
- using given path.
138
- Please note that currently file locking only works when it's executed by
139
- the same user, I.E single user scenarios
140
-
141
- :kw path: Path (file) to lock
142
- :kw tmpdir: Path where to place the temporary .lock file
143
- :kw lock_timeout:
144
- Wait n seconds for lock acquisition, fail if timeout is reached.
145
- 0 = Do not wait, fail if lock cannot be acquired immediately,
146
- Default is None, wait indefinitely until lock is released.
147
- :returns: True
148
- '''
149
- lock_path = os.path.join(tmpdir, 'ansible-{0}.lock'.format(os.path.basename(path)))
150
- l_wait = 0.1
151
- r_exception = IOError
152
- if sys.version_info[0] == 3:
153
- r_exception = BlockingIOError
154
-
155
- self.lockfd = open(lock_path, 'w')
156
-
157
- if lock_timeout <= 0:
158
- fcntl.flock(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
159
- os.chmod(lock_path, stat.S_IWRITE | stat.S_IREAD)
160
- return True
161
-
162
- if lock_timeout:
163
- e_secs = 0
164
- while e_secs < lock_timeout:
165
- try:
166
- fcntl.flock(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
167
- os.chmod(lock_path, stat.S_IWRITE | stat.S_IREAD)
168
- return True
169
- except r_exception:
170
- time.sleep(l_wait)
171
- e_secs += l_wait
172
- continue
173
-
174
- self.lockfd.close()
175
- raise LockTimeout('{0} sec'.format(lock_timeout))
176
-
177
- fcntl.flock(self.lockfd, fcntl.LOCK_EX)
178
- os.chmod(lock_path, stat.S_IWRITE | stat.S_IREAD)
179
-
180
- return True
181
-
182
- def unlock(self):
183
- '''
184
- Make sure lock file is available for everyone and Unlock the file descriptor
185
- locked by set_lock
186
-
187
- :returns: True
188
- '''
189
- if not self.lockfd:
190
- return True
191
-
192
- try:
193
- fcntl.flock(self.lockfd, fcntl.LOCK_UN)
194
- self.lockfd.close()
195
- except ValueError: # file wasn't opened, let context manager fail gracefully
196
- pass
197
-
198
- return True
@@ -10,7 +10,7 @@ import json
10
10
 
11
11
  import datetime
12
12
 
13
- from ansible.module_utils._text import to_text
13
+ from ansible.module_utils.common.text.converters import to_text
14
14
  from ansible.module_utils.six.moves.collections_abc import Mapping
15
15
  from ansible.module_utils.common.collections import is_sequence
16
16
 
@@ -4,7 +4,7 @@
4
4
  from __future__ import absolute_import, division, print_function
5
5
  __metaclass__ = type
6
6
 
7
- from ansible.module_utils._text import to_native
7
+ from ansible.module_utils.common.text.converters import to_native
8
8
 
9
9
 
10
10
  def get_best_parsable_locale(module, preferences=None, raise_on_locale=False):
@@ -168,7 +168,7 @@ def to_text(obj, encoding='utf-8', errors=None, nonstring='simplerepr'):
168
168
  handler, otherwise it will use replace.
169
169
  :surrogate_then_replace: Does the same as surrogate_or_replace but
170
170
  `was added for symmetry with the error handlers in
171
- :func:`ansible.module_utils._text.to_bytes` (Added in Ansible 2.3)
171
+ :func:`ansible.module_utils.common.text.converters.to_bytes` (Added in Ansible 2.3)
172
172
 
173
173
  Because surrogateescape was added in Python3 this usually means that
174
174
  Python3 will use `surrogateescape` and Python2 will use the fallback
@@ -179,7 +179,7 @@ def to_text(obj, encoding='utf-8', errors=None, nonstring='simplerepr'):
179
179
 
180
180
  The default until Ansible-2.2 was `surrogate_or_replace`
181
181
  In Ansible-2.3 this defaults to `surrogate_then_replace` for symmetry
182
- with :func:`ansible.module_utils._text.to_bytes` .
182
+ with :func:`ansible.module_utils.common.text.converters.to_bytes` .
183
183
  :kwarg nonstring: The strategy to use if a nonstring is specified in
184
184
  ``obj``. Default is 'simplerepr'. Valid values are:
185
185
 
@@ -9,7 +9,7 @@ import os
9
9
  import re
10
10
 
11
11
  from ast import literal_eval
12
- from ansible.module_utils._text import to_native
12
+ from ansible.module_utils.common.text.converters import to_native
13
13
  from ansible.module_utils.common._json_compat import json
14
14
  from ansible.module_utils.common.collections import is_iterable
15
15
  from ansible.module_utils.common.text.converters import jsonify
@@ -81,7 +81,7 @@ def _fileobj_to_fd(fileobj):
81
81
 
82
82
  # Python 3.5 uses a more direct route to wrap system calls to increase speed.
83
83
  if sys.version_info >= (3, 5):
84
- def _syscall_wrapper(func, _, *args, **kwargs):
84
+ def _syscall_wrapper(func, dummy, *args, **kwargs):
85
85
  """ This is the short-circuit version of the below logic
86
86
  because in Python 3.5+ all selectors restart system calls. """
87
87
  try:
@@ -342,8 +342,8 @@ if hasattr(select, "select"):
342
342
 
343
343
  timeout = None if timeout is None else max(timeout, 0.0)
344
344
  ready = []
345
- r, w, _ = _syscall_wrapper(self._select, True, self._readers,
346
- self._writers, timeout=timeout)
345
+ r, w, dummy = _syscall_wrapper(self._select, True, self._readers,
346
+ self._writers, timeout=timeout)
347
347
  r = set(r)
348
348
  w = set(w)
349
349
  for fd in r | w:
@@ -649,7 +649,7 @@ elif 'PollSelector' in globals(): # Platform-specific: Linux
649
649
  elif 'SelectSelector' in globals(): # Platform-specific: Windows
650
650
  DefaultSelector = SelectSelector
651
651
  else: # Platform-specific: AppEngine
652
- def no_selector(_):
652
+ def no_selector(dummy):
653
653
  raise ValueError("Platform does not have a selector")
654
654
  DefaultSelector = no_selector
655
655
  HAS_SELECT = False
@@ -0,0 +1,40 @@
1
+ # Copyright (c) 2023 Ansible
2
+ # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
3
+
4
+ # Make coding more python3-ish
5
+ from __future__ import (absolute_import, division, print_function)
6
+ __metaclass__ = type
7
+
8
+ from ansible.module_utils.six import PY3
9
+
10
+ import datetime
11
+
12
+
13
+ if PY3:
14
+ UTC = datetime.timezone.utc
15
+ else:
16
+ _ZERO = datetime.timedelta(0)
17
+
18
+ class _UTC(datetime.tzinfo):
19
+ __slots__ = ()
20
+
21
+ def utcoffset(self, dt):
22
+ return _ZERO
23
+
24
+ def dst(self, dt):
25
+ return _ZERO
26
+
27
+ def tzname(self, dt):
28
+ return "UTC"
29
+
30
+ UTC = _UTC()
31
+
32
+
33
+ def utcfromtimestamp(timestamp): # type: (float) -> datetime.datetime
34
+ """Construct an aware UTC datetime from a POSIX timestamp."""
35
+ return datetime.datetime.fromtimestamp(timestamp, UTC)
36
+
37
+
38
+ def utcnow(): # type: () -> datetime.datetime
39
+ """Construct an aware UTC datetime from time.time()."""
40
+ return datetime.datetime.now(UTC)
@@ -62,7 +62,7 @@ def _module_setup():
62
62
  fn.restype = cfg.get('restype', c_int)
63
63
 
64
64
  # just patch simple directly callable functions directly onto the module
65
- if not fn.argtypes or not any(argtype for argtype in fn.argtypes if type(argtype) == base_ptr_type):
65
+ if not fn.argtypes or not any(argtype for argtype in fn.argtypes if type(argtype) is base_ptr_type):
66
66
  setattr(_thismod, fname, fn)
67
67
  continue
68
68
 
@@ -13,7 +13,7 @@ except Exception: # pylint: disable=broad-except
13
13
  pass
14
14
 
15
15
  try:
16
- from typing import * # type: ignore[assignment]
16
+ from typing import * # type: ignore[assignment,no-redef]
17
17
  except Exception: # pylint: disable=broad-except
18
18
  pass
19
19
 
@@ -38,7 +38,7 @@ import traceback
38
38
  import uuid
39
39
 
40
40
  from functools import partial
41
- from ansible.module_utils._text import to_bytes, to_text
41
+ from ansible.module_utils.common.text.converters import to_bytes, to_text
42
42
  from ansible.module_utils.common.json import AnsibleJSONEncoder
43
43
  from ansible.module_utils.six import iteritems
44
44
  from ansible.module_utils.six.moves import cPickle