chef 15.11.3-universal-mingw32 → 16.1.16-universal-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (513) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -7
  3. data/README.md +1 -1
  4. data/Rakefile +44 -16
  5. data/chef.gemspec +6 -4
  6. data/distro/powershell/chef/chef.psm1 +3 -3
  7. data/distro/templates/powershell/chef/chef.psm1.erb +3 -3
  8. data/lib/chef/action_collection.rb +16 -5
  9. data/lib/chef/application.rb +33 -54
  10. data/lib/chef/application/apply.rb +18 -1
  11. data/lib/chef/application/base.rb +8 -3
  12. data/lib/chef/application/knife.rb +1 -1
  13. data/lib/chef/chef_class.rb +4 -4
  14. data/lib/chef/chef_fs/file_system/chef_server/acls_dir.rb +1 -1
  15. data/lib/chef/chef_fs/file_system/chef_server/cookbook_file.rb +1 -1
  16. data/lib/chef/chef_fs/file_system/chef_server/rest_list_entry.rb +6 -2
  17. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb +3 -3
  18. data/lib/chef/chef_fs/file_system/repository/directory.rb +1 -1
  19. data/lib/chef/chef_fs/parallelizer/parallel_enumerable.rb +1 -1
  20. data/lib/chef/chef_fs/path_utils.rb +3 -3
  21. data/lib/chef/client.rb +16 -14
  22. data/lib/chef/config.rb +1 -1
  23. data/lib/chef/cookbook/file_system_file_vendor.rb +1 -1
  24. data/lib/chef/cookbook/gem_installer.rb +1 -1
  25. data/lib/chef/cookbook/metadata.rb +45 -22
  26. data/lib/chef/cookbook_loader.rb +1 -1
  27. data/lib/chef/cookbook_manifest.rb +1 -1
  28. data/lib/chef/cookbook_site_streaming_uploader.rb +1 -1
  29. data/lib/chef/cookbook_version.rb +38 -3
  30. data/lib/chef/data_collector.rb +1 -1
  31. data/lib/chef/data_collector/error_handlers.rb +1 -1
  32. data/lib/chef/data_collector/run_end_message.rb +7 -1
  33. data/lib/chef/decorator/lazy_array.rb +2 -2
  34. data/lib/chef/deprecated.rb +4 -0
  35. data/lib/chef/digester.rb +4 -4
  36. data/lib/chef/dist.rb +8 -0
  37. data/lib/chef/dsl/chef_vault.rb +84 -0
  38. data/lib/chef/dsl/declare_resource.rb +7 -5
  39. data/lib/chef/dsl/platform_introspection.rb +3 -2
  40. data/lib/chef/dsl/recipe.rb +7 -12
  41. data/lib/chef/dsl/universal.rb +3 -7
  42. data/lib/chef/encrypted_data_bag_item/decryptor.rb +1 -1
  43. data/lib/chef/encrypted_data_bag_item/encryptor.rb +1 -1
  44. data/lib/chef/event_dispatch/base.rb +3 -0
  45. data/lib/chef/formatters/base.rb +1 -1
  46. data/lib/chef/formatters/doc.rb +1 -1
  47. data/lib/chef/formatters/indentable_output_stream.rb +7 -16
  48. data/lib/chef/http.rb +1 -1
  49. data/lib/chef/http/decompressor.rb +1 -1
  50. data/lib/chef/http/http_request.rb +3 -2
  51. data/lib/chef/json_compat.rb +1 -1
  52. data/lib/chef/key.rb +1 -1
  53. data/lib/chef/knife.rb +2 -4
  54. data/lib/chef/knife/acl_add.rb +57 -0
  55. data/lib/chef/knife/acl_base.rb +183 -0
  56. data/lib/chef/knife/acl_bulk_add.rb +78 -0
  57. data/lib/chef/knife/acl_bulk_remove.rb +83 -0
  58. data/lib/chef/knife/acl_remove.rb +62 -0
  59. data/lib/chef/knife/acl_show.rb +56 -0
  60. data/lib/chef/knife/bootstrap.rb +84 -90
  61. data/lib/chef/knife/bootstrap/chef_vault_handler.rb +2 -2
  62. data/lib/chef/knife/bootstrap/client_builder.rb +2 -2
  63. data/lib/chef/knife/bootstrap/templates/chef-full.erb +11 -11
  64. data/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb +12 -12
  65. data/lib/chef/knife/core/bootstrap_context.rb +63 -60
  66. data/lib/chef/knife/core/generic_presenter.rb +4 -3
  67. data/lib/chef/knife/core/hashed_command_loader.rb +1 -1
  68. data/lib/chef/knife/core/node_presenter.rb +2 -2
  69. data/lib/chef/knife/core/status_presenter.rb +5 -5
  70. data/lib/chef/knife/core/subcommand_loader.rb +1 -1
  71. data/lib/chef/knife/core/ui.rb +17 -1
  72. data/lib/chef/knife/core/windows_bootstrap_context.rb +44 -42
  73. data/lib/chef/knife/data_bag_secret_options.rb +18 -45
  74. data/lib/chef/knife/group_add.rb +55 -0
  75. data/lib/chef/knife/{cookbook_site_download.rb → group_create.rb} +21 -12
  76. data/lib/chef/knife/group_destroy.rb +53 -0
  77. data/lib/chef/knife/{cookbook_site_list.rb → group_list.rb} +14 -11
  78. data/lib/chef/knife/group_remove.rb +56 -0
  79. data/lib/chef/knife/{cookbook_site_install.rb → group_show.rb} +21 -12
  80. data/lib/chef/knife/key_create_base.rb +1 -1
  81. data/lib/chef/knife/key_edit_base.rb +1 -1
  82. data/lib/chef/knife/ssh.rb +12 -31
  83. data/lib/chef/knife/status.rb +3 -3
  84. data/lib/chef/knife/supermarket_download.rb +1 -2
  85. data/lib/chef/knife/supermarket_install.rb +2 -3
  86. data/lib/chef/knife/supermarket_list.rb +1 -2
  87. data/lib/chef/knife/supermarket_search.rb +1 -2
  88. data/lib/chef/knife/supermarket_share.rb +1 -2
  89. data/lib/chef/knife/supermarket_show.rb +1 -2
  90. data/lib/chef/knife/supermarket_unshare.rb +1 -2
  91. data/lib/chef/knife/{cookbook_site_show.rb → user_dissociate.rb} +15 -13
  92. data/lib/chef/knife/{cookbook_site_search.rb → user_invite_add.rb} +16 -13
  93. data/lib/chef/knife/user_invite_list.rb +34 -0
  94. data/lib/chef/knife/user_invite_rescind.rb +63 -0
  95. data/lib/chef/knife/yaml_convert.rb +91 -0
  96. data/lib/chef/mixin/api_version_request_handling.rb +1 -1
  97. data/lib/chef/mixin/checksum.rb +0 -1
  98. data/lib/chef/mixin/openssl_helper.rb +4 -4
  99. data/lib/chef/mixin/powershell_exec.rb +10 -1
  100. data/lib/chef/mixin/powershell_out.rb +1 -1
  101. data/lib/chef/mixin/properties.rb +16 -2
  102. data/lib/chef/mixin/shell_out.rb +1 -5
  103. data/lib/chef/monkey_patches/net_http.rb +0 -4
  104. data/lib/chef/node.rb +18 -6
  105. data/lib/chef/node/attribute.rb +2 -2
  106. data/lib/chef/node/immutable_collections.rb +1 -1
  107. data/lib/chef/node/mixin/immutablize_array.rb +4 -0
  108. data/lib/chef/node/mixin/immutablize_hash.rb +3 -0
  109. data/lib/chef/node_map.rb +5 -31
  110. data/lib/chef/platform/priority_map.rb +4 -4
  111. data/lib/chef/platform/query_helpers.rb +6 -34
  112. data/lib/chef/policy_builder/policyfile.rb +1 -1
  113. data/lib/chef/powershell.rb +14 -0
  114. data/lib/chef/property.rb +24 -6
  115. data/lib/chef/provider.rb +40 -6
  116. data/lib/chef/provider/cron.rb +2 -2
  117. data/lib/chef/provider/directory.rb +3 -3
  118. data/lib/chef/provider/dsc_resource.rb +1 -1
  119. data/lib/chef/provider/dsc_script.rb +1 -1
  120. data/lib/chef/provider/execute.rb +3 -9
  121. data/lib/chef/provider/file.rb +6 -6
  122. data/lib/chef/provider/git.rb +84 -27
  123. data/lib/chef/provider/group.rb +4 -4
  124. data/lib/chef/provider/http_request.rb +6 -6
  125. data/lib/chef/provider/ifconfig.rb +4 -4
  126. data/lib/chef/provider/launchd.rb +45 -64
  127. data/lib/chef/provider/link.rb +2 -2
  128. data/lib/chef/provider/mount.rb +5 -5
  129. data/lib/chef/provider/osx_profile.rb +7 -3
  130. data/lib/chef/provider/package.rb +2 -2
  131. data/lib/chef/provider/package/cab.rb +5 -6
  132. data/lib/chef/provider/package/chocolatey.rb +1 -3
  133. data/lib/chef/provider/package/dnf.rb +66 -10
  134. data/lib/chef/provider/package/dnf/dnf_helper.py +85 -26
  135. data/lib/chef/provider/package/dnf/python_helper.rb +79 -36
  136. data/lib/chef/provider/package/dnf/version.rb +5 -1
  137. data/lib/chef/provider/package/dpkg.rb +1 -1
  138. data/lib/chef/provider/package/freebsd/base.rb +2 -1
  139. data/lib/chef/provider/package/homebrew.rb +107 -43
  140. data/lib/chef/provider/package/macports.rb +0 -2
  141. data/lib/chef/provider/package/msu.rb +4 -1
  142. data/lib/chef/provider/package/pacman.rb +25 -34
  143. data/lib/chef/provider/package/portage.rb +1 -0
  144. data/lib/chef/provider/package/powershell.rb +1 -1
  145. data/lib/chef/provider/package/rubygems.rb +30 -3
  146. data/lib/chef/provider/package/windows.rb +29 -53
  147. data/lib/chef/provider/package/windows/msi.rb +2 -2
  148. data/lib/chef/provider/package/yum.rb +1 -9
  149. data/lib/chef/provider/package/yum/yum_cache.rb +1 -1
  150. data/lib/chef/provider/package/zypper.rb +0 -1
  151. data/lib/chef/provider/powershell_script.rb +5 -11
  152. data/lib/chef/provider/registry_key.rb +4 -4
  153. data/lib/chef/provider/remote_directory.rb +5 -5
  154. data/lib/chef/provider/remote_file/ftp.rb +3 -2
  155. data/lib/chef/provider/remote_file/local_file.rb +2 -1
  156. data/lib/chef/provider/remote_file/sftp.rb +3 -2
  157. data/lib/chef/provider/route.rb +5 -3
  158. data/lib/chef/provider/ruby_block.rb +1 -1
  159. data/lib/chef/provider/script.rb +2 -2
  160. data/lib/chef/provider/service.rb +8 -8
  161. data/lib/chef/provider/service/aixinit.rb +1 -1
  162. data/lib/chef/provider/service/arch.rb +1 -1
  163. data/lib/chef/provider/service/debian.rb +30 -28
  164. data/lib/chef/provider/service/macosx.rb +16 -10
  165. data/lib/chef/provider/service/systemd.rb +12 -12
  166. data/lib/chef/provider/service/upstart.rb +1 -1
  167. data/lib/chef/provider/service/windows.rb +5 -11
  168. data/lib/chef/provider/subversion.rb +25 -5
  169. data/lib/chef/provider/systemd_unit.rb +26 -25
  170. data/lib/chef/provider/user.rb +6 -6
  171. data/lib/chef/provider/user/aix.rb +1 -1
  172. data/lib/chef/provider/user/dscl.rb +6 -6
  173. data/lib/chef/provider/user/mac.rb +20 -15
  174. data/lib/chef/provider/whyrun_safe_ruby_block.rb +1 -1
  175. data/lib/chef/provider/windows_env.rb +3 -3
  176. data/lib/chef/provider/windows_script.rb +2 -2
  177. data/lib/chef/provider/windows_task.rb +10 -10
  178. data/lib/chef/providers.rb +0 -6
  179. data/lib/chef/recipe.rb +36 -0
  180. data/lib/chef/resource.rb +44 -57
  181. data/lib/chef/resource/action_class.rb +24 -22
  182. data/lib/chef/resource/alternatives.rb +210 -0
  183. data/lib/chef/resource/apt_package.rb +33 -3
  184. data/lib/chef/resource/apt_preference.rb +103 -7
  185. data/lib/chef/resource/apt_repository.rb +357 -18
  186. data/lib/chef/resource/apt_update.rb +58 -5
  187. data/lib/chef/resource/archive_file.rb +6 -5
  188. data/lib/chef/resource/bash.rb +3 -1
  189. data/lib/chef/resource/batch.rb +1 -1
  190. data/lib/chef/resource/bff_package.rb +10 -2
  191. data/lib/chef/resource/breakpoint.rb +1 -2
  192. data/lib/chef/resource/build_essential.rb +49 -51
  193. data/lib/chef/resource/cab_package.rb +9 -2
  194. data/lib/chef/resource/chef_client_cron.rb +228 -0
  195. data/lib/chef/resource/chef_client_scheduled_task.rb +201 -0
  196. data/lib/chef/resource/chef_client_systemd_timer.rb +180 -0
  197. data/lib/chef/resource/chef_gem.rb +15 -18
  198. data/lib/chef/resource/chef_handler.rb +5 -4
  199. data/lib/chef/resource/chef_sleep.rb +7 -5
  200. data/lib/chef/resource/chef_vault_secret.rb +135 -0
  201. data/lib/chef/resource/chocolatey_config.rb +8 -4
  202. data/lib/chef/resource/chocolatey_feature.rb +7 -4
  203. data/lib/chef/resource/chocolatey_package.rb +7 -4
  204. data/lib/chef/resource/chocolatey_source.rb +7 -4
  205. data/lib/chef/resource/cookbook_file.rb +4 -3
  206. data/lib/chef/resource/cron.rb +34 -80
  207. data/lib/chef/resource/cron_access.rb +10 -6
  208. data/lib/chef/resource/cron_d.rb +44 -95
  209. data/lib/chef/resource/csh.rb +3 -1
  210. data/lib/chef/resource/directory.rb +3 -3
  211. data/lib/chef/resource/dmg_package.rb +22 -19
  212. data/lib/chef/resource/dnf_package.rb +3 -4
  213. data/lib/chef/resource/dpkg_package.rb +3 -2
  214. data/lib/chef/resource/dsc_resource.rb +6 -4
  215. data/lib/chef/resource/dsc_script.rb +3 -2
  216. data/lib/chef/resource/execute.rb +15 -14
  217. data/lib/chef/resource/file.rb +14 -9
  218. data/lib/chef/resource/freebsd_package.rb +3 -2
  219. data/lib/chef/resource/gem_package.rb +19 -11
  220. data/lib/chef/resource/group.rb +5 -2
  221. data/lib/chef/resource/helpers/cron_validations.rb +98 -0
  222. data/lib/chef/resource/homebrew_cask.rb +3 -2
  223. data/lib/chef/resource/homebrew_package.rb +5 -3
  224. data/lib/chef/resource/homebrew_tap.rb +3 -2
  225. data/lib/chef/resource/hostname.rb +26 -20
  226. data/lib/chef/resource/http_request.rb +1 -2
  227. data/lib/chef/resource/ifconfig.rb +8 -8
  228. data/lib/chef/resource/ips_package.rb +11 -3
  229. data/lib/chef/resource/kernel_module.rb +30 -30
  230. data/lib/chef/resource/ksh.rb +3 -1
  231. data/lib/chef/resource/launchd.rb +3 -3
  232. data/lib/chef/resource/link.rb +5 -27
  233. data/lib/chef/resource/locale.rb +60 -26
  234. data/lib/chef/resource/log.rb +13 -2
  235. data/lib/chef/resource/lwrp_base.rb +1 -1
  236. data/lib/chef/resource/macos_userdefaults.rb +18 -10
  237. data/lib/chef/resource/macosx_service.rb +3 -2
  238. data/lib/chef/resource/macports_package.rb +10 -2
  239. data/lib/chef/resource/mdadm.rb +63 -3
  240. data/lib/chef/resource/mount.rb +4 -1
  241. data/lib/chef/resource/msu_package.rb +19 -2
  242. data/lib/chef/resource/notify_group.rb +8 -3
  243. data/lib/chef/resource/ohai.rb +20 -4
  244. data/lib/chef/resource/ohai_hint.rb +4 -13
  245. data/lib/chef/resource/openbsd_package.rb +10 -2
  246. data/lib/chef/resource/openssl_dhparam.rb +11 -2
  247. data/lib/chef/resource/openssl_ec_private_key.rb +24 -2
  248. data/lib/chef/resource/openssl_ec_public_key.rb +22 -2
  249. data/lib/chef/resource/openssl_rsa_private_key.rb +21 -2
  250. data/lib/chef/resource/openssl_rsa_public_key.rb +23 -2
  251. data/lib/chef/resource/openssl_x509_certificate.rb +38 -2
  252. data/lib/chef/resource/openssl_x509_crl.rb +13 -2
  253. data/lib/chef/resource/openssl_x509_request.rb +38 -2
  254. data/lib/chef/resource/osx_profile.rb +4 -3
  255. data/lib/chef/resource/package.rb +3 -2
  256. data/lib/chef/resource/pacman_package.rb +3 -2
  257. data/lib/chef/resource/paludis_package.rb +13 -4
  258. data/lib/chef/resource/perl.rb +3 -1
  259. data/lib/chef/resource/plist.rb +207 -0
  260. data/lib/chef/resource/portage_package.rb +14 -4
  261. data/lib/chef/resource/powershell_package.rb +2 -4
  262. data/lib/chef/resource/powershell_package_source.rb +4 -2
  263. data/lib/chef/resource/powershell_script.rb +8 -18
  264. data/lib/chef/resource/python.rb +3 -1
  265. data/lib/chef/resource/reboot.rb +1 -2
  266. data/lib/chef/resource/registry_key.rb +2 -3
  267. data/lib/chef/resource/remote_directory.rb +3 -1
  268. data/lib/chef/resource/remote_file.rb +3 -2
  269. data/lib/chef/resource/rhsm_errata.rb +1 -4
  270. data/lib/chef/resource/rhsm_errata_level.rb +1 -2
  271. data/lib/chef/resource/rhsm_register.rb +3 -3
  272. data/lib/chef/resource/rhsm_repo.rb +4 -3
  273. data/lib/chef/resource/rhsm_subscription.rb +5 -4
  274. data/lib/chef/resource/route.rb +6 -2
  275. data/lib/chef/resource/rpm_package.rb +13 -3
  276. data/lib/chef/resource/ruby.rb +3 -1
  277. data/lib/chef/resource/ruby_block.rb +2 -5
  278. data/lib/chef/resource/scm/_scm.rb +49 -0
  279. data/lib/chef/resource/{scm.rb → scm/git.rb} +16 -30
  280. data/lib/chef/resource/{subversion.rb → scm/subversion.rb} +10 -7
  281. data/lib/chef/resource/script.rb +7 -4
  282. data/lib/chef/resource/service.rb +7 -8
  283. data/lib/chef/resource/smartos_package.rb +10 -2
  284. data/lib/chef/resource/snap_package.rb +4 -2
  285. data/lib/chef/resource/solaris_package.rb +10 -2
  286. data/lib/chef/resource/ssh_known_hosts_entry.rb +6 -3
  287. data/lib/chef/resource/sudo.rb +11 -11
  288. data/lib/chef/resource/support/cron.d.erb +1 -1
  289. data/lib/chef/resource/support/cron_access.erb +1 -1
  290. data/lib/chef/resource/support/sudoer.erb +1 -2
  291. data/lib/chef/resource/support/ulimit.erb +41 -0
  292. data/lib/chef/resource/swap_file.rb +7 -5
  293. data/lib/chef/resource/sysctl.rb +63 -4
  294. data/lib/chef/resource/systemd_unit.rb +6 -4
  295. data/lib/chef/resource/template.rb +0 -1
  296. data/lib/chef/resource/timezone.rb +8 -19
  297. data/lib/chef/resource/user.rb +3 -5
  298. data/lib/chef/resource/user/aix_user.rb +0 -2
  299. data/lib/chef/resource/user/dscl_user.rb +1 -1
  300. data/lib/chef/resource/user/linux_user.rb +0 -2
  301. data/lib/chef/resource/user/mac_user.rb +1 -1
  302. data/lib/chef/resource/user/pw_user.rb +0 -2
  303. data/lib/chef/resource/user/solaris_user.rb +0 -2
  304. data/lib/chef/resource/user/windows_user.rb +0 -2
  305. data/lib/chef/resource/user_ulimit.rb +116 -0
  306. data/lib/chef/resource/whyrun_safe_ruby_block.rb +1 -0
  307. data/lib/chef/resource/windows_ad_join.rb +20 -7
  308. data/lib/chef/resource/windows_auto_run.rb +2 -3
  309. data/lib/chef/resource/windows_certificate.rb +3 -3
  310. data/lib/chef/resource/windows_dfs_folder.rb +1 -2
  311. data/lib/chef/resource/windows_dfs_namespace.rb +1 -2
  312. data/lib/chef/resource/windows_dfs_server.rb +2 -3
  313. data/lib/chef/resource/windows_dns_record.rb +0 -1
  314. data/lib/chef/resource/windows_dns_zone.rb +0 -1
  315. data/lib/chef/resource/windows_env.rb +12 -4
  316. data/lib/chef/resource/windows_feature.rb +59 -4
  317. data/lib/chef/resource/windows_feature_dism.rb +24 -24
  318. data/lib/chef/resource/windows_feature_powershell.rb +44 -78
  319. data/lib/chef/resource/windows_firewall_rule.rb +121 -8
  320. data/lib/chef/resource/windows_font.rb +10 -2
  321. data/lib/chef/resource/windows_package.rb +76 -7
  322. data/lib/chef/resource/windows_pagefile.rb +31 -4
  323. data/lib/chef/resource/windows_path.rb +18 -2
  324. data/lib/chef/resource/windows_printer.rb +26 -7
  325. data/lib/chef/resource/windows_printer_port.rb +29 -2
  326. data/lib/chef/resource/windows_script.rb +3 -4
  327. data/lib/chef/resource/windows_security_policy.rb +119 -0
  328. data/lib/chef/resource/windows_service.rb +46 -32
  329. data/lib/chef/resource/windows_share.rb +22 -6
  330. data/lib/chef/resource/windows_shortcut.rb +13 -3
  331. data/lib/chef/resource/windows_task.rb +129 -16
  332. data/lib/chef/resource/windows_uac.rb +20 -2
  333. data/lib/chef/resource/windows_user_privilege.rb +199 -0
  334. data/lib/chef/resource/windows_workgroup.rb +19 -4
  335. data/lib/chef/resource/yum_package.rb +91 -7
  336. data/lib/chef/resource/yum_repository.rb +30 -12
  337. data/lib/chef/resource/zypper_package.rb +32 -5
  338. data/lib/chef/resource/zypper_repository.rb +19 -6
  339. data/lib/chef/resource_builder.rb +8 -0
  340. data/lib/chef/resource_inspector.rb +3 -2
  341. data/lib/chef/resource_resolver.rb +7 -14
  342. data/lib/chef/resources.rb +11 -3
  343. data/lib/chef/run_context/cookbook_compiler.rb +29 -5
  344. data/lib/chef/scan_access_control.rb +1 -1
  345. data/lib/chef/shell.rb +22 -0
  346. data/lib/chef/shell/ext.rb +1 -1
  347. data/lib/chef/version.rb +1 -1
  348. data/lib/chef/win32/api.rb +2 -2
  349. data/lib/chef/win32/api/error.rb +3 -1
  350. data/lib/chef/win32/api/file.rb +1 -1
  351. data/lib/chef/win32/api/net.rb +1 -0
  352. data/lib/chef/win32/api/security.rb +6 -0
  353. data/lib/chef/win32/file.rb +1 -9
  354. data/lib/chef/win32/mutex.rb +1 -1
  355. data/lib/chef/win32/net.rb +1 -0
  356. data/lib/chef/win32/security.rb +40 -2
  357. data/lib/chef/win32/security/sid.rb +4 -4
  358. data/spec/functional/assets/inittest +8 -7
  359. data/spec/functional/knife/ssh_spec.rb +23 -19
  360. data/spec/functional/resource/cron_spec.rb +10 -29
  361. data/spec/functional/resource/dnf_package_spec.rb +441 -156
  362. data/spec/functional/resource/git_spec.rb +184 -134
  363. data/spec/functional/resource/insserv_spec.rb +1 -1
  364. data/spec/functional/resource/launchd_spec.rb +232 -0
  365. data/spec/functional/resource/link_spec.rb +3 -3
  366. data/spec/functional/resource/locale_spec.rb +13 -2
  367. data/spec/functional/resource/msu_package_spec.rb +5 -2
  368. data/spec/functional/resource/powershell_script_spec.rb +7 -68
  369. data/spec/functional/resource/remote_file_spec.rb +1 -1
  370. data/spec/functional/resource/windows_security_policy_spec.rb +90 -0
  371. data/spec/functional/resource/windows_task_spec.rb +4 -4
  372. data/spec/functional/resource/windows_user_privilege_spec.rb +193 -0
  373. data/spec/functional/run_lock_spec.rb +1 -1
  374. data/spec/functional/shell_spec.rb +1 -1
  375. data/spec/functional/util/powershell/cmdlet_spec.rb +1 -1
  376. data/spec/functional/version_spec.rb +1 -1
  377. data/spec/functional/win32/registry_spec.rb +0 -6
  378. data/spec/functional/win32/security_spec.rb +22 -0
  379. data/spec/integration/client/client_spec.rb +123 -2
  380. data/spec/integration/knife/cookbook_show_spec.rb +28 -26
  381. data/spec/integration/knife/data_bag_show_spec.rb +1 -1
  382. data/spec/integration/knife/raw_spec.rb +34 -6
  383. data/spec/integration/knife/redirection_spec.rb +2 -2
  384. data/spec/integration/knife/show_spec.rb +32 -3
  385. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +3 -3
  386. data/spec/integration/recipes/noop_resource_spec.rb +1 -1
  387. data/spec/integration/recipes/notifies_spec.rb +49 -20
  388. data/spec/integration/recipes/notifying_block_spec.rb +8 -5
  389. data/spec/integration/recipes/provider_choice.rb +2 -0
  390. data/spec/integration/recipes/recipe_dsl_spec.rb +45 -143
  391. data/spec/integration/recipes/resource_action_spec.rb +16 -11
  392. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +1 -1
  393. data/spec/integration/recipes/resource_load_spec.rb +133 -12
  394. data/spec/integration/recipes/use_partial_spec.rb +112 -0
  395. data/spec/integration/solo/solo_spec.rb +3 -3
  396. data/spec/spec_helper.rb +18 -3
  397. data/spec/support/chef_helpers.rb +2 -2
  398. data/spec/support/lib/chef/resource/zen_follower.rb +2 -0
  399. data/spec/support/platform_helpers.rb +2 -20
  400. data/spec/support/recipe_dsl_helper.rb +83 -0
  401. data/spec/support/shared/functional/http.rb +2 -2
  402. data/spec/support/shared/functional/windows_script.rb +3 -16
  403. data/spec/support/shared/integration/knife_support.rb +9 -6
  404. data/spec/support/shared/unit/mock_shellout.rb +1 -1
  405. data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +4 -4
  406. data/spec/unit/application/apply_spec.rb +3 -0
  407. data/spec/unit/application/client_spec.rb +5 -1
  408. data/spec/unit/application_spec.rb +1 -2
  409. data/spec/unit/client_spec.rb +7 -5
  410. data/spec/unit/cookbook/gem_installer_spec.rb +2 -2
  411. data/spec/unit/cookbook/metadata_spec.rb +38 -19
  412. data/spec/unit/data_collector_spec.rb +39 -18
  413. data/spec/unit/file_access_control_spec.rb +1 -1
  414. data/spec/unit/json_compat_spec.rb +1 -1
  415. data/spec/unit/knife/bootstrap/chef_vault_handler_spec.rb +15 -15
  416. data/spec/unit/knife/bootstrap/client_builder_spec.rb +9 -9
  417. data/spec/unit/knife/bootstrap_spec.rb +20 -38
  418. data/spec/unit/knife/cookbook_show_spec.rb +1 -0
  419. data/spec/unit/knife/core/bootstrap_context_spec.rb +23 -43
  420. data/spec/unit/knife/core/ui_spec.rb +16 -0
  421. data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +9 -63
  422. data/spec/unit/knife/data_bag_secret_options_spec.rb +22 -14
  423. data/spec/unit/knife/ssh_spec.rb +8 -111
  424. data/spec/unit/knife/status_spec.rb +1 -1
  425. data/spec/unit/knife_spec.rb +18 -0
  426. data/spec/unit/mixin/openssl_helper_spec.rb +4 -4
  427. data/spec/unit/mixin/powershell_exec_spec.rb +10 -0
  428. data/spec/unit/mixin/shell_out_spec.rb +25 -31
  429. data/spec/unit/node/attribute_spec.rb +3 -3
  430. data/spec/unit/node_spec.rb +24 -0
  431. data/spec/unit/platform/query_helpers_spec.rb +0 -143
  432. data/spec/unit/property/state_spec.rb +12 -7
  433. data/spec/unit/property/validation_spec.rb +25 -1
  434. data/spec/unit/property_spec.rb +12 -9
  435. data/spec/unit/provider/apt_preference_spec.rb +14 -10
  436. data/spec/unit/provider/apt_repository_spec.rb +34 -36
  437. data/spec/unit/provider/apt_update_spec.rb +12 -11
  438. data/spec/unit/provider/cookbook_file_spec.rb +4 -4
  439. data/spec/unit/provider/cron_spec.rb +2 -2
  440. data/spec/unit/provider/directory_spec.rb +4 -15
  441. data/spec/unit/provider/file_spec.rb +4 -4
  442. data/spec/unit/provider/git_spec.rb +41 -1
  443. data/spec/unit/provider/group/groupadd_spec.rb +1 -1
  444. data/spec/unit/provider/launchd_spec.rb +8 -50
  445. data/spec/unit/provider/link_spec.rb +0 -1
  446. data/spec/unit/provider/log_spec.rb +3 -3
  447. data/spec/unit/provider/mdadm_spec.rb +3 -3
  448. data/spec/unit/provider/package/dnf/python_helper_spec.rb +1 -1
  449. data/spec/unit/provider/package/homebrew_spec.rb +280 -174
  450. data/spec/unit/provider/package/pacman_spec.rb +65 -147
  451. data/spec/unit/provider/package/portage_spec.rb +2 -2
  452. data/spec/unit/provider/package/powershell_spec.rb +3 -2
  453. data/spec/unit/provider/package/rubygems_spec.rb +211 -26
  454. data/spec/unit/provider/package/windows/exe_spec.rb +1 -1
  455. data/spec/unit/provider/powershell_script_spec.rb +21 -61
  456. data/spec/unit/provider/remote_file_spec.rb +3 -4
  457. data/spec/unit/provider/service/debian_service_spec.rb +34 -13
  458. data/spec/unit/provider/service/macosx_spec.rb +210 -214
  459. data/spec/unit/provider/service/systemd_service_spec.rb +23 -23
  460. data/spec/unit/provider/subversion_spec.rb +4 -2
  461. data/spec/unit/provider/template_spec.rb +3 -4
  462. data/spec/unit/provider/zypper_repository_spec.rb +17 -17
  463. data/spec/unit/provider_resolver_spec.rb +4 -4
  464. data/spec/unit/recipe_spec.rb +68 -0
  465. data/spec/unit/resource/alternatives_spec.rb +120 -0
  466. data/spec/unit/resource/apt_preference_spec.rb +0 -18
  467. data/spec/unit/resource/apt_repository_spec.rb +0 -18
  468. data/spec/unit/resource/apt_update_spec.rb +0 -18
  469. data/spec/unit/resource/chef_client_cron_spec.rb +119 -0
  470. data/spec/unit/resource/chef_client_scheduled_task_spec.rb +102 -0
  471. data/spec/unit/resource/chef_client_systemd_timer_spec.rb +70 -0
  472. data/spec/unit/resource/chef_vault_secret_spec.rb +40 -0
  473. data/spec/unit/resource/chocolatey_source_spec.rb +2 -1
  474. data/spec/unit/resource/cron_d_spec.rb +6 -48
  475. data/spec/unit/resource/cron_spec.rb +4 -10
  476. data/spec/unit/resource/gem_package_spec.rb +3 -3
  477. data/spec/unit/resource/helpers/cron_validations_spec.rb +77 -0
  478. data/spec/unit/resource/link_spec.rb +0 -4
  479. data/spec/unit/resource/locale_spec.rb +0 -34
  480. data/spec/unit/resource/msu_package_spec.rb +4 -0
  481. data/spec/unit/resource/ohai_spec.rb +56 -2
  482. data/spec/unit/resource/plist_spec.rb +130 -0
  483. data/spec/unit/resource/powershell_script_spec.rb +0 -5
  484. data/spec/unit/resource/{git_spec.rb → scm/git_spec.rb} +50 -2
  485. data/spec/unit/resource/{scm_spec.rb → scm/scm.rb} +1 -52
  486. data/spec/unit/resource/{subversion_spec.rb → scm/subversion_spec.rb} +2 -3
  487. data/spec/unit/resource/service_spec.rb +4 -0
  488. data/spec/unit/resource/user_spec.rb +2 -2
  489. data/spec/unit/resource/user_ulimit_spec.rb +53 -0
  490. data/spec/unit/resource/windows_feature_dism_spec.rb +2 -17
  491. data/spec/unit/resource/windows_feature_powershell_spec.rb +2 -17
  492. data/spec/unit/resource/windows_firewall_rule_spec.rb +88 -41
  493. data/spec/unit/resource/windows_package_spec.rb +14 -0
  494. data/spec/unit/resource/windows_service_spec.rb +9 -0
  495. data/spec/unit/resource_reporter_spec.rb +2 -6
  496. data/spec/unit/resource_spec.rb +10 -3
  497. data/spec/unit/run_lock_spec.rb +1 -1
  498. data/spec/unit/scan_access_control_spec.rb +1 -1
  499. data/spec/unit/search/query_spec.rb +1 -1
  500. data/spec/unit/win32/registry_spec.rb +1 -1
  501. data/tasks/rspec.rb +6 -14
  502. metadata +92 -37
  503. data/lib/chef/dsl/core.rb +0 -52
  504. data/lib/chef/knife/cookbook_site_share.rb +0 -41
  505. data/lib/chef/knife/cookbook_site_unshare.rb +0 -41
  506. data/lib/chef/provider/apt_preference.rb +0 -93
  507. data/lib/chef/provider/apt_repository.rb +0 -358
  508. data/lib/chef/provider/apt_update.rb +0 -79
  509. data/lib/chef/provider/log.rb +0 -43
  510. data/lib/chef/provider/mdadm.rb +0 -85
  511. data/lib/chef/provider/ohai.rb +0 -45
  512. data/lib/chef/resource/git.rb +0 -37
  513. data/spec/unit/provider/ohai_spec.rb +0 -84
