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
@@ -23,7 +23,6 @@ import time
23
23
 
24
24
  from ansible.module_utils.facts.hardware.base import Hardware, HardwareCollector
25
25
  from ansible.module_utils.facts.timeout import TimeoutError, timeout
26
-
27
26
  from ansible.module_utils.facts.utils import get_file_content, get_mount_size
28
27
 
29
28
 
@@ -173,13 +172,50 @@ class FreeBSDHardware(Hardware):
173
172
 
174
173
  sysdir = '/dev'
175
174
  device_facts['devices'] = {}
176
- drives = re.compile(r'(ada?\d+|da\d+|a?cd\d+)') # TODO: rc, disks, err = self.module.run_command("/sbin/sysctl kern.disks")
177
- slices = re.compile(r'(ada?\d+s\d+\w*|da\d+s\d+\w*)')
175
+ # TODO: rc, disks, err = self.module.run_command("/sbin/sysctl kern.disks")
176
+ drives = re.compile(
177
+ r"""(?x)(
178
+ (?:
179
+ ada? # ATA/SATA disk device
180
+ |da # SCSI disk device
181
+ |a?cd # SCSI CDROM drive
182
+ |amrd # AMI MegaRAID drive
183
+ |idad # Compaq RAID array
184
+ |ipsd # IBM ServeRAID RAID array
185
+ |md # md(4) disk device
186
+ |mfid # LSI MegaRAID SAS array
187
+ |mlxd # Mylex RAID disk
188
+ |twed # 3ware ATA RAID array
189
+ |vtbd # VirtIO Block Device
190
+ )\d+
191
+ )
192
+ """
193
+ )
194
+
195
+ slices = re.compile(
196
+ r"""(?x)(
197
+ (?:
198
+ ada? # ATA/SATA disk device
199
+ |a?cd # SCSI CDROM drive
200
+ |amrd # AMI MegaRAID drive
201
+ |da # SCSI disk device
202
+ |idad # Compaq RAID array
203
+ |ipsd # IBM ServeRAID RAID array
204
+ |md # md(4) disk device
205
+ |mfid # LSI MegaRAID SAS array
206
+ |mlxd # Mylex RAID disk
207
+ |twed # 3ware ATA RAID array
208
+ |vtbd # VirtIO Block Device
209
+ )\d+[ps]\d+\w*
210
+ )
211
+ """
212
+ )
213
+
178
214
  if os.path.isdir(sysdir):
179
215
  dirlist = sorted(os.listdir(sysdir))
180
216
  for device in dirlist:
181
217
  d = drives.match(device)
182
- if d:
218
+ if d and d.group(1) not in device_facts['devices']:
183
219
  device_facts['devices'][d.group(1)] = []
184
220
  s = slices.match(device)
185
221
  if s:
@@ -216,18 +252,22 @@ class FreeBSDHardware(Hardware):
216
252
  'product_version': 'system-version',
217
253
  'system_vendor': 'system-manufacturer',
218
254
  }
255
+ if dmi_bin is None:
256
+ dmi_facts = dict.fromkeys(
257
+ DMI_DICT.keys(),
258
+ 'NA'
259
+ )
260
+ return dmi_facts
261
+
219
262
  for (k, v) in DMI_DICT.items():
220
- if dmi_bin is not None:
221
- (rc, out, err) = self.module.run_command('%s -s %s' % (dmi_bin, v))
222
- if rc == 0:
223
- # Strip out commented lines (specific dmidecode output)
224
- # FIXME: why add the fact and then test if it is json?
225
- dmi_facts[k] = ''.join([line for line in out.splitlines() if not line.startswith('#')])
226
- try:
227
- json.dumps(dmi_facts[k])
228
- except UnicodeDecodeError:
229
- dmi_facts[k] = 'NA'
230
- else:
263
+ (rc, out, err) = self.module.run_command('%s -s %s' % (dmi_bin, v))
264
+ if rc == 0:
265
+ # Strip out commented lines (specific dmidecode output)
266
+ # FIXME: why add the fact and then test if it is json?
267
+ dmi_facts[k] = ''.join([line for line in out.splitlines() if not line.startswith('#')])
268
+ try:
269
+ json.dumps(dmi_facts[k])
270
+ except UnicodeDecodeError:
231
271
  dmi_facts[k] = 'NA'
