ansible-core 2.17.6__py3-none-any.whl → 2.18.0__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 (325) hide show
  1. ansible/__main__.py +2 -17
  2. ansible/cli/__init__.py +3 -15
  3. ansible/cli/config.py +187 -24
  4. ansible/cli/console.py +1 -1
  5. ansible/cli/doc.py +38 -16
  6. ansible/cli/galaxy.py +3 -49
  7. ansible/cli/inventory.py +2 -2
  8. ansible/cli/pull.py +2 -2
  9. ansible/cli/scripts/ansible_connection_cli_stub.py +1 -10
  10. ansible/config/base.yml +127 -57
  11. ansible/config/manager.py +89 -11
  12. ansible/constants.py +32 -9
  13. ansible/errors/__init__.py +5 -0
  14. ansible/executor/interpreter_discovery.py +1 -1
  15. ansible/executor/play_iterator.py +16 -0
  16. ansible/executor/playbook_executor.py +1 -4
  17. ansible/executor/powershell/become_wrapper.ps1 +4 -5
  18. ansible/executor/powershell/bootstrap_wrapper.ps1 +2 -3
  19. ansible/executor/powershell/exec_wrapper.ps1 +1 -1
  20. ansible/executor/powershell/module_manifest.py +2 -2
  21. ansible/executor/task_executor.py +50 -39
  22. ansible/executor/task_queue_manager.py +1 -1
  23. ansible/executor/task_result.py +1 -1
  24. ansible/galaxy/api.py +3 -4
  25. ansible/galaxy/collection/__init__.py +21 -10
  26. ansible/galaxy/collection/concrete_artifact_manager.py +2 -2
  27. ansible/galaxy/collection/galaxy_api_proxy.py +10 -16
  28. ansible/galaxy/collection/gpg.py +17 -23
  29. ansible/galaxy/data/COPYING +7 -0
  30. ansible/galaxy/data/apb/Dockerfile.j2 +1 -0
  31. ansible/galaxy/data/apb/Makefile.j2 +1 -0
  32. ansible/galaxy/data/apb/README.md +7 -3
  33. ansible/galaxy/data/apb/apb.yml.j2 +1 -0
  34. ansible/galaxy/data/apb/defaults/main.yml.j2 +1 -0
  35. ansible/galaxy/data/apb/handlers/main.yml.j2 +1 -0
  36. ansible/galaxy/data/apb/meta/main.yml.j2 +1 -0
  37. ansible/galaxy/data/apb/playbooks/deprovision.yml.j2 +1 -0
  38. ansible/galaxy/data/apb/playbooks/provision.yml.j2 +1 -0
  39. ansible/galaxy/data/apb/tasks/main.yml.j2 +1 -0
  40. ansible/galaxy/data/apb/tests/ansible.cfg +1 -0
  41. ansible/galaxy/data/apb/tests/inventory +1 -0
  42. ansible/galaxy/data/apb/tests/test.yml.j2 +1 -0
  43. ansible/galaxy/data/apb/vars/main.yml.j2 +1 -0
  44. ansible/galaxy/data/collections_galaxy_meta.yml +1 -0
  45. ansible/galaxy/data/container/defaults/main.yml.j2 +1 -0
  46. ansible/galaxy/data/container/handlers/main.yml.j2 +1 -0
  47. ansible/galaxy/data/container/meta/container.yml.j2 +1 -0
  48. ansible/galaxy/data/container/meta/main.yml.j2 +1 -0
  49. ansible/galaxy/data/container/tasks/main.yml.j2 +1 -0
  50. ansible/galaxy/data/container/tests/ansible.cfg +1 -0
  51. ansible/galaxy/data/container/tests/inventory +1 -0
  52. ansible/galaxy/data/container/tests/test.yml.j2 +1 -0
  53. ansible/galaxy/data/container/vars/main.yml.j2 +1 -0
  54. ansible/galaxy/data/default/collection/README.md.j2 +1 -0
  55. ansible/galaxy/data/default/collection/galaxy.yml.j2 +1 -0
  56. ansible/galaxy/data/default/collection/meta/runtime.yml +1 -0
  57. ansible/galaxy/data/default/collection/plugins/README.md.j2 +1 -0
  58. ansible/galaxy/data/default/role/defaults/main.yml.j2 +1 -0
  59. ansible/galaxy/data/default/role/handlers/main.yml.j2 +1 -0
  60. ansible/galaxy/data/default/role/meta/main.yml.j2 +1 -0
  61. ansible/galaxy/data/default/role/tasks/main.yml.j2 +1 -0
  62. ansible/galaxy/data/default/role/tests/inventory +1 -0
  63. ansible/galaxy/data/default/role/tests/test.yml.j2 +1 -0
  64. ansible/galaxy/data/default/role/vars/main.yml.j2 +1 -0
  65. ansible/galaxy/data/network/cliconf_plugins/example.py.j2 +1 -0
  66. ansible/galaxy/data/network/defaults/main.yml.j2 +1 -0
  67. ansible/galaxy/data/network/library/example_command.py.j2 +1 -0
  68. ansible/galaxy/data/network/library/example_config.py.j2 +1 -0
  69. ansible/galaxy/data/network/library/example_facts.py.j2 +1 -0
  70. ansible/galaxy/data/network/meta/main.yml.j2 +1 -0
  71. ansible/galaxy/data/network/module_utils/example.py.j2 +1 -0
  72. ansible/galaxy/data/network/netconf_plugins/example.py.j2 +1 -0
  73. ansible/galaxy/data/network/tasks/main.yml.j2 +1 -0
  74. ansible/galaxy/data/network/terminal_plugins/example.py.j2 +1 -0
  75. ansible/galaxy/data/network/tests/inventory +1 -0
  76. ansible/galaxy/data/network/tests/test.yml.j2 +1 -0
  77. ansible/galaxy/data/network/vars/main.yml.j2 +1 -0
  78. ansible/galaxy/dependency_resolution/providers.py +3 -3
  79. ansible/galaxy/role.py +1 -1
  80. ansible/galaxy/token.py +20 -8
  81. ansible/keyword_desc.yml +1 -1
  82. ansible/module_utils/_internal/__init__.py +0 -0
  83. ansible/module_utils/_internal/_concurrent/__init__.py +0 -0
  84. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +28 -0
  85. ansible/module_utils/_internal/_concurrent/_futures.py +21 -0
  86. ansible/module_utils/ansible_release.py +2 -2
  87. ansible/module_utils/api.py +2 -2
  88. ansible/module_utils/basic.py +8 -8
  89. ansible/module_utils/common/collections.py +1 -1
  90. ansible/module_utils/common/file.py +0 -6
  91. ansible/module_utils/common/process.py +22 -9
  92. ansible/module_utils/common/text/converters.py +5 -8
  93. ansible/module_utils/common/text/formatters.py +20 -4
  94. ansible/module_utils/common/validation.py +33 -25
  95. ansible/module_utils/compat/paramiko.py +6 -1
  96. ansible/module_utils/compat/selinux.py +2 -2
  97. ansible/module_utils/connection.py +8 -24
  98. ansible/module_utils/csharp/Ansible.Become.cs +14 -25
  99. ansible/module_utils/csharp/Ansible.Process.cs +1 -1
  100. ansible/module_utils/distro/__init__.py +1 -1
  101. ansible/module_utils/distro/_distro.py +8 -4
  102. ansible/module_utils/facts/collector.py +2 -0
  103. ansible/module_utils/facts/default_collectors.py +3 -1
  104. ansible/module_utils/facts/hardware/aix.py +54 -52
  105. ansible/module_utils/facts/hardware/darwin.py +37 -34
  106. ansible/module_utils/facts/hardware/freebsd.py +55 -15
  107. ansible/module_utils/facts/hardware/hpux.py +3 -0
  108. ansible/module_utils/facts/hardware/linux.py +101 -57
  109. ansible/module_utils/facts/hardware/netbsd.py +3 -0
  110. ansible/module_utils/facts/hardware/openbsd.py +4 -1
  111. ansible/module_utils/facts/hardware/sunos.py +7 -1
  112. ansible/module_utils/facts/network/aix.py +16 -17
  113. ansible/module_utils/facts/network/fc_wwn.py +4 -1
  114. ansible/module_utils/facts/network/hpux.py +21 -4
  115. ansible/module_utils/facts/network/iscsi.py +7 -8
  116. ansible/module_utils/facts/network/linux.py +0 -2
  117. ansible/module_utils/facts/other/facter.py +9 -4
  118. ansible/module_utils/facts/other/ohai.py +5 -5
  119. ansible/module_utils/facts/packages.py +49 -7
  120. ansible/module_utils/facts/sysctl.py +33 -31
  121. ansible/module_utils/facts/system/distribution.py +1 -1
  122. ansible/module_utils/facts/system/local.py +12 -22
  123. ansible/module_utils/facts/system/service_mgr.py +3 -1
  124. ansible/module_utils/facts/system/systemd.py +47 -0
  125. ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
  126. ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
  127. ansible/module_utils/splitter.py +1 -1
  128. ansible/modules/add_host.py +1 -1
  129. ansible/modules/apt.py +43 -32
  130. ansible/modules/apt_key.py +6 -6
  131. ansible/modules/apt_repository.py +23 -14
  132. ansible/modules/assemble.py +7 -2
  133. ansible/modules/assert.py +4 -4
  134. ansible/modules/blockinfile.py +3 -6
  135. ansible/modules/command.py +1 -1
  136. ansible/modules/copy.py +4 -4
  137. ansible/modules/cron.py +13 -10
  138. ansible/modules/deb822_repository.py +16 -17
  139. ansible/modules/debconf.py +9 -9
  140. ansible/modules/debug.py +1 -1
  141. ansible/modules/dnf.py +79 -164
  142. ansible/modules/dnf5.py +54 -29
  143. ansible/modules/dpkg_selections.py +2 -2
  144. ansible/modules/expect.py +2 -2
  145. ansible/modules/fetch.py +2 -2
  146. ansible/modules/file.py +5 -3
  147. ansible/modules/find.py +40 -12
  148. ansible/modules/gather_facts.py +4 -2
  149. ansible/modules/get_url.py +29 -24
  150. ansible/modules/git.py +35 -35
  151. ansible/modules/group.py +71 -1
  152. ansible/modules/hostname.py +2 -4
  153. ansible/modules/include_vars.py +5 -5
  154. ansible/modules/iptables.py +13 -16
  155. ansible/modules/known_hosts.py +16 -13
  156. ansible/modules/lineinfile.py +1 -4
  157. ansible/modules/meta.py +6 -1
  158. ansible/modules/mount_facts.py +651 -0
  159. ansible/modules/package_facts.py +63 -80
  160. ansible/modules/pause.py +4 -3
  161. ansible/modules/pip.py +14 -14
  162. ansible/modules/replace.py +1 -4
  163. ansible/modules/rpm_key.py +31 -11
  164. ansible/modules/service.py +8 -8
  165. ansible/modules/service_facts.py +20 -5
  166. ansible/modules/set_stats.py +1 -1
  167. ansible/modules/setup.py +3 -3
  168. ansible/modules/stat.py +3 -3
  169. ansible/modules/subversion.py +1 -1
  170. ansible/modules/systemd.py +16 -10
  171. ansible/modules/systemd_service.py +16 -10
  172. ansible/modules/sysvinit.py +4 -4
  173. ansible/modules/unarchive.py +35 -22
  174. ansible/modules/uri.py +24 -18
  175. ansible/modules/user.py +145 -12
  176. ansible/modules/validate_argument_spec.py +3 -3
  177. ansible/modules/wait_for_connection.py +2 -1
  178. ansible/modules/yum_repository.py +136 -179
  179. ansible/parsing/dataloader.py +2 -2
  180. ansible/parsing/mod_args.py +11 -10
  181. ansible/parsing/vault/__init__.py +8 -3
  182. ansible/parsing/yaml/constructor.py +10 -8
  183. ansible/parsing/yaml/objects.py +1 -1
  184. ansible/playbook/base.py +12 -23
  185. ansible/playbook/helpers.py +4 -0
  186. ansible/playbook/loop_control.py +8 -0
  187. ansible/playbook/play.py +4 -22
  188. ansible/playbook/play_context.py +0 -16
  189. ansible/playbook/playbook_include.py +2 -2
  190. ansible/playbook/role/__init__.py +2 -2
  191. ansible/plugins/__init__.py +2 -0
  192. ansible/plugins/action/__init__.py +7 -9
  193. ansible/plugins/action/dnf.py +7 -5
  194. ansible/plugins/action/package.py +5 -4
  195. ansible/plugins/action/reboot.py +2 -2
  196. ansible/plugins/become/__init__.py +1 -1
  197. ansible/plugins/callback/__init__.py +44 -3
  198. ansible/plugins/callback/default.py +1 -1
  199. ansible/plugins/cliconf/__init__.py +1 -1
  200. ansible/plugins/connection/paramiko_ssh.py +2 -80
  201. ansible/plugins/connection/psrp.py +33 -82
  202. ansible/plugins/connection/ssh.py +0 -8
  203. ansible/plugins/connection/winrm.py +46 -1
  204. ansible/plugins/doc_fragments/connection_pipelining.py +2 -2
  205. ansible/plugins/doc_fragments/constructed.py +10 -10
  206. ansible/plugins/doc_fragments/default_callback.py +8 -8
  207. ansible/plugins/doc_fragments/files.py +5 -5
  208. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  209. ansible/plugins/doc_fragments/result_format_callback.py +6 -6
  210. ansible/plugins/doc_fragments/return_common.py +1 -1
  211. ansible/plugins/doc_fragments/shell_common.py +2 -10
  212. ansible/plugins/doc_fragments/shell_windows.py +0 -9
  213. ansible/plugins/doc_fragments/url.py +2 -2
  214. ansible/plugins/doc_fragments/url_windows.py +4 -5
  215. ansible/plugins/doc_fragments/validate.py +1 -1
  216. ansible/plugins/filter/core.py +2 -0
  217. ansible/plugins/filter/human_to_bytes.yml +9 -0
  218. ansible/plugins/filter/password_hash.yml +1 -1
  219. ansible/plugins/filter/strftime.yml +1 -1
  220. ansible/plugins/filter/to_nice_json.yml +7 -3
  221. ansible/plugins/filter/to_uuid.yml +1 -1
  222. ansible/plugins/inventory/script.py +1 -1
  223. ansible/plugins/list.py +1 -1
  224. ansible/plugins/loader.py +0 -11
  225. ansible/plugins/lookup/config.py +1 -1
  226. ansible/plugins/lookup/csvfile.py +21 -9
  227. ansible/plugins/lookup/env.py +8 -9
  228. ansible/plugins/lookup/ini.py +10 -1
  229. ansible/plugins/lookup/random_choice.py +2 -2
  230. ansible/plugins/lookup/url.py +7 -2
  231. ansible/plugins/shell/__init__.py +15 -20
  232. ansible/plugins/shell/powershell.py +9 -6
  233. ansible/plugins/strategy/__init__.py +16 -7
  234. ansible/plugins/test/core.py +23 -1
  235. ansible/plugins/test/issubset.yml +1 -1
  236. ansible/plugins/test/subset.yml +1 -1
  237. ansible/plugins/test/timedout.yml +20 -0
  238. ansible/plugins/test/vault_encrypted.yml +6 -6
  239. ansible/plugins/test/vaulted_file.yml +19 -0
  240. ansible/release.py +2 -2
  241. ansible/template/__init__.py +3 -8
  242. ansible/utils/collection_loader/_collection_finder.py +23 -55
  243. ansible/utils/display.py +44 -31
  244. ansible/utils/jsonrpc.py +1 -1
  245. ansible/utils/listify.py +1 -5
  246. ansible/utils/path.py +3 -0
  247. ansible/utils/vars.py +18 -27
  248. ansible/vars/manager.py +7 -150
  249. ansible/vars/plugins.py +1 -1
  250. ansible_core-2.18.0.dist-info/Apache-License.txt +202 -0
  251. {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/METADATA +36 -23
  252. ansible_core-2.18.0.dist-info/MIT-license.txt +14 -0
  253. ansible_core-2.18.0.dist-info/PSF-license.txt +48 -0
  254. {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/RECORD +316 -311
  255. {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/entry_points.txt +1 -1
  256. ansible_core-2.18.0.dist-info/simplified_bsd.txt +8 -0
  257. ansible_test/_data/completion/docker.txt +7 -7
  258. ansible_test/_data/completion/remote.txt +5 -4
  259. ansible_test/_data/completion/windows.txt +4 -4
  260. ansible_test/_data/requirements/ansible-test.txt +1 -2
  261. ansible_test/_data/requirements/constraints.txt +1 -2
  262. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  263. ansible_test/_data/requirements/sanity.changelog.in +1 -1
  264. ansible_test/_data/requirements/sanity.changelog.txt +4 -4
  265. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  266. ansible_test/_data/requirements/sanity.import.txt +1 -1
  267. ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -1
  268. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  269. ansible_test/_data/requirements/sanity.pylint.txt +6 -8
  270. ansible_test/_data/requirements/sanity.runtime-metadata.txt +2 -2
  271. ansible_test/_data/requirements/sanity.validate-modules.txt +3 -3
  272. ansible_test/_data/requirements/sanity.yamllint.in +1 -0
  273. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  274. ansible_test/_internal/ansible_util.py +8 -35
  275. ansible_test/_internal/ci/azp.py +1 -1
  276. ansible_test/_internal/classification/__init__.py +0 -2
  277. ansible_test/_internal/cli/parsers/key_value_parsers.py +3 -0
  278. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -1
  279. ansible_test/_internal/commands/integration/cloud/httptester.py +1 -1
  280. ansible_test/_internal/commands/integration/cloud/nios.py +1 -1
  281. ansible_test/_internal/commands/sanity/__init__.py +96 -19
  282. ansible_test/_internal/commands/sanity/pylint.py +20 -24
  283. ansible_test/_internal/completion.py +2 -0
  284. ansible_test/_internal/constants.py +0 -1
  285. ansible_test/_internal/coverage_util.py +1 -2
  286. ansible_test/_internal/docker_util.py +1 -1
  287. ansible_test/_internal/encoding.py +4 -4
  288. ansible_test/_internal/host_configs.py +10 -0
  289. ansible_test/_internal/host_profiles.py +9 -13
  290. ansible_test/_internal/pypi_proxy.py +1 -1
  291. ansible_test/_internal/python_requirements.py +5 -14
  292. ansible_test/_internal/timeout.py +1 -1
  293. ansible_test/_internal/util.py +40 -0
  294. ansible_test/_internal/util_common.py +5 -1
  295. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.json +3 -1
  296. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +6 -3
  297. ansible_test/_util/controller/sanity/code-smell/empty-init.json +0 -2
  298. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +5 -0
  299. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +5 -0
  300. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +5 -0
  301. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +6 -0
  302. ansible_test/_util/controller/sanity/pylint/config/default.cfg +6 -0
  303. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -19
  304. ansible_test/_util/controller/sanity/shellcheck/exclude.txt +1 -0
  305. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +67 -2
  306. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +27 -5
  307. ansible_test/_util/target/cli/ansible_test_cli_stub.py +0 -0
  308. ansible_test/_util/target/common/constants.py +2 -2
  309. ansible_test/_util/target/injector/python.py +5 -0
  310. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +6 -0
  311. ansible_test/_util/target/sanity/import/importer.py +1 -1
  312. ansible_test/_util/target/setup/bootstrap.sh +6 -17
  313. ansible_test/_util/target/setup/requirements.py +18 -24
  314. ansible_test/config/config.yml +1 -1
  315. ansible_core-2.17.6.data/scripts/ansible-test +0 -44
  316. ansible_test/_data/requirements/sanity.mypy.in +0 -10
  317. ansible_test/_data/requirements/sanity.mypy.txt +0 -18
  318. ansible_test/_internal/commands/sanity/mypy.py +0 -274
  319. ansible_test/_util/controller/sanity/mypy/ansible-core.ini +0 -116
  320. ansible_test/_util/controller/sanity/mypy/ansible-test.ini +0 -27
  321. ansible_test/_util/controller/sanity/mypy/modules.ini +0 -92
  322. ansible_test/_util/controller/sanity/mypy/packaging.ini +0 -20
  323. {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/COPYING +0 -0
  324. {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/WHEEL +0 -0
  325. {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/top_level.txt +0 -0
@@ -11,7 +11,7 @@ DOCUMENTATION = '''
11
11
  module: dpkg_selections
12
12
  short_description: Dpkg package selection selections
13
13
  description:
14
- - Change dpkg package selection state via --get-selections and --set-selections.
14
+ - Change dpkg package selection state via C(--get-selections) and C(--set-selections).
15
15
  version_added: "2.0"
16
16
  author:
17
17
  - Brian Brazil (@brian-brazil) <brian.brazil@boxever.com>
@@ -68,7 +68,7 @@ def main():
68
68
  dpkg = module.get_bin_path('dpkg', True)
69
69
 
70
70
  locale = get_best_parsable_locale(module)
71
- DPKG_ENV = dict(LANG=locale, LC_ALL=locale, LC_MESSAGES=locale, LC_CTYPE=locale)
71
+ DPKG_ENV = dict(LANG=locale, LC_ALL=locale, LC_MESSAGES=locale, LC_CTYPE=locale, LANGUAGE=locale)
72
72
  module.run_command_environ_update = DPKG_ENV
73
73
 
74
74
  name = module.params['name']
ansible/modules/expect.py CHANGED
@@ -70,10 +70,10 @@ notes:
70
70
  - If you want to run a command through the shell (say you are using C(<),
71
71
  C(>), C(|), and so on), you must specify a shell in the command such as
72
72
  C(/bin/bash -c "/path/to/something | grep else").
73
- - Case insensitive searches are indicated with a prefix of C(?i).
73
+ - Case insensitive searches are indicated with a prefix of C((?i)).
74
74
  - The C(pexpect) library used by this module operates with a search window
75
75
  of 2000 bytes, and does not use a multiline regex match. To perform a
76
- start of line bound match, use a pattern like ``(?m)^pattern``
76
+ start of line bound match, use a pattern like C((?m)^pattern).
77
77
  - The M(ansible.builtin.expect) module is designed for simple scenarios.
78
78
  For more complex needs, consider the use of expect code with the M(ansible.builtin.shell)
79
79
  or M(ansible.builtin.script) modules. (An example is part of the M(ansible.builtin.shell) module documentation).
ansible/modules/fetch.py CHANGED
@@ -28,8 +28,8 @@ options:
28
28
  dest:
29
29
  description:
30
30
  - A directory to save the file into.
31
- - For example, if the O(dest) directory is C(/backup) a O(src) file named C(/etc/profile) on host
32
- C(host.example.com), would be saved into C(/backup/host.example.com/etc/profile).
31
+ - For example, if O(dest=/backup), then O(src=/etc/profile) on host
32
+ C(host.example.com), would save the file into C(/backup/host.example.com/etc/profile).
33
33
  The host name is based on the inventory name.
34
34
  required: yes
35
35
  fail_on_missing:
ansible/modules/file.py CHANGED
@@ -63,9 +63,9 @@ options:
63
63
  force:
64
64
  description:
65
65
  - >
66
- Force the creation of the symlinks in two cases: the source file does
66
+ Force the creation of the links in two cases: if the link type is symbolic and the source file does
67
67
  not exist (but will appear later); the destination exists and is a file (so, we need to unlink the
68
- O(path) file and create a symlink to the O(src) file in place of it).
68
+ O(path) file and create a link to the O(src) file in place of it).
69
69
  type: bool
70
70
  default: no
71
71
  follow:
@@ -73,7 +73,7 @@ options:
73
73
  - This flag indicates that filesystem links, if they exist, should be followed.
74
74
  - O(follow=yes) and O(state=link) can modify O(src) when combined with parameters such as O(mode).
75
75
  - Previous to Ansible 2.5, this was V(false) by default.
76
- - While creating a symlink with a non-existent destination, set O(follow) to V(false) to avoid a warning message related to permission issues.
76
+ - While creating a symlink with a non-existent destination, set O(follow=false) to avoid a warning message related to permission issues.
77
77
  The warning message is added to notify the user that we can not set permissions to the non-existent destination.
78
78
  type: bool
79
79
  default: yes
@@ -872,6 +872,8 @@ def ensure_hardlink(path, src, follow, force, timestamps):
872
872
  'path': path})
873
873
  else:
874
874
  try:
875
+ if follow and os.path.islink(b_src):
876
+ b_src = os.readlink(b_src)
875
877
  os.link(b_src, b_path)
876
878
  except OSError as e:
877
879
  raise AnsibleModuleError(results={'msg': 'Error while linking: %s'
ansible/modules/find.py CHANGED
@@ -58,8 +58,8 @@ options:
58
58
  contains:
59
59
  description:
60
60
  - A regular expression or pattern which should be matched against the file content.
61
- - If O(read_whole_file) is V(false) it matches against the beginning of the line (uses
62
- V(re.match(\))). If O(read_whole_file) is V(true), it searches anywhere for that pattern
61
+ - If O(read_whole_file=false) it matches against the beginning of the line (uses
62
+ V(re.match(\))). If O(read_whole_file=true), it searches anywhere for that pattern
63
63
  (uses V(re.search(\))).
64
64
  - Works only when O(file_type) is V(file).
65
65
  type: str
@@ -75,14 +75,15 @@ options:
75
75
  paths:
76
76
  description:
77
77
  - List of paths of directories to search. All paths must be fully qualified.
78
+ - From ansible-core 2.18 and onwards, the data type has changed from C(str) to C(path).
78
79
  type: list
79
80
  required: true
80
81
  aliases: [ name, path ]
81
- elements: str
82
+ elements: path
82
83
  file_type:
83
84
  description:
84
85
  - Type of file to select.
85
- - The 'link' and 'any' choices were added in Ansible 2.3.
86
+ - The V(link) and V(any) choices were added in Ansible 2.3.
86
87
  type: str
87
88
  choices: [ any, directory, file, link ]
88
89
  default: file
@@ -116,7 +117,7 @@ options:
116
117
  restricted to modes that can be applied using the python
117
118
  C(os.chmod) function.
118
119
  - The mode can be provided as an octal such as V("0644") or
119
- as symbolic such as V(u=rw,g=r,o=r)
120
+ as symbolic such as V(u=rw,g=r,o=r).
120
121
  type: raw
121
122
  version_added: '2.16'
122
123
  exact_mode:
@@ -145,15 +146,23 @@ options:
145
146
  depth:
146
147
  description:
147
148
  - Set the maximum number of levels to descend into.
148
- - Setting recurse to V(false) will override this value, which is effectively depth 1.
149
+ - Setting O(recurse=false) will override this value, which is effectively depth 1.
149
150
  - Default is unlimited depth.
150
151
  type: int
151
152
  version_added: "2.6"
152
153
  encoding:
153
154
  description:
154
- - When doing a C(contains) search, determine the encoding of the files to be searched.
155
+ - When doing a O(contains) search, determine the encoding of the files to be searched.
155
156
  type: str
156
157
  version_added: "2.17"
158
+ limit:
159
+ description:
160
+ - Limit the maximum number of matching paths returned. After finding this many, the find action will stop looking.
161
+ - Matches are made from the top, down (i.e. shallowest directory first).
162
+ - If not set, or set to v(null), it will do unlimited matches.
163
+ - Default is unlimited matches.
164
+ type: int
165
+ version_added: "2.18"
157
166
  extends_documentation_fragment: action_common_attributes
158
167
  attributes:
159
168
  check_mode:
@@ -227,6 +236,16 @@ EXAMPLES = r'''
227
236
  - '^_[0-9]{2,4}_.*.log$'
228
237
  - '^[a-z]{1,5}_.*log$'
229
238
 
239
+ - name: Find file containing "wally" without necessarily reading all files
240
+ ansible.builtin.find:
241
+ paths: /var/log
242
+ file_type: file
243
+ contains: wally
244
+ read_whole_file: true
245
+ patterns: "^.*\\.log$"
246
+ use_regex: true
247
+ recurse: true
248
+ limit: 1
230
249
  '''
231
250
 
232
251
  RETURN = r'''
@@ -450,7 +469,7 @@ def statinfo(st):
450
469
  def main():
451
470
  module = AnsibleModule(
452
471
  argument_spec=dict(
453
- paths=dict(type='list', required=True, aliases=['name', 'path'], elements='str'),
472
+ paths=dict(type='list', required=True, aliases=['name', 'path'], elements='path'),
454
473
  patterns=dict(type='list', default=[], aliases=['pattern'], elements='str'),
455
474
  excludes=dict(type='list', aliases=['exclude'], elements='str'),
456
475
  contains=dict(type='str'),
@@ -467,7 +486,8 @@ def main():
467
486
  depth=dict(type='int'),
468
487
  mode=dict(type='raw'),
469
488
  exact_mode=dict(type='bool', default=True),
470
- encoding=dict(type='str')
489
+ encoding=dict(type='str'),
490
+ limit=dict(type='int')
471
491
  ),
472
492
  supports_check_mode=True,
473
493
  )
@@ -520,17 +540,20 @@ def main():
520
540
  else:
521
541
  module.fail_json(size=params['size'], msg="failed to process size")
522
542
 
543
+ if params['limit'] is not None and params['limit'] <= 0:
544
+ module.fail_json(msg="limit cannot be %d (use None for unlimited)" % params['limit'])
545
+
523
546
  now = time.time()
524
547
  msg = 'All paths examined'
525
548
  looked = 0
526
549
  has_warnings = False
527
550
  for npath in params['paths']:
528
- npath = os.path.expanduser(os.path.expandvars(npath))
529
551
  try:
530
552
  if not os.path.isdir(npath):
531
553
  raise Exception("'%s' is not a directory" % to_native(npath))
532
554
 
533
- for root, dirs, files in os.walk(npath, onerror=handle_walk_errors, followlinks=params['follow']):
555
+ # Setting `topdown=True` to explicitly guarantee matches are made from the shallowest directory first
556
+ for root, dirs, files in os.walk(npath, onerror=handle_walk_errors, followlinks=params['follow'], topdown=True):
534
557
  looked = looked + len(files) + len(dirs)
535
558
  for fsobj in (files + dirs):
536
559
  fsname = os.path.normpath(os.path.join(root, fsobj))
@@ -596,7 +619,12 @@ def main():
596
619
  r.update(statinfo(st))
597
620
  filelist.append(r)
598
621
 
599
- if not params['recurse']:
622
+ if len(filelist) == params["limit"]:
623
+ # Breaks out of directory files loop only
624
+ msg = "Limit of matches reached"
625
+ break
626
+
627
+ if not params['recurse'] or len(filelist) == params["limit"]:
600
628
  break
601
629
  except Exception as e:
602
630
  skipped[npath] = to_text(e)
@@ -27,6 +27,8 @@ options:
27
27
  - By default it will be true if more than one fact module is used.
28
28
  - For low cost/delay fact modules parallelism overhead might end up meaning the whole process takes longer.
29
29
  Test your specific case to see if it is a speed improvement or not.
30
+ - The C(ansible_facts_parallel) variable can be used to set this option,
31
+ overriding the default, but not the direct assignment of the option in the task.
30
32
  type: bool
31
33
  attributes:
32
34
  action:
@@ -49,8 +51,8 @@ attributes:
49
51
  notes:
50
52
  - This is mostly a wrapper around other fact gathering modules.
51
53
  - Options passed into this action must be supported by all the underlying fact modules configured.
52
- - If using C(gather_timeout) and parallel execution, it will limit the total execution time of
53
- modules that do not accept C(gather_timeout) themselves.
54
+ - If using O(ignore:gather_timeout) and parallel execution, it will limit the total execution time of
55
+ modules that do not accept O(ignore:gather_timeout) themselves.
54
56
  - Facts returned by each module will be merged, conflicts will favor 'last merged'.
55
57
  Order is not guaranteed, when doing parallel gathering on multiple modules.
56
58
  author:
@@ -13,7 +13,7 @@ short_description: Downloads files from HTTP, HTTPS, or FTP to node
13
13
  description:
14
14
  - Downloads files from HTTP, HTTPS, or FTP to the remote server. The remote
15
15
  server I(must) have direct access to the remote resource.
16
- - By default, if an environment variable C(<protocol>_proxy) is set on
16
+ - By default, if an environment variable E(<protocol>_proxy) is set on
17
17
  the target host, requests will be sent through that proxy. This
18
18
  behaviour can be overridden by setting a variable for this task
19
19
  (see R(setting the environment,playbooks_environment)),
@@ -27,23 +27,23 @@ version_added: '0.6'
27
27
  options:
28
28
  ciphers:
29
29
  description:
30
- - SSL/TLS Ciphers to use for the request
31
- - 'When a list is provided, all ciphers are joined in order with V(:)'
30
+ - SSL/TLS Ciphers to use for the request.
31
+ - 'When a list is provided, all ciphers are joined in order with C(:).'
32
32
  - See the L(OpenSSL Cipher List Format,https://www.openssl.org/docs/manmaster/man1/openssl-ciphers.html#CIPHER-LIST-FORMAT)
33
33
  for more details.
34
- - The available ciphers is dependent on the Python and OpenSSL/LibreSSL versions
34
+ - The available ciphers is dependent on the Python and OpenSSL/LibreSSL versions.
35
35
  type: list
36
36
  elements: str
37
37
  version_added: '2.14'
38
38
  decompress:
39
39
  description:
40
- - Whether to attempt to decompress gzip content-encoded responses
40
+ - Whether to attempt to decompress gzip content-encoded responses.
41
41
  type: bool
42
42
  default: true
43
43
  version_added: '2.14'
44
44
  url:
45
45
  description:
46
- - HTTP, HTTPS, or FTP URL in the form (http|https|ftp)://[user[:pass]]@host.domain[:port]/path
46
+ - HTTP, HTTPS, or FTP URL in the form C((http|https|ftp)://[user[:pass]]@host.domain[:port]/path).
47
47
  type: str
48
48
  required: true
49
49
  dest:
@@ -60,9 +60,9 @@ options:
60
60
  tmp_dest:
61
61
  description:
62
62
  - Absolute path of where temporary file is downloaded to.
63
- - When run on Ansible 2.5 or greater, path defaults to ansible's remote_tmp setting
63
+ - When run on Ansible 2.5 or greater, path defaults to ansible's C(remote_tmp) setting.
64
64
  - When run on Ansible prior to 2.5, it defaults to E(TMPDIR), E(TEMP) or E(TMP) env variables or a platform specific value.
65
- - U(https://docs.python.org/3/library/tempfile.html#tempfile.tempdir)
65
+ - U(https://docs.python.org/3/library/tempfile.html#tempfile.tempdir).
66
66
  type: path
67
67
  version_added: '2.1'
68
68
  force:
@@ -87,18 +87,20 @@ options:
87
87
  - 'If a checksum is passed to this parameter, the digest of the
88
88
  destination file will be calculated after it is downloaded to ensure
89
89
  its integrity and verify that the transfer completed successfully.
90
- Format: <algorithm>:<checksum|url>, e.g. checksum="sha256:D98291AC[...]B6DC7B97",
91
- checksum="sha256:http://example.com/path/sha256sum.txt"'
90
+ Format: <algorithm>:<checksum|url>, for example C(checksum="sha256:D98291AC[...]B6DC7B97",
91
+ C(checksum="sha256:http://example.com/path/sha256sum.txt").'
92
92
  - If you worry about portability, only the sha1 algorithm is available
93
93
  on all platforms and python versions.
94
- - The Python ``hashlib`` module is responsible for providing the available algorithms.
94
+ - The Python C(hashlib) module is responsible for providing the available algorithms.
95
95
  The choices vary based on Python version and OpenSSL version.
96
- - On systems running in FIPS compliant mode, the ``md5`` algorithm may be unavailable.
96
+ - On systems running in FIPS compliant mode, the C(md5) algorithm may be unavailable.
97
97
  - Additionally, if a checksum is passed to this parameter, and the file exist under
98
98
  the O(dest) location, the C(destination_checksum) would be calculated, and if
99
99
  checksum equals C(destination_checksum), the file download would be skipped
100
- (unless O(force) is V(true)). If the checksum does not equal C(destination_checksum),
100
+ (unless O(force=true)). If the checksum does not equal C(destination_checksum),
101
101
  the destination file is deleted.
102
+ - If the checksum URL requires username and password, O(url_username) and O(url_password) are used
103
+ to download the checksum file.
102
104
  type: str
103
105
  default: ''
104
106
  version_added: "2.0"
@@ -185,16 +187,16 @@ options:
185
187
  authentication.
186
188
  - Requires the Python library L(gssapi,https://github.com/pythongssapi/python-gssapi) to be installed.
187
189
  - Credentials for GSSAPI can be specified with O(url_username)/O(url_password) or with the GSSAPI env var
188
- C(KRB5CCNAME) that specified a custom Kerberos credential cache.
190
+ E(KRB5CCNAME) that specified a custom Kerberos credential cache.
189
191
  - NTLM authentication is I(not) supported even if the GSSAPI mech for NTLM has been installed.
190
192
  type: bool
191
193
  default: no
192
194
  version_added: '2.11'
193
195
  use_netrc:
194
196
  description:
195
- - Determining whether to use credentials from ``~/.netrc`` file
196
- - By default .netrc is used with Basic authentication headers
197
- - When set to False, .netrc credentials are ignored
197
+ - Determining whether to use credentials from C(~/.netrc) file.
198
+ - By default C(.netrc) is used with Basic authentication headers.
199
+ - When V(false), C(.netrc) credentials are ignored.
198
200
  type: bool
199
201
  default: true
200
202
  version_added: '2.14'
@@ -661,6 +663,16 @@ def main():
661
663
  result['checksum_src'] != result['checksum_dest'])
662
664
  module.exit_json(msg=info.get('msg', ''), **result)
663
665
 
666
+ # If a checksum was provided, ensure that the temporary file matches this checksum
667
+ # before moving it to the destination.
668
+ if checksum != '':
669
+ tmpsrc_checksum = module.digest_from_file(tmpsrc, algorithm)
670
+
671
+ if checksum != tmpsrc_checksum:
672
+ os.remove(tmpsrc)
673
+ module.fail_json(msg=f"The checksum for {tmpsrc} did not match {checksum}; it was {tmpsrc_checksum}.", **result)
674
+
675
+ # Copy temporary file to destination if necessary
664
676
  backup_file = None
665
677
  if result['checksum_src'] != result['checksum_dest']:
666
678
  try:
@@ -679,13 +691,6 @@ def main():
679
691
  if os.path.exists(tmpsrc):
680
692
  os.remove(tmpsrc)
681
693
 
682
- if checksum != '':
683
- destination_checksum = module.digest_from_file(dest, algorithm)
684
-
685
- if checksum != destination_checksum:
686
- os.remove(dest)
687
- module.fail_json(msg="The checksum for %s did not match %s; it was %s." % (dest, checksum, destination_checksum), **result)
688
-
689
694
  # allow file attribute changes
690
695
  file_args = module.load_file_common_arguments(module.params, path=dest)
691
696
  result['changed'] = module.set_fs_attributes_if_different(file_args, result['changed'])
ansible/modules/git.py CHANGED
@@ -42,19 +42,19 @@ options:
42
42
  default: "HEAD"
43
43
  accept_hostkey:
44
44
  description:
45
- - Will ensure or not that "-o StrictHostKeyChecking=no" is present as an ssh option.
45
+ - Will ensure or not that C(-o StrictHostKeyChecking=no) is present as an ssh option.
46
46
  - Be aware that this disables a protection against MITM attacks.
47
- - Those using OpenSSH >= 7.5 might want to set O(ssh_opts) to V(StrictHostKeyChecking=accept-new)
47
+ - Those using OpenSSH >= 7.5 might want to use O(accept_newhostkey) or set O(ssh_opts) to V(StrictHostKeyChecking=accept-new)
48
48
  instead, it does not remove the MITM issue but it does restrict it to the first attempt.
49
49
  type: bool
50
50
  default: 'no'
51
51
  version_added: "1.5"
52
52
  accept_newhostkey:
53
53
  description:
54
- - As of OpenSSH 7.5, "-o StrictHostKeyChecking=accept-new" can be
54
+ - As of OpenSSH 7.5, C(-o StrictHostKeyChecking=accept-new) can be
55
55
  used which is safer and will only accepts host keys which are
56
- not present or are the same. if V(true), ensure that
57
- "-o StrictHostKeyChecking=accept-new" is present as an ssh option.
56
+ not present or are the same. If V(true), ensure that
57
+ C(-o StrictHostKeyChecking=accept-new) is present as an ssh option.
58
58
  type: bool
59
59
  default: 'no'
60
60
  version_added: "2.12"
@@ -65,21 +65,21 @@ options:
65
65
  - For older versions it appends E(GIT_SSH_OPTS) (specific to this module) to the
66
66
  variables above or via a wrapper script.
67
67
  - Other options can add to this list, like O(key_file) and O(accept_hostkey).
68
- - An example value could be "-o StrictHostKeyChecking=no" (although this particular
68
+ - An example value could be C(-o StrictHostKeyChecking=no) (although this particular
69
69
  option is better set by O(accept_hostkey)).
70
- - The module ensures that 'BatchMode=yes' is always present to avoid prompts.
70
+ - The module ensures that C(BatchMode=yes) is always present to avoid prompts.
71
71
  type: str
72
72
  version_added: "1.5"
73
73
 
74
74
  key_file:
75
75
  description:
76
76
  - Specify an optional private key file path, on the target host, to use for the checkout.
77
- - This ensures 'IdentitiesOnly=yes' is present in O(ssh_opts).
77
+ - This ensures C(IdentitiesOnly=yes) is present in O(ssh_opts).
78
78
  type: path
79
79
  version_added: "1.5"
80
80
  reference:
81
81
  description:
82
- - Reference repository (see "git clone --reference ...").
82
+ - Reference repository (see C(git clone --reference ...)).
83
83
  type: str
84
84
  version_added: "1.4"
85
85
  remote:
@@ -165,7 +165,7 @@ options:
165
165
  track_submodules:
166
166
  description:
167
167
  - If V(true), submodules will track the latest commit on their
168
- master branch (or other branch specified in .gitmodules). If
168
+ master branch (or other branch specified in C(.gitmodules)). If
169
169
  V(false), submodules will be kept at the revision specified by the
170
170
  main project. This is equivalent to specifying the C(--remote) flag
171
171
  to git submodule update.
@@ -235,63 +235,63 @@ notes:
235
235
  SSH will prompt user to authorize the first contact with a remote host. To avoid this prompt,
236
236
  one solution is to use the option accept_hostkey. Another solution is to
237
237
  add the remote host public key in C(/etc/ssh/ssh_known_hosts) before calling
238
- the git module, with the following command: ssh-keyscan -H remote_host.com >> /etc/ssh/ssh_known_hosts."
238
+ the git module, with the following command: C(ssh-keyscan -H remote_host.com >> /etc/ssh/ssh_known_hosts)."
239
239
  '''
240
240
 
241
241
  EXAMPLES = '''
242
242
  - name: Git checkout
243
243
  ansible.builtin.git:
244
- repo: 'https://foosball.example.org/path/to/repo.git'
245
- dest: /srv/checkout
244
+ repo: 'https://github.com/ansible/ansible.git'
245
+ dest: /tmp/checkout
246
246
  version: release-0.22
247
247
 
248
248
  - name: Read-write git checkout from github
249
249
  ansible.builtin.git:
250
- repo: git@github.com:mylogin/hello.git
251
- dest: /home/mylogin/hello
250
+ repo: git@github.com:ansible/ansible.git
251
+ dest: /tmp/checkout
252
252
 
253
253
  - name: Just ensuring the repo checkout exists
254
254
  ansible.builtin.git:
255
- repo: 'https://foosball.example.org/path/to/repo.git'
256
- dest: /srv/checkout
255
+ repo: 'https://github.com/ansible/ansible.git'
256
+ dest: /tmp/checkout
257
257
  update: no
258
258
 
259
259
  - name: Just get information about the repository whether or not it has already been cloned locally
260
260
  ansible.builtin.git:
261
- repo: 'https://foosball.example.org/path/to/repo.git'
262
- dest: /srv/checkout
261
+ repo: git@github.com:ansible/ansible.git
262
+ dest: /tmp/checkout
263
263
  clone: no
264
264
  update: no
265
265
 
266
266
  - name: Checkout a github repo and use refspec to fetch all pull requests
267
267
  ansible.builtin.git:
268
- repo: https://github.com/ansible/ansible-examples.git
269
- dest: /src/ansible-examples
268
+ repo: 'https://github.com/ansible/ansible.git'
269
+ dest: /tmp/checkout
270
270
  refspec: '+refs/pull/*:refs/heads/*'
271
271
 
272
272
  - name: Create git archive from repo
273
273
  ansible.builtin.git:
274
- repo: https://github.com/ansible/ansible-examples.git
275
- dest: /src/ansible-examples
276
- archive: /tmp/ansible-examples.zip
274
+ repo: git@github.com:ansible/ansible.git
275
+ dest: /tmp/checkout
276
+ archive: /tmp/ansible.zip
277
277
 
278
278
  - name: Clone a repo with separate git directory
279
279
  ansible.builtin.git:
280
- repo: https://github.com/ansible/ansible-examples.git
281
- dest: /src/ansible-examples
282
- separate_git_dir: /src/ansible-examples.git
280
+ repo: 'https://github.com/ansible/ansible.git'
281
+ dest: /tmp/checkout
282
+ separate_git_dir: /tmp/repo
283
283
 
284
284
  - name: Example clone of a single branch
285
285
  ansible.builtin.git:
286
- repo: https://github.com/ansible/ansible-examples.git
287
- dest: /src/ansible-examples
286
+ repo: git@github.com:ansible/ansible.git
287
+ dest: /tmp/checkout
288
288
  single_branch: yes
289
289
  version: master
290
290
 
291
291
  - name: Avoid hanging when http(s) password is missing
292
292
  ansible.builtin.git:
293
- repo: https://github.com/ansible/could-be-a-private-repo
294
- dest: /src/from-private-repo
293
+ repo: 'https://github.com/ansible/ansible.git'
294
+ dest: /tmp/checkout
295
295
  environment:
296
296
  GIT_TERMINAL_PROMPT: 0 # reports "terminal prompts disabled" on missing password
297
297
  # or GIT_ASKPASS: /bin/true # for git before version 2.3.0, reports "Authentication failed" on missing password
@@ -468,7 +468,7 @@ def write_ssh_wrapper(module):
468
468
  def set_git_ssh_env(key_file, ssh_opts, git_version, module):
469
469
  '''
470
470
  use environment variables to configure git's ssh execution,
471
- which varies by version but this functino should handle all.
471
+ which varies by version but this function should handle all.
472
472
  '''
473
473
 
474
474
  # initialise to existing ssh opts and/or append user provided
@@ -500,7 +500,7 @@ def set_git_ssh_env(key_file, ssh_opts, git_version, module):
500
500
  # older than 2.3 does not know how to use git_ssh_command,
501
501
  # so we force it into get_ssh var
502
502
  # https://github.com/gitster/git/commit/09d60d785c68c8fa65094ecbe46fbc2a38d0fc1f
503
- if git_version < LooseVersion('2.3.0'):
503
+ if git_version is not None and git_version < LooseVersion('2.3.0'):
504
504
  # for use in wrapper
505
505
  os.environ["GIT_SSH_OPTS"] = ssh_opts
506
506
 
@@ -913,7 +913,7 @@ def fetch(git_path, module, repo, dest, version, remote, depth, bare, refspec, g
913
913
  refspecs = ['+refs/heads/*:refs/heads/*', '+refs/tags/*:refs/tags/*']
914
914
  else:
915
915
  # ensure all tags are fetched
916
- if git_version_used >= LooseVersion('1.9'):
916
+ if git_version_used is not None and git_version_used >= LooseVersion('1.9'):
917
917
  fetch_cmd.append('--tags')
918
918
  else:
919
919
  # old git versions have a bug in --tags that prevents updating existing tags
@@ -1308,7 +1308,7 @@ def main():
1308
1308
  # GIT_SSH=<path> as an environment variable, might create sh wrapper script for older versions.
1309
1309
  set_git_ssh_env(key_file, ssh_opts, git_version_used, module)
1310
1310
 
1311
- if depth is not None and git_version_used < LooseVersion('1.9.1'):
1311
+ if depth is not None and git_version_used is not None and git_version_used < LooseVersion('1.9.1'):
1312
1312
  module.warn("git version is too old to fully support the depth argument. Falling back to full checkouts.")
1313
1313
  depth = None
1314
1314