@@ -17,6 +17,7 @@ def get_sack():
17
17
  conf = base.conf
18
18
  conf.read()
19
19
  conf.installroot = '/'
20
+ conf.assumeyes = True
20
21
  subst = conf.substitutions
21
22
  subst.update_from_etc(conf.installroot)
22
23
  try:
@@ -25,6 +26,17 @@ def get_sack():
25
26
  except AttributeError:
26
27
  pass
27
28
  base.read_all_repos()
29
+ repos = base.repos
30
+
31
+ if 'repos' in command:
32
+ for repo_pattern in command['repos']:
33
+ if 'enable' in repo_pattern:
34
+ for repo in repos.get_matching(repo_pattern['enable']):
35
+ repo.enable()
36
+ if 'disable' in repo_pattern:
37
+ for repo in repos.get_matching(repo_pattern['disable']):
38
+ repo.disable()
39
+
28
40
  try:
29
41
  base.configure_plugins()
30
42
  except AttributeError:
@@ -40,13 +52,38 @@ def flushcache():
40
52
  pass
41
53
  get_sack().load_system_repo(build_cache=True)
42
54
 
55
+ def version_tuple(versionstr):
56
+ e = '0'
57
+ v = None
58
+ r = None
59
+ colon_index = versionstr.find(':')
60
+ if colon_index > 0:
61
+ e = str(versionstr[:colon_index])
62
+ dash_index = versionstr.find('-')
63
+ if dash_index > 0:
64
+ tmp = versionstr[colon_index + 1:dash_index]
65
+ if tmp != '':
66
+ v = tmp
67
+ arch_index = versionstr.find('.', dash_index)
68
+ if arch_index > 0:
69
+ r = versionstr[dash_index + 1:arch_index]
70
+ else:
71
+ r = versionstr[dash_index + 1:]
72
+ else:
73
+ tmp = versionstr[colon_index + 1:]
74
+ if tmp != '':
75
+ v = tmp
76
+ return (e, v, r)
77
+
43
78
  def versioncompare(versions):