232
272
  else:
233
273
  dmi_facts[k] = 'NA'
@@ -40,6 +40,9 @@ class HPUXHardware(Hardware):
40
40
  def populate(self, collected_facts=None):
41
41
  hardware_facts = {}
42
42
 
43
+ # TODO: very inefficient calls to machinfo,
44
+ # should just make one and then deal with finding the data (see facts/sysctl)
45
+ # but not going to change unless there is hp/ux for testing
43
46
  cpu_facts = self.get_cpu_facts(collected_facts=collected_facts)
44
47
  memory_facts = self.get_memory_facts()
45
48
  hw_facts = self.get_hw_facts()
@@ -24,12 +24,9 @@ import re
24
24
  import sys
25
25
  import time
26
26
 
27
- from multiprocessing import cpu_count
28
- from multiprocessing.pool import ThreadPool
29
-
30
- from ansible.module_utils.common.text.converters import to_text
27
+ from ansible.module_utils._internal._concurrent import _futures
31
28
  from ansible.module_utils.common.locale import get_best_parsable_locale
32
- from ansible.module_utils.common.process import get_bin_path
29
+ from ansible.module_utils.common.text.converters import to_text
33
30
  from ansible.module_utils.common.text.formatters import bytes_to_human
34
31
  from ansible.module_utils.facts.hardware.base import Hardware, HardwareCollector
35
32
  from ansible.module_utils.facts.utils import get_file_content, get_file_lines, get_mount_size
@@ -91,6 +88,7 @@ class LinuxHardware(Hardware):
91
88
  cpu_facts = self.get_cpu_facts(collected_facts=collected_facts)
92
89
  memory_facts = self.get_memory_facts()
93
90
  dmi_facts = self.get_dmi_facts()
91
+ sysinfo_facts = self.get_sysinfo_facts()
94
92
  device_facts = self.get_device_facts()
95
93
  uptime_facts = self.get_uptime_facts()
96
94
  lvm_facts = self.get_lvm_facts()
@@ -104,6 +102,7 @@ class LinuxHardware(Hardware):
104
102
  hardware_facts.update(cpu_facts)
105
103
  hardware_facts.update(memory_facts)
106
104
  hardware_facts.update(dmi_facts)
105
+ hardware_facts.update(sysinfo_facts)
107
106
  hardware_facts.update(device_facts)
108
107
  hardware_facts.update(uptime_facts)
109
108
  hardware_facts.update(lvm_facts)
@@ -208,6 +207,9 @@ class LinuxHardware(Hardware):
208
207
  if 'vme' not in val:
209
208
  xen_paravirt = True
210
209
 
210
+ if key == "flags":
211
+ cpu_facts['flags'] = val.split()
212
+
211
213
  # model name is for Intel arch, Processor (mind the uppercase P)
212
214
  # works for some ARM devices, like the Sheevaplug.
213
215
  if key in ['model name', 'Processor', 'vendor_id', 'cpu', 'Vendor', 'processor']:
@@ -300,12 +302,9 @@ class LinuxHardware(Hardware):
300
302
  )
301
303
  except AttributeError:
302
304
  # In Python < 3.3, os.sched_getaffinity() is not available
303
- try:
304
- cmd = get_bin_path('nproc')
305
- except ValueError:
306
- pass
307
- else:
308
- rc, out, _err = self.module.run_command(cmd)
305
+ nproc_cmd = self.module.get_bin_path('nproc')
306
+ if nproc_cmd is not None:
307
+ rc, out, _err = self.module.run_command(nproc_cmd)
309
308
  if rc == 0:
310
309
  cpu_facts['processor_nproc'] = int(out)
311
310
 
@@ -370,7 +369,6 @@ class LinuxHardware(Hardware):
370
369
 
371
370
  else:
372
371
  # Fall back to using dmidecode, if available
373
- dmi_bin = self.module.get_bin_path('dmidecode')
374
372
  DMI_DICT = {
375
373
  'bios_date': 'bios-release-date',
376
374
  'bios_vendor': 'bios-vendor',
@@ -391,25 +389,54 @@ class LinuxHardware(Hardware):
391
389
  'product_version': 'system-version',
392
390
  'system_vendor': 'system-manufacturer',
393
391
  }
392
+ dmi_bin = self.module.get_bin_path('dmidecode')
393
+ if dmi_bin is None:
394
+ dmi_facts = dict.fromkeys(
395
+ DMI_DICT.keys(),
396
+ 'NA'
397
+ )
398
+ return dmi_facts
399
+
394
400
  for (k, v) in DMI_DICT.items():
395
- if dmi_bin is not None:
396
- (rc, out, err) = self.module.run_command('%s -s %s' % (dmi_bin, v))
397
- if rc == 0:
398
- # Strip out commented lines (specific dmidecode output)
399
- thisvalue = ''.join([line for line in out.splitlines() if not line.startswith('#')])
400
- try:
401
- json.dumps(thisvalue)
402
- except UnicodeDecodeError:
403
- thisvalue = "NA"
401
+ (rc, out, err) = self.module.run_command('%s -s %s' % (dmi_bin, v))
402
+ if rc == 0:
403
+ # Strip out commented lines (specific dmidecode output)
404
+ thisvalue = ''.join([line for line in out.splitlines() if not line.startswith('#')])
405
+ try:
406
+ json.dumps(thisvalue)
407
+ except UnicodeDecodeError:
408
+ thisvalue = "NA"
404
409
 
405
- dmi_facts[k] = thisvalue
406
- else:
407
- dmi_facts[k] = 'NA'
410
+ dmi_facts[k] = thisvalue
408
411
  else:
409
412
  dmi_facts[k] = 'NA'
410
413
 
411
414
  return dmi_facts
412
415
 
416
+ def get_sysinfo_facts(self):
417
+ """Fetch /proc/sysinfo facts from s390 Linux on IBM Z"""
418
+ if not os.path.exists('/proc/sysinfo'):
419
+ return {}
420
+
421
+ sysinfo_facts = dict.fromkeys(
422
+ ('system_vendor', 'product_version', 'product_serial', 'product_name', 'product_uuid'),
423
+ 'NA'
424
+ )
425
+ sysinfo_re = re.compile(
426
+ r'''
427
+ ^
428
+ (?:Manufacturer:\s+(?P<system_vendor>.+))|
429
+ (?:Type:\s+(?P<product_name>.+))|
430
+ (?:Sequence\ Code:\s+0+(?P<product_serial>.+))
431
+ $
432
+ ''',
433
+ re.VERBOSE | re.MULTILINE
434
+ )
435
+ data = get_file_content('/proc/sysinfo')
436
+ for match in sysinfo_re.finditer(data):
437
+ sysinfo_facts.update({k: v for k, v in match.groupdict().items() if v is not None})
438
+ return sysinfo_facts
439
+
413
440
  def _run_lsblk(self, lsblk_path):
414
441
  # call lsblk and collect all uuids
415
442
  # --exclude 2 makes lsblk ignore floppy disks, which are slower to answer than typical timeouts
@@ -548,7 +575,7 @@ class LinuxHardware(Hardware):
548
575
 
549
576
  # start threads to query each mount
550
577
  results = {}