44
79
  sack = get_sack()
45
80
  if (versions[0] is None) or (versions[1] is None):
46
- sys.stdout.write('0\n')
81
+ outpipe.write('0\n')
82
+ outpipe.flush()
47
83
  else:
48
- evr_comparison = sack.evr_cmp(versions[0], versions[1])
49
- sys.stdout.write('{}\n'.format(evr_comparison))
84
+ evr_comparison = dnf.rpm.rpm.labelCompare(version_tuple(versions[0]), version_tuple(versions[1]))
85
+ outpipe.write('{}\n'.format(evr_comparison))
86
+ outpipe.flush()
50
87
 
51
88
  def query(command):
52
89
  sack = get_sack()
@@ -78,37 +115,59 @@ def query(command):
78
115
  pkgs = q.latest(1).run()
79
116
 
80
117
  if not pkgs:
81
- sys.stdout.write('{} nil nil\n'.format(command['provides'].split().pop(0)))
118
+ outpipe.write('{} nil nil\n'.format(command['provides'].split().pop(0)))
119
+ outpipe.flush()
82
120
  else:
83
121
  # make sure we picked the package with the highest version
84
122
  pkgs.sort
85
123
  pkg = pkgs.pop()
86
- sys.stdout.write('{} {}:{}-{} {}\n'.format(pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch))
124
+ outpipe.write('{} {}:{}-{} {}\n'.format(pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch))
125
+ outpipe.flush()
87
126
 
88
127
  # the design of this helper is that it should try to be 'brittle' and fail hard and exit in order
89
128
  # to keep process tables clean. additional error handling should probably be added to the retry loop
90
129
  # on the ruby side.
91
130
  def exit_handler(signal, frame):
131
+ if base is not None:
132
+ base.close()
92
133
  sys.exit(0)
93
134
 
94
- signal.signal(signal.SIGINT, exit_handler)
95
- signal.signal(signal.SIGHUP, exit_handler)
96
- signal.signal(signal.SIGPIPE, exit_handler)
97
-
98
- while 1:
99
- # kill self if we get orphaned (tragic)
100
- ppid = os.getppid()
101
- if ppid == 1:
102
- sys.exit(0)
103
- line = sys.stdin.readline()
104
- command = json.loads(line)
105
- if command['action'] == "whatinstalled":
106
- query(command)
107
- elif command['action'] == "whatavailable":
108
- query(command)
109
- elif command['action'] == "flushcache":
110
- flushcache()
111
- elif command['action'] == "versioncompare":
112
- versioncompare(command['versions'])
113
- else:
114
- raise RuntimeError("bad command")
135
+ def setup_exit_handler():
136
+ signal.signal(signal.SIGINT, exit_handler)
137
+ signal.signal(signal.SIGHUP, exit_handler)
138
+ signal.signal(signal.SIGPIPE, exit_handler)
139
+ signal.signal(signal.SIGQUIT, exit_handler)
140
+
141
+ if len(sys.argv) < 3:
142
+ inpipe = sys.stdin
143
+ outpipe = sys.stdout
144
+ else:
145
+ inpipe = os.fdopen(int(sys.argv[1]), "r")
146
+ outpipe = os.fdopen(int(sys.argv[2]), "w")
147
+
148
+ try:
149
+ while 1:
150
+ # kill self if we get orphaned (tragic)
151
+ ppid = os.getppid()
152
+ if ppid == 1:
153
+ raise RuntimeError("orphaned")
154
+
155
+ setup_exit_handler()
156
+ line = inpipe.readline()
157
+
158
+ try:
159
+ command = json.loads(line)
160
+ except ValueError:
161
+ raise RuntimeError("bad json parse")
162
+
163
+ if command['action'] == "whatinstalled":
164
+ query(command)
165
+ elif command['action'] == "whatavailable":
166
+ query(command)
167
+ elif command['action'] == "versioncompare":
168
+ versioncompare(command['versions'])
169
+ else:
170
+ raise RuntimeError("bad command")
171
+ finally:
172
+ if base is not None:
173
+ base.closeRpmDB()
@@ -18,6 +18,7 @@
18
18
  require_relative "../../../mixin/which"