551
- pool = ThreadPool(processes=min(len(mtab_entries), cpu_count()))
578
+ executor = _futures.DaemonThreadPoolExecutor()
552
579
  maxtime = timeout.GATHER_TIMEOUT or timeout.DEFAULT_GATHER_TIMEOUT
553
580
  for fields in mtab_entries:
554
581
  # Transform octal escape sequences
@@ -572,30 +599,29 @@ class LinuxHardware(Hardware):
572
599
  if not self.MTAB_BIND_MOUNT_RE.match(options):
573
600
  mount_info['options'] += ",bind"
574
601
 
575
- results[mount] = {'info': mount_info,
576
- 'extra': pool.apply_async(self.get_mount_info, (mount, device, uuids)),
577
- 'timelimit': time.time() + maxtime}
602
+ results[mount] = {'info': mount_info, 'timelimit': time.monotonic() + maxtime}
603
+ results[mount]['extra'] = executor.submit(self.get_mount_info, mount, device, uuids)
578
604
 
579
- pool.close() # done with new workers, start gc
605
+ # done with spawning new workers, start gc
606
+ executor.shutdown()
580
607
 
581
- # wait for workers and get results
582
- while results:
608
+ while results: # wait for workers and get results
583
609
  for mount in list(results):
584
610
  done = False
585
611
  res = results[mount]['extra']
586
612
  try:
587
- if res.ready():
613
+ if res.done():
588
614
  done = True
589
- if res.successful():
590
- mount_size, uuid = res.get()
615
+ if res.exception() is None:
616
+ mount_size, uuid = res.result()
591
617
  if mount_size:
592
618
  results[mount]['info'].update(mount_size)
593
619
  results[mount]['info']['uuid'] = uuid or 'N/A'
594
620
  else:
595
621
  # failed, try to find out why, if 'res.successful' we know there are no exceptions
596
- results[mount]['info']['note'] = 'Could not get extra information: %s.' % (to_text(res.get()))
622
+ results[mount]['info']['note'] = f'Could not get extra information: {res.exception()}'
597
623
 
598
- elif time.time() > results[mount]['timelimit']:
624
+ elif time.monotonic() > results[mount]['timelimit']:
599
625
  done = True
600
626
  self.module.warn("Timeout exceeded when getting mount info for %s" % mount)
601
627
  results[mount]['info']['note'] = 'Could not get extra information due to timeout'
@@ -744,10 +770,24 @@ class LinuxHardware(Hardware):
744
770
  if serial:
745
771
  d['serial'] = serial
746
772
 
747
- for key, test in [('removable', '/removable'),
748
- ('support_discard', '/queue/discard_granularity'),
749
- ]:
750
- d[key] = get_file_content(sysdir + test)
773
+ d['removable'] = get_file_content(sysdir + '/removable')
774
+
775
+ # Historically, `support_discard` simply returned the value of
776
+ # `/sys/block/{device}/queue/discard_granularity`. When its value
777
+ # is `0`, then the block device doesn't support discards;
778
+ # _however_, it being greater than zero doesn't necessarily mean
779
+ # that the block device _does_ support discards.
780
+ #
781
+ # Another indication that a block device doesn't support discards
782
+ # is `/sys/block/{device}/queue/discard_max_hw_bytes` being equal
783
+ # to `0` (with the same caveat as above). So if either of those are
784
+ # `0`, set `support_discard` to zero, otherwise set it to the value
785
+ # of `discard_granularity` for backwards compatibility.
786
+ d['support_discard'] = (
787
+ '0'
788
+ if get_file_content(sysdir + '/queue/discard_max_hw_bytes') == '0'
789
+ else get_file_content(sysdir + '/queue/discard_granularity')
790
+ )
751
791
 
752
792
  if diskname in devs_wwn:
753
793
  d['wwn'] = devs_wwn[diskname]
@@ -765,12 +805,12 @@ class LinuxHardware(Hardware):
765
805
  part['links'][link_type] = link_values.get(partname, [])
766
806
 
767
807
  part['start'] = get_file_content(part_sysdir + "/start", 0)
768
- part['sectors'] = get_file_content(part_sysdir + "/size", 0)
769
-
770
808
  part['sectorsize'] = get_file_content(part_sysdir + "/queue/logical_block_size")
771
809
  if not part['sectorsize']:
772
810
  part['sectorsize'] = get_file_content(part_sysdir + "/queue/hw_sector_size", 512)
773
- part['size'] = bytes_to_human((float(part['sectors']) * 512.0))
811
+ # sysfs sectorcount assumes 512 blocksize. Convert using the correct sectorsize
812
+ part['sectors'] = int(get_file_content(part_sysdir + "/size", 0)) * 512 // int(part['sectorsize'])
813
+ part['size'] = bytes_to_human(float(part['sectors']) * float(part['sectorsize']))
774
814
  part['uuid'] = get_partition_uuid(partname)
775
815
  self.get_holders(part, part_sysdir)
776
816
 
@@ -784,13 +824,14 @@ class LinuxHardware(Hardware):
784
824
  if m:
785
825
  d['scheduler_mode'] = m.group(2)
786
826
 
787
- d['sectors'] = get_file_content(sysdir + "/size")
788
- if not d['sectors']:
789
- d['sectors'] = 0
790
827
  d['sectorsize'] = get_file_content(sysdir + "/queue/logical_block_size")
791
828
  if not d['sectorsize']:
792
829
  d['sectorsize'] = get_file_content(sysdir + "/queue/hw_sector_size", 512)
793
- d['size'] = bytes_to_human(float(d['sectors']) * 512.0)
830
+ # sysfs sectorcount assumes 512 blocksize. Convert using the correct sectorsize
831
+ d['sectors'] = int(get_file_content(sysdir + "/size")) * 512 // int(d['sectorsize'])
832
+ if not d['sectors']:
833
+ d['sectors'] = 0
834
+ d['size'] = bytes_to_human(float(d['sectors']) * float(d['sectorsize']))
794
835
 
795
836
  d['host'] = ""
796
837
 
@@ -833,21 +874,24 @@ class LinuxHardware(Hardware):
833
874
  """ Get LVM Facts if running as root and lvm utils are available """
834
875
 
835
876
  lvm_facts = {'lvm': 'N/A'}
877
+ vgs_cmd = self.module.get_bin_path('vgs')
878
+ if vgs_cmd is None:
879
+ return lvm_facts
836
880
 
837
- if os.getuid() == 0 and self.module.get_bin_path('vgs'):
881
+ if os.getuid() == 0:
838
882
  lvm_util_options = '--noheadings --nosuffix --units g --separator ,'
839
883
 
840
- vgs_path = self.module.get_bin_path('vgs')
841
884
  # vgs fields: VG #PV #LV #SN Attr VSize VFree
842
885
  vgs = {}
843
- if vgs_path:
844
- rc, vg_lines, err = self.module.run_command('%s %s' % (vgs_path, lvm_util_options))
845
- for vg_line in vg_lines.splitlines():
846
- items = vg_line.strip().split(',')
847
- vgs[items[0]] = {'size_g': items[-2],
848
- 'free_g': items[-1],
849
- 'num_lvs': items[2],
850
- 'num_pvs': items[1]}
886
+ rc, vg_lines, err = self.module.run_command('%s %s' % (vgs_cmd, lvm_util_options))
887
+ for vg_line in vg_lines.splitlines():
888
+ items = vg_line.strip().split(',')
889
+ vgs[items[0]] = {
890
+ 'size_g': items[-2],
891
+ 'free_g': items[-1],
892
+ 'num_lvs': items[2],
893
+ 'num_pvs': items[1]
894
+ }
851
895
 
852
896
  lvs_path = self.module.get_bin_path('lvs')
853
897
  # lvs fields:
@@ -162,6 +162,9 @@ class NetBSDHardware(Hardware):
162
162
  def get_uptime_facts(self):
163
163
  # On NetBSD, we need to call sysctl with -n to get this value as an int.
164
164
  sysctl_cmd = self.module.get_bin_path('sysctl')
165
+ if sysctl_cmd is None:
166
+ return {}
167
+
165
168
  cmd = [sysctl_cmd, '-n', 'kern.boottime']
166
169
 
167
170
  rc, out, err = self.module.run_command(cmd)
@@ -54,7 +54,7 @@ class OpenBSDHardware(Hardware):
54
54
  hardware_facts.update(self.get_dmi_facts())
55
55
  hardware_facts.update(self.get_uptime_facts())
56
56
 
57
- # storage devices notorioslly prone to hang/block so they are under a timeout
57
+ # storage devices notoriously prone to hang/block so they are under a timeout
58
58
  try:
59
59
  hardware_facts.update(self.get_mount_facts())
60
60
  except timeout.TimeoutError:
@@ -113,6 +113,9 @@ class OpenBSDHardware(Hardware):
113
113
  def get_uptime_facts(self):
114
114
  # On openbsd, we need to call it with -n to get this value as an int.
115
115
  sysctl_cmd = self.module.get_bin_path('sysctl')
116
+ if sysctl_cmd is None:
117
+ return {}
118
+
116
119
  cmd = [sysctl_cmd, '-n', 'kern.boottime']
117
120
 
118
121
  rc, out, err = self.module.run_command(cmd)
@@ -172,7 +172,13 @@ class SunOSHardware(Hardware):
172
172
  rc, platform, err = self.module.run_command('/usr/bin/uname -i')
173
173
  platform_sbin = '/usr/platform/' + platform.rstrip() + '/sbin'
174
174
 
175
- prtdiag_path = self.module.get_bin_path("prtdiag", opt_dirs=[platform_sbin])
175
+ prtdiag_path = self.module.get_bin_path(
176
+ "prtdiag",
177
+ opt_dirs=[platform_sbin]
178
+ )
179
+ if prtdiag_path is None:
180
+ return dmi_facts
181
+
176
182
  rc, out, err = self.module.run_command(prtdiag_path)
177
183
  # rc returns 1
178
184
  if out:
@@ -32,20 +32,21 @@ class AIXNetwork(GenericBsdIfconfigNetwork):
32
32
  interface = dict(v4={}, v6={})
33
33
 
34
34
  netstat_path = self.module.get_bin_path('netstat')
35
-
36
- if netstat_path:
37
- rc, out, err = self.module.run_command([netstat_path, '-nr'])
38
-
39
- lines = out.splitlines()
40
- for line in lines:
41
- words = line.split()
42
- if len(words) > 1 and words[0] == 'default':
43
- if '.' in words[1]:
44
- interface['v4']['gateway'] = words[1]
45
- interface['v4']['interface'] = words[5]
46
- elif ':' in words[1]:
47
- interface['v6']['gateway'] = words[1]
48
- interface['v6']['interface'] = words[5]
35
+ if netstat_path is None:
36
+ return interface['v4'], interface['v6']
37
+
38
+ rc, out, err = self.module.run_command([netstat_path, '-nr'])
39
+
40
+ lines = out.splitlines()
41
+ for line in lines:
42
+ words = line.split()
43
+ if len(words) > 1 and words[0] == 'default':
44
+ if '.' in words[1]:
45
+ interface['v4']['gateway'] = words[1]
46
+ interface['v4']['interface'] = words[5]
47
+ elif ':' in words[1]:
48
+ interface['v6']['gateway'] = words[1]
49
+ interface['v6']['interface'] = words[5]
49
50
 
50
51
  return interface['v4'], interface['v6']
51
52
 
@@ -58,9 +59,7 @@ class AIXNetwork(GenericBsdIfconfigNetwork):
58
59
  all_ipv6_addresses=[],