19
19
  require_relative "../../../mixin/shell_out"
20
20
  require_relative "version"
21
+ require "singleton" unless defined?(Singleton)
21
22
  require "timeout" unless defined?(Timeout)
22
23
 
23
24
  class Chef
@@ -32,6 +33,8 @@ class Chef
32
33
  attr_accessor :stdin
33
34
  attr_accessor :stdout
34
35
  attr_accessor :stderr
36
+ attr_accessor :inpipe
37
+ attr_accessor :outpipe
35
38
  attr_accessor :wait_thr
36
39
 
37
40
  DNF_HELPER = ::File.expand_path(::File.join(::File.dirname(__FILE__), "dnf_helper.py")).freeze
@@ -50,16 +53,28 @@ class Chef
50
53
 
51
54
  def start
52
55
  ENV["PYTHONUNBUFFERED"] = "1"
53
- @stdin, @stdout, @stderr, @wait_thr = Open3.popen3(dnf_command)
56
+ @inpipe, inpipe_write = IO.pipe
57
+ outpipe_read, @outpipe = IO.pipe
58
+ @stdin, @stdout, @stderr, @wait_thr = Open3.popen3("#{dnf_command} #{outpipe_read.fileno} #{inpipe_write.fileno}", outpipe_read.fileno => outpipe_read, inpipe_write.fileno => inpipe_write, close_others: false)
59
+ outpipe_read.close
60
+ inpipe_write.close
54
61
  end
55
62
 
56
63
  def reap
57
64
  unless wait_thr.nil?
58
- Process.kill("KILL", wait_thr.pid) rescue nil
65
+ Process.kill("INT", wait_thr.pid) rescue nil
66
+ begin
67
+ Timeout.timeout(3) do
68
+ wait_thr.value # this calls waitpid()
69
+ end
70
+ rescue Timeout::Error
71
+ Process.kill("KILL", wait_thr.pid) rescue nil
72
+ end
59
73
  stdin.close unless stdin.nil?
60
74
  stdout.close unless stdout.nil?
61
75
  stderr.close unless stderr.nil?
62
- wait_thr.value # this calls waitpit()
76
+ inpipe.close unless inpipe.nil?
77
+ outpipe.close unless outpipe.nil?
63
78
  end
64
79
  end
65
80
 
@@ -68,26 +83,39 @@ class Chef
68
83
  end
69
84
 
70
85
  def compare_versions(version1, version2)
71
- with_helper do
72
- json = build_version_query("versioncompare", [version1, version2])
73
- Chef::Log.trace "sending '#{json}' to python helper"
74
- stdin.syswrite json + "\n"
75
- stdout.sysread(4096).chomp.to_i
86
+ query("versioncompare", { "versions" => [version1, version2] }).to_i
87
+ end
88
+
89
+ def options_params(options)
90
+ options.each_with_object({}) do |opt, h|
91
+ if opt =~ /--enablerepo=(.+)/
92
+ $1.split(",").each do |repo|
93
+ h["repos"] ||= []
94
+ h["repos"].push( { "enable" => repo } )
95
+ end
96
+ end
97
+ if opt =~ /--disablerepo=(.+)/
98
+ $1.split(",").each do |repo|
99
+ h["repos"] ||= []
100
+ h["repos"].push( { "disable" => repo } )
101
+ end
102
+ end
76
103
  end