59
60
  )
60
61
 
61
- uname_rc = None
62
- uname_out = None
63
- uname_err = None
62
+ uname_rc = uname_out = uname_err = None
64
63
  uname_path = self.module.get_bin_path('uname')
65
64
  if uname_path:
66
65
  uname_rc, uname_out, uname_err = self.module.run_command([uname_path, '-W'])
@@ -82,7 +82,10 @@ class FcWwnInitiatorFactCollector(BaseFactCollector):
82
82
  fc_facts['fibre_channel_wwn'].append(data[-1].rstrip())
83
83
  elif sys.platform.startswith('hp-ux'):
84
84
  cmd = module.get_bin_path('ioscan')
85
- fcmsu_cmd = module.get_bin_path('fcmsutil', opt_dirs=['/opt/fcms/bin'])
85
+ fcmsu_cmd = module.get_bin_path(
86
+ 'fcmsutil',
87
+ opt_dirs=['/opt/fcms/bin'],
88
+ )
86
89
  # go ahead if we have both commands available
87
90
  if cmd and fcmsu_cmd:
88
91
  # ioscan / get list of available fibre-channel devices (fcd)
@@ -20,7 +20,7 @@ from ansible.module_utils.facts.network.base import Network, NetworkCollector
20
20
 
21
21
  class HPUXNetwork(Network):