77
104
  end
78
105
 
79
106
  # @return Array<Version>
80
- def query(action, provides, version = nil, arch = nil)
81
- with_helper do
82
- json = build_query(action, provides, version, arch)
83
- Chef::Log.trace "sending '#{json}' to python helper"
84
- stdin.syswrite json + "\n"
85
- output = stdout.sysread(4096).chomp
86
- Chef::Log.trace "got '#{output}' from python helper"
87
- version = parse_response(output)
88
- Chef::Log.trace "parsed #{version} from python helper"
89
- version
90
- end
107
+ # NB: "options" here is the dnf_package options hash and is deliberately not **opts
108
+ def package_query(action, provides, version: nil, arch: nil, options: {})
109
+ parameters = { "provides" => provides, "version" => version, "arch" => arch }
110
+ repo_opts = options_params(options || {})
111
+ parameters.merge!(repo_opts)
112
+ # XXX: for now we restart before and after every query with an enablerepo/disablerepo to clean the helpers internal state
113
+ restart unless repo_opts.empty?
114
+ query_output = query(action, parameters)
115
+ version = parse_response(query_output.lines.last)
116
+ Chef::Log.trace "parsed #{version} from python helper"
117
+ restart unless repo_opts.empty?
118
+ version
91
119
  end
92
120
 
93
121
  def restart
@@ -116,17 +144,28 @@ class Chef
116
144
  hash["version"] = version
117
145
  end
118
146
 
119
- def build_query(action, provides, version, arch)
120
- hash = { "action" => action }
121
- hash["provides"] = provides
122
- add_version(hash, version) unless version.nil?
123
- hash["arch" ] = arch unless arch.nil?
124
- FFI_Yajl::Encoder.encode(hash)
147
+ def query(action, parameters)
148
+ with_helper do
149
+ json = build_query(action, parameters)
150
+ Chef::Log.trace "sending '#{json}' to python helper"
151
+ outpipe.syswrite json + "\n"
152
+ output = inpipe.sysread(4096).chomp
153
+ Chef::Log.trace "got '#{output}' from python helper"
154
+ return output
155
+ end
125
156
  end
126
157
 
127
- def build_version_query(action, versions)
158
+ def build_query(action, parameters)
128
159
  hash = { "action" => action }
129
- hash["versions"] = versions
160
+ parameters.each do |param_name, param_value|
161
+ hash[param_name] = param_value unless param_value.nil?
162
+ end
163
+
164
+ # Special handling for certain action / param combos
165
+ if %i{whatinstalled whatavailable}.include?(action)
166
+ add_version(hash, parameters["version"]) unless parameters["version"].nil?
167
+ end
168
+
130
169
  FFI_Yajl::Encoder.encode(hash)
131
170
  end
132
171
 
@@ -135,12 +174,16 @@ class Chef
135
174
  array.each_slice(3).map { |x| Version.new(*x) }.first
136
175
  end
137
176
 
138
- def drain_stderr
177
+ def drain_fds
139
178
  output = ""
140
- output += stderr.sysread(4096).chomp until IO.select([stderr], nil, nil, 0).nil?
179
+ fds, = IO.select([stderr, stdout, inpipe], nil, nil, 0)
180
+ unless fds.nil?
181
+ fds.each do |fd|
182
+ output += fd.sysread(4096) rescue ""
183
+ end
184
+ end
141
185
  output
142
- rescue
143
- # we must rescue EOFError, and we don't much care about errors on stderr anyway
186
+ rescue => e
144
187
  output
145
188
  end
146
189
 
@@ -151,23 +194,23 @@ class Chef
151
194
  check
152
195
  ret = yield
153
196
  end
154
- output = drain_stderr
197
+ output = drain_fds
155
198
  unless output.empty?
156
- Chef::Log.trace "discarding output on stderr from python helper: #{output}"
199
+ Chef::Log.trace "discarding output on stderr/stdout from python helper: #{output}"
157
200
  end
158
201
  ret
159
202
  rescue EOFError, Errno::EPIPE, Timeout::Error, Errno::ESRCH => e
160
- output = drain_stderr
203
+ output = drain_fds
161
204
  if ( max_retries -= 1 ) > 0
162
205
  unless output.empty?
163
- Chef::Log.trace "discarding output on stderr from python helper: #{output}"
206
+ Chef::Log.trace "discarding output on stderr/stdout from python helper: #{output}"
164
207
  end
165
208
  restart
166
209
  retry
167
210
  else
168
211
  raise e if output.empty?
169
212
 
170
- raise "dnf-helper.py had stderr output:\n\n#{output}"
213
+ raise "dnf-helper.py had stderr/stdout output:\n\n#{output}"
171
214
  end
172
215
  end
173
216
  end
@@ -33,13 +33,17 @@ class Chef
33
33
  end
34
34
 
35
35
  def to_s
36
- "#{name}-#{version}.#{arch}"
36
+ "#{name}-#{version}.#{arch}" unless version.nil?
37
37
  end
38
38
 
39
39
  def version_with_arch
40
40
  "#{version}.#{arch}" unless version.nil?
41
41
  end
42
42
 
43
+ def name_with_arch
44
+ "#{name}.#{arch}" unless name.nil?
45
+ end
46
+
43
47
  def matches_name_and_arch?(other)
44
48
  other.version == version && other.arch == arch
45
49
  end
@@ -149,7 +149,7 @@ class Chef
149
149
  resolved_source_array.all? { |s| s && ::File.exist?(s) }
150
150
  end
151
151
 
152
- # Helper to return all the nanes of the missing sources for error messages.
152
+ # Helper to return all the names of the missing sources for error messages.
153
153
  #
154
154
  # @return [Array<String>] Array of missing sources
155
155
  def missing_sources
@@ -58,7 +58,8 @@ class Chef
58
58
 
59
59
  def makefile_variable_value(variable, dir = nil)
60
60
  options = dir ? { cwd: dir } : {}
61
- make_v = shell_out!("make", "-V", variable, options.merge!(env: nil, returns: [0, 1]))
61
+ options.merge!(env: nil, returns: [0, 1])
62
+ make_v = shell_out!("make", "-V", variable, **options)
62
63
  make_v.exitstatus == 0 ? make_v.stdout.strip.split($OUTPUT_RECORD_SEPARATOR).first : nil # $\ is the line separator, i.e. newline.
63
64
  end
64
65
  end
@@ -24,56 +24,60 @@ class Chef
24
24
  class Provider
25
25
  class Package
26
26
  class Homebrew < Chef::Provider::Package
27
+ allow_nils
28
+ use_multipackage_api
27
29
 
28
- provides :package, os: "darwin", override: true
30
+ provides :package, os: "darwin"
29
31
  provides :homebrew_package
30
32
 
31
33
  include Chef::Mixin::HomebrewUser
32
34
 
33
35
  def load_current_resource
34
- self.current_resource = Chef::Resource::HomebrewPackage.new(new_resource.name)
36
+ @current_resource = Chef::Resource::HomebrewPackage.new(new_resource.name)
35
37
  current_resource.package_name(new_resource.package_name)
36
- current_resource.version(current_installed_version)
37
- logger.trace("#{new_resource} current version is #{current_resource.version}") if current_resource.version
38
-
39
- @candidate_version = candidate_version
40
-
41
- logger.trace("#{new_resource} candidate version is #{@candidate_version}") if @candidate_version
38
+ current_resource.version(get_current_versions)
39
+ logger.trace("#{new_resource} current package version(s): #{current_resource.version}") if current_resource.version
42
40
 
43
41
  current_resource