22
22
  """
23
- HP-UX-specifig subclass of Network. Defines networking facts:
23
+ HP-UX-specific subclass of Network. Defines networking facts:
24
24
  - default_interface
25
25
  - interfaces (a list of interface names)
26
26
  - interface_<name> dictionary of ipv4 address information.
@@ -29,7 +29,10 @@ class HPUXNetwork(Network):
29
29
 
30
30
  def populate(self, collected_facts=None):
31
31
  network_facts = {}
32
- netstat_path = self.module.get_bin_path('netstat')
32
+ netstat_path = self.module.get_bin_path(
33
+ 'netstat',
34
+ opt_dirs=['/usr/bin']
35
+ )
33
36
 
34
37
  if netstat_path is None:
35
38
  return network_facts
@@ -46,7 +49,14 @@ class HPUXNetwork(Network):
46
49
 
47
50
  def get_default_interfaces(self):
48
51
  default_interfaces = {}
49
- rc, out, err = self.module.run_command("/usr/bin/netstat -nr")
52
+ netstat_path = self.module.get_bin_path(
53
+ 'netstat',
54
+ opt_dirs=['/usr/bin']
55
+ )
56
+
57
+ if netstat_path is None:
58
+ return default_interfaces
59
+ rc, out, err = self.module.run_command("%s -nr" % netstat_path)
50
60
  lines = out.splitlines()
51
61
  for line in lines:
52
62
  words = line.split()
@@ -59,7 +69,14 @@ class HPUXNetwork(Network):
59
69
 
60
70
  def get_interfaces_info(self):
61
71
  interfaces = {}
62
- rc, out, err = self.module.run_command("/usr/bin/netstat -niw")
72
+ netstat_path = self.module.get_bin_path(
73
+ 'netstat',
74
+ opt_dirs=['/usr/bin']
75
+ )
76
+
77
+ if netstat_path is None:
78
+ return interfaces
79
+ rc, out, err = self.module.run_command("%s -niw" % netstat_path)
63
80
  lines = out.splitlines()
64
81
  for line in lines:
65
82
  words = line.split()
@@ -21,7 +21,6 @@ import sys
21
21
 
22
22
  import ansible.module_utils.compat.typing as t
23
23
 
24
- from ansible.module_utils.common.process import get_bin_path
25
24
  from ansible.module_utils.facts.utils import get_file_content
26
25
  from ansible.module_utils.facts.network.base import NetworkCollector
27
26
 
@@ -80,9 +79,8 @@ class IscsiInitiatorNetworkCollector(NetworkCollector):
80
79
  iscsi_facts['iscsi_iqn'] = line.split('=', 1)[1]
81
80
  break
82
81
  elif sys.platform.startswith('aix'):
83
- try:
84
- cmd = get_bin_path('lsattr')
85
- except ValueError:
82
+ cmd = module.get_bin_path('lsattr')
83
+ if cmd is None:
86
84
  return iscsi_facts
87
85
 
88
86
  cmd += " -E -l iscsi0"
@@ -92,10 +90,11 @@ class IscsiInitiatorNetworkCollector(NetworkCollector):
92
90
  iscsi_facts['iscsi_iqn'] = line.split()[1].rstrip()
93
91
 
94
92
  elif sys.platform.startswith('hp-ux'):
95
- # try to find it in the default PATH and opt_dirs
96
- try:
97
- cmd = get_bin_path('iscsiutil', opt_dirs=['/opt/iscsi/bin'])
98
- except ValueError:
93
+ cmd = module.get_bin_path(
94
+ 'iscsiutil',
95
+ opt_dirs=['/opt/iscsi/bin']
96
+ )
97
+ if cmd is None:
99
98
  return iscsi_facts
100
99
 
101
100
  cmd += " -l"
@@ -295,8 +295,6 @@ class LinuxNetwork(Network):
295
295
  if not address == '::1':
296
296
  ips['all_ipv6_addresses'].append(address)
297
297
 
298
- ip_path = self.module.get_bin_path("ip")
299
-
300
298
  args = [ip_path, 'addr', 'show', 'primary', 'dev', device]
301
299
  rc, primary_data, stderr = self.module.run_command(args, errors='surrogate_then_replace')
302
300
  if rc == 0:
@@ -22,8 +22,14 @@ class FacterFactCollector(BaseFactCollector):
22
22
  namespace=namespace)
23
23
 
24
24
  def find_facter(self, module):
25
- facter_path = module.get_bin_path('facter', opt_dirs=['/opt/puppetlabs/bin'])
26
- cfacter_path = module.get_bin_path('cfacter', opt_dirs=['/opt/puppetlabs/bin'])
25
+ facter_path = module.get_bin_path(
26
+ 'facter',
27
+ opt_dirs=['/opt/puppetlabs/bin']
28
+ )
29
+ cfacter_path = module.get_bin_path(
30
+ 'cfacter',
31
+ opt_dirs=['/opt/puppetlabs/bin']
32
+ )
27
33
 
28
34
  # Prefer to use cfacter if available
29
35
  if cfacter_path is not None:
@@ -73,7 +79,6 @@ class FacterFactCollector(BaseFactCollector):
73
79
  try:
74
80
  facter_dict = json.loads(facter_output)
75
81
  except Exception:
76
- # FIXME: maybe raise a FactCollectorError with some info attrs?
77
- pass
82
+ module.warn("Failed to parse facter facts")
78
83
 
79
84
  return facter_dict
@@ -36,10 +36,11 @@ class OhaiFactCollector(BaseFactCollector):
36
36
  namespace=namespace)
37
37
 
38
38
  def find_ohai(self, module):
39
- ohai_path = module.get_bin_path('ohai')
40
- return ohai_path
39
+ return module.get_bin_path(
40
+ 'ohai'
41
+ )
41
42
 
42
- def run_ohai(self, module, ohai_path,):
43
+ def run_ohai(self, module, ohai_path):
43
44
  rc, out, err = module.run_command(ohai_path)
44
45
  return rc, out, err
45
46
 
@@ -67,7 +68,6 @@ class OhaiFactCollector(BaseFactCollector):
67
68
  try:
68
69
  ohai_facts = json.loads(ohai_output)
69
70
  except Exception:
70
- # FIXME: useful error, logging, something...
71
- pass
71
+ module.warn("Failed to gather ohai facts")
72
72
 
73
73
  return ohai_facts