44
42
  end
45
43
 
46
- def install_package(name, version)
47
- unless current_resource.version == version
48
- brew("install", options, name)
44
+ def candidate_version
45
+ package_name_array.map do |package_name|
46
+ available_version(package_name)
49
47
  end
50
48
  end
51
49
 
52
- def upgrade_package(name, version)
53
- current_version = current_resource.version
54
-
55
- if current_version.nil? || current_version.empty?
56
- install_package(name, version)
57
- elsif current_version != version
58
- brew("upgrade", options, name)
50
+ def get_current_versions
51
+ package_name_array.map do |package_name|
52
+ installed_version(package_name)
59
53
  end
60
54
  end
61
55
 
62
- def remove_package(name, version)
63
- if current_resource.version
64
- brew("uninstall", options, name)
65
- end
56
+ def install_package(names, versions)
57
+ brew_cmd_output("install", options, names.compact)
66
58
  end
67
59
 
68
- # Homebrew doesn't really have a notion of purging, do a "force remove"
69
- def purge_package(name, version)
70
- if current_resource.version
71
- brew("uninstall", "--force", options, name)
72
- end
60
+ # upgrades are a bit harder in homebrew than other package formats. If you try to
61
+ # brew upgrade a package that isn't installed it will fail so if a user specifies
62
+ # the action of upgrade we need to figure out which packages need to be installed
63
+ # and which packages can be upgrades. We do this by checking if brew_info has an entry
64
+ # via the installed_version helper.
65
+ def upgrade_package(names, versions)
66
+ # @todo when we no longer support Ruby 2.6 this can be simplified to be a .filter_map
67
+ upgrade_pkgs = names.select { |x| x if installed_version(x) }.compact
68
+ install_pkgs = names.select { |x| x unless installed_version(x) }.compact
69
+
70
+ brew_cmd_output("upgrade", options, upgrade_pkgs) unless upgrade_pkgs.empty?
71
+ brew_cmd_output("install", options, install_pkgs) unless install_pkgs.empty?
73
72
  end
74
73
 
75
- def brew(*args)
76
- get_response_from_command("brew", *args)
74
+ def remove_package(names, versions)
75
+ brew_cmd_output("uninstall", options, names.compact)
76
+ end
77
+
78
+ # Homebrew doesn't really have a notion of purging, do a "force remove"
79
+ def purge_package(names, versions)
80
+ brew_cmd_output("uninstall", "--force", options, names.compact)
77
81
  end
78
82
 
79
83
  # We implement a querying method that returns the JSON-as-Hash
@@ -83,9 +87,50 @@ class Chef
83
87
  # information, but that is not any more robust than using the
84
88
  # command-line interface that returns the same thing.
85
89
  #
86
- # https://github.com/Homebrew/homebrew/wiki/Querying-Brew
90
+ # https://docs.brew.sh/Querying-Brew
91
+ #
92
+ # @returns [Hash] a hash of package information where the key is the package name
87
93
  def brew_info
88
- @brew_info ||= Chef::JSONCompat.from_json(brew("info", "--json=v1", new_resource.package_name)).first
94
+ @brew_info ||= begin
95
+ command_array = ["info", "--json=v1"].concat package_name_array
96
+ # convert the array of hashes into a hash where the key is the package name
97
+
98
+ cmd_output = brew_cmd_output(command_array, allow_failure: true)
99
+
100
+ if cmd_output.empty?
101
+ # we had some kind of failure so we need to iterate through each package to find them
102
+ package_name_array.each_with_object({}) do |package_name, hsh|
103
+ cmd_output = brew_cmd_output("info", "--json=v1", package_name, allow_failure: true)
104
+ if cmd_output.empty?
105
+ hsh[package_name] = {}
106
+ else
107
+ json = Chef::JSONCompat.from_json(cmd_output).first
108
+ hsh[json["name"]] = json
109
+ end
110
+ end
111
+ else
112
+ Hash[Chef::JSONCompat.from_json(cmd_output).collect { |pkg| [pkg["name"], pkg] }]
113
+ end
114
+ end
115
+ end
116
+
117
+ #
118
+ # Return the package information given a package name or package alias
119
+ #
120
+ # @param [String] name_or_alias The name of the package or its alias
121
+ #
122
+ # @return [Hash] Package information
123
+ #
124
+ def package_info(package_name)
125
+ # return the package hash if it's in the brew info hash
126
+ return brew_info[package_name] if brew_info[package_name]
127
+
128
+ # check each item in the hash to see if we were passed an alias
129
+ brew_info.each_value do |p|
130
+ return p if p["aliases"].include?(package_name)
131
+ end
132
+
133
+ {}
89
134
  end
90
135
 
91
136
  # Some packages (formula) are "keg only" and aren't linked,
@@ -94,15 +139,20 @@ class Chef
94
139
  # "current" (as in latest). Otherwise, we will use the version
95
140
  # that brew thinks is linked as the current version.
96
141
  #
97
- def current_installed_version
98
- if brew_info["keg_only"]
99
- if brew_info["installed"].empty?
142
+ # @param [String] package name
143
+ #
144
+ # @returns [String] package version
145
+ def installed_version(i)
146
+ p_data = package_info(i)
147
+
148
+ if p_data["keg_only"]
149
+ if p_data["installed"].empty?
100
150
  nil
101
151
  else
102
- brew_info["installed"].last["version"]
152
+ p_data["installed"].last["version"]
103
153
  end
104
154
  else
105
- brew_info["linked_keg"]
155
+ p_data["linked_keg"]
106
156
  end
107
157
  end
108
158
 
@@ -115,19 +165,33 @@ class Chef
115
165
  # forward project.
116
166
  #
117
167
  # https://github.com/Homebrew/homebrew/wiki/Acceptable-Formulae#stable-versions
118
- def candidate_version
119
- brew_info["versions"]["stable"]
120
- end
168
+ #
169
+ # @param [String] package name
170
+ #
171
+ # @returns [String] package version
172
+ def available_version(i)
173
+ p_data = package_info(i)
121
174
 
122
- private
175
+ # nothing is available
176
+ return nil if p_data.empty?
123
177
 
124
- def get_response_from_command(*command)
178
+ p_data["versions"]["stable"]
179
+ end
180
+
181
+ def brew_cmd_output(*command, **options)
125
182
  homebrew_uid = find_homebrew_uid(new_resource.respond_to?(:homebrew_user) && new_resource.homebrew_user)
126
183
  homebrew_user = Etc.getpwuid(homebrew_uid)
127
184
 
128
- logger.trace "Executing '#{command.join(" ")}' as user '#{homebrew_user.name}'"
185
+ logger.trace "Executing 'brew #{command.join(" ")}' as user '#{homebrew_user.name}'"
186
+
187
+ # allow the calling method to decide if the cmd should raise or not
188
+ # brew_info uses this when querying out available package info since a bad
189
+ # package name will raise and we want to surface a nil available package so that
190
+ # the package provider can magically handle that
191
+ shell_out_cmd = options[:allow_failure] ? :shell_out : :shell_out!
192
+
129
193
  # FIXME: this 1800 second default timeout should be deprecated
130
- output = shell_out!(*command, timeout: 1800, user: homebrew_uid, environment: { "HOME" => homebrew_user.dir, "RUBYOPT" => nil, "TMPDIR" => nil })
194
+ output = send(shell_out_cmd, "brew", *command, timeout: 1800, user: homebrew_uid, environment: { "HOME" => homebrew_user.dir, "RUBYOPT" => nil, "TMPDIR" => nil })
131
195
  output.stdout.chomp
132
196
  end
133
197