chef 12.4.0.rc.0-universal-mingw32 → 12.4.0.rc.2-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 (298) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +12 -1
  3. data/lib/chef/api_client.rb +130 -26
  4. data/lib/chef/application.rb +0 -1
  5. data/lib/chef/application/client.rb +8 -19
  6. data/lib/chef/audit/audit_reporter.rb +12 -7
  7. data/lib/chef/audit/logger.rb +36 -0
  8. data/lib/chef/audit/runner.rb +4 -2
  9. data/lib/chef/chef_class.rb +62 -11
  10. data/lib/chef/client.rb +587 -207
  11. data/lib/chef/config.rb +0 -1
  12. data/lib/chef/dsl/recipe.rb +45 -56
  13. data/lib/chef/dsl/resources.rb +3 -2
  14. data/lib/chef/event_dispatch/base.rb +7 -2
  15. data/lib/chef/exceptions.rb +4 -1
  16. data/lib/chef/file_content_management/deploy/mv_windows.rb +16 -6
  17. data/lib/chef/formatters/doc.rb +15 -7
  18. data/lib/chef/formatters/error_inspectors/api_error_formatting.rb +10 -7
  19. data/lib/chef/guard_interpreter/default_guard_interpreter.rb +2 -0
  20. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +4 -1
  21. data/lib/chef/http/authenticator.rb +7 -2
  22. data/lib/chef/knife.rb +16 -4
  23. data/lib/chef/knife/client_create.rb +55 -31
  24. data/lib/chef/knife/core/generic_presenter.rb +1 -1
  25. data/lib/chef/knife/core/subcommand_loader.rb +1 -1
  26. data/lib/chef/knife/osc_user_create.rb +97 -0
  27. data/lib/chef/knife/osc_user_delete.rb +51 -0
  28. data/lib/chef/knife/osc_user_edit.rb +58 -0
  29. data/lib/chef/knife/osc_user_list.rb +47 -0
  30. data/lib/chef/knife/osc_user_reregister.rb +64 -0
  31. data/lib/chef/knife/osc_user_show.rb +54 -0
  32. data/lib/chef/knife/user_create.rb +95 -36
  33. data/lib/chef/knife/user_delete.rb +52 -2
  34. data/lib/chef/knife/user_edit.rb +37 -7
  35. data/lib/chef/knife/user_list.rb +3 -0
  36. data/lib/chef/knife/user_reregister.rb +39 -8
  37. data/lib/chef/knife/user_show.rb +30 -1
  38. data/lib/chef/mixin/api_version_request_handling.rb +66 -0
  39. data/lib/chef/mixin/convert_to_class_name.rb +10 -4
  40. data/lib/chef/mixin/deprecation.rb +24 -0
  41. data/lib/chef/mixin/powershell_out.rb +98 -0
  42. data/lib/chef/mixin/provides.rb +5 -18
  43. data/lib/chef/mixin/uris.rb +11 -0
  44. data/lib/chef/mixin/windows_architecture_helper.rb +5 -2
  45. data/lib/chef/mixin/windows_env_helper.rb +11 -2
  46. data/lib/chef/node_map.rb +130 -75
  47. data/lib/chef/osc_user.rb +194 -0
  48. data/lib/chef/platform/provider_mapping.rb +2 -269
  49. data/lib/chef/platform/provider_priority_map.rb +6 -69
  50. data/lib/chef/platform/query_helpers.rb +5 -0
  51. data/lib/chef/platform/resource_priority_map.rb +12 -15
  52. data/lib/chef/policy_builder/policyfile.rb +1 -0
  53. data/lib/chef/provider.rb +19 -0
  54. data/lib/chef/provider/directory.rb +3 -0
  55. data/lib/chef/provider/dsc_resource.rb +8 -1
  56. data/lib/chef/provider/file.rb +1 -0
  57. data/lib/chef/provider/group/aix.rb +1 -0
  58. data/lib/chef/provider/group/dscl.rb +1 -1
  59. data/lib/chef/provider/group/gpasswd.rb +1 -0
  60. data/lib/chef/provider/group/groupmod.rb +1 -1
  61. data/lib/chef/provider/group/pw.rb +1 -0
  62. data/lib/chef/provider/group/suse.rb +2 -0
  63. data/lib/chef/provider/group/usermod.rb +2 -1
  64. data/lib/chef/provider/group/windows.rb +1 -1
  65. data/lib/chef/provider/ifconfig.rb +2 -0
  66. data/lib/chef/provider/ifconfig/aix.rb +1 -0
  67. data/lib/chef/provider/ifconfig/debian.rb +2 -0
  68. data/lib/chef/provider/ifconfig/redhat.rb +1 -0
  69. data/lib/chef/provider/lwrp_base.rb +4 -0
  70. data/lib/chef/provider/mount.rb +0 -1
  71. data/lib/chef/provider/mount/aix.rb +1 -0
  72. data/lib/chef/provider/mount/mount.rb +2 -0
  73. data/lib/chef/provider/mount/solaris.rb +2 -0
  74. data/lib/chef/provider/package.rb +55 -0
  75. data/lib/chef/provider/package/aix.rb +7 -7
  76. data/lib/chef/provider/package/apt.rb +3 -3
  77. data/lib/chef/provider/package/dpkg.rb +4 -4
  78. data/lib/chef/provider/package/easy_install.rb +5 -5
  79. data/lib/chef/provider/package/freebsd/base.rb +2 -2
  80. data/lib/chef/provider/package/freebsd/pkg.rb +6 -6
  81. data/lib/chef/provider/package/freebsd/pkgng.rb +5 -5
  82. data/lib/chef/provider/package/freebsd/port.rb +4 -4
  83. data/lib/chef/provider/package/homebrew.rb +2 -2
  84. data/lib/chef/provider/package/ips.rb +4 -4
  85. data/lib/chef/provider/package/macports.rb +5 -6
  86. data/lib/chef/provider/package/openbsd.rb +4 -5
  87. data/lib/chef/provider/package/pacman.rb +4 -4
  88. data/lib/chef/provider/package/portage.rb +2 -0
  89. data/lib/chef/provider/package/rpm.rb +7 -8
  90. data/lib/chef/provider/package/rubygems.rb +5 -12
  91. data/lib/chef/provider/package/smartos.rb +4 -4
  92. data/lib/chef/provider/package/solaris.rb +7 -7
  93. data/lib/chef/provider/package/windows/msi.rb +1 -1
  94. data/lib/chef/provider/package/yum.rb +4 -6
  95. data/lib/chef/provider/package/zypper.rb +16 -14
  96. data/lib/chef/provider/powershell_script.rb +129 -47
  97. data/lib/chef/provider/remote_file/content.rb +4 -1
  98. data/lib/chef/provider/remote_file/local_file.rb +10 -4
  99. data/lib/chef/provider/service.rb +44 -0
  100. data/lib/chef/provider/service/freebsd.rb +1 -1
  101. data/lib/chef/provider/service/init.rb +1 -0
  102. data/lib/chef/provider/service/macosx.rb +1 -1
  103. data/lib/chef/provider/service/windows.rb +0 -1
  104. data/lib/chef/provider/user.rb +1 -1
  105. data/lib/chef/provider/user/aix.rb +3 -2
  106. data/lib/chef/provider/user/pw.rb +1 -0
  107. data/lib/chef/provider/user/solaris.rb +2 -0
  108. data/lib/chef/provider/user/useradd.rb +1 -0
  109. data/lib/chef/provider_resolver.rb +87 -134
  110. data/lib/chef/resource.rb +274 -68
  111. data/lib/chef/resource/apt_package.rb +0 -2
  112. data/lib/chef/resource/bash.rb +0 -2
  113. data/lib/chef/resource/batch.rb +1 -1
  114. data/lib/chef/resource/bff_package.rb +0 -7
  115. data/lib/chef/resource/breakpoint.rb +3 -6
  116. data/lib/chef/resource/chef_gem.rb +0 -3
  117. data/lib/chef/resource/cookbook_file.rb +1 -3
  118. data/lib/chef/resource/cron.rb +2 -4
  119. data/lib/chef/resource/csh.rb +0 -2
  120. data/lib/chef/resource/deploy.rb +9 -6
  121. data/lib/chef/resource/deploy_revision.rb +0 -14
  122. data/lib/chef/resource/directory.rb +2 -4
  123. data/lib/chef/resource/dpkg_package.rb +0 -5
  124. data/lib/chef/resource/dsc_resource.rb +2 -3
  125. data/lib/chef/resource/dsc_script.rb +2 -3
  126. data/lib/chef/resource/easy_install_package.rb +0 -7
  127. data/lib/chef/resource/env.rb +3 -3
  128. data/lib/chef/resource/erl_call.rb +2 -5
  129. data/lib/chef/resource/execute.rb +2 -4
  130. data/lib/chef/resource/file.rb +2 -4
  131. data/lib/chef/resource/freebsd_package.rb +0 -5
  132. data/lib/chef/resource/gem_package.rb +0 -3
  133. data/lib/chef/resource/git.rb +0 -3
  134. data/lib/chef/resource/group.rb +2 -4
  135. data/lib/chef/resource/homebrew_package.rb +0 -2
  136. data/lib/chef/resource/http_request.rb +3 -4
  137. data/lib/chef/resource/ifconfig.rb +3 -4
  138. data/lib/chef/resource/ips_package.rb +2 -2
  139. data/lib/chef/resource/link.rb +3 -5
  140. data/lib/chef/resource/log.rb +2 -4
  141. data/lib/chef/resource/lwrp_base.rb +10 -61
  142. data/lib/chef/resource/macosx_service.rb +1 -2
  143. data/lib/chef/resource/macports_package.rb +0 -7
  144. data/lib/chef/resource/mdadm.rb +2 -5
  145. data/lib/chef/resource/mount.rb +2 -4
  146. data/lib/chef/resource/ohai.rb +2 -4
  147. data/lib/chef/resource/openbsd_package.rb +0 -6
  148. data/lib/chef/resource/package.rb +9 -6
  149. data/lib/chef/resource/pacman_package.rb +0 -7
  150. data/lib/chef/resource/paludis_package.rb +2 -3
  151. data/lib/chef/resource/perl.rb +0 -3
  152. data/lib/chef/resource/portage_package.rb +0 -3
  153. data/lib/chef/resource/powershell_script.rb +1 -2
  154. data/lib/chef/resource/python.rb +0 -3
  155. data/lib/chef/resource/reboot.rb +1 -3
  156. data/lib/chef/resource/registry_key.rb +3 -5
  157. data/lib/chef/resource/remote_directory.rb +3 -5
  158. data/lib/chef/resource/remote_file.rb +4 -5
  159. data/lib/chef/resource/route.rb +3 -5
  160. data/lib/chef/resource/rpm_package.rb +0 -2
  161. data/lib/chef/resource/ruby.rb +0 -4
  162. data/lib/chef/resource/ruby_block.rb +2 -4
  163. data/lib/chef/resource/scm.rb +3 -5
  164. data/lib/chef/resource/script.rb +0 -3
  165. data/lib/chef/resource/service.rb +3 -5
  166. data/lib/chef/resource/smartos_package.rb +0 -9
  167. data/lib/chef/resource/solaris_package.rb +0 -10
  168. data/lib/chef/resource/subversion.rb +1 -3
  169. data/lib/chef/resource/template.rb +0 -4
  170. data/lib/chef/resource/timestamped_deploy.rb +0 -4
  171. data/lib/chef/resource/user.rb +2 -5
  172. data/lib/chef/resource/whyrun_safe_ruby_block.rb +0 -7
  173. data/lib/chef/resource/windows_package.rb +3 -3
  174. data/lib/chef/resource/windows_script.rb +2 -2
  175. data/lib/chef/resource/windows_service.rb +3 -3
  176. data/lib/chef/resource/yum_package.rb +0 -3
  177. data/lib/chef/resource/zypper_package.rb +27 -0
  178. data/lib/chef/resource_builder.rb +7 -0
  179. data/lib/chef/resource_reporter.rb +1 -1
  180. data/lib/chef/resource_resolver.rb +108 -62
  181. data/lib/chef/resources.rb +1 -0
  182. data/lib/chef/rest.rb +1 -0
  183. data/lib/chef/server_api.rb +2 -0
  184. data/lib/chef/user.rb +193 -42
  185. data/lib/chef/util/backup.rb +9 -1
  186. data/lib/chef/util/path_helper.rb +0 -1
  187. data/lib/chef/version.rb +1 -1
  188. data/spec/functional/audit/runner_spec.rb +22 -42
  189. data/spec/functional/mixin/powershell_out_spec.rb +43 -0
  190. data/spec/functional/resource/execute_spec.rb +9 -2
  191. data/spec/functional/resource/file_spec.rb +25 -0
  192. data/spec/functional/resource/group_spec.rb +5 -0
  193. data/spec/functional/resource/link_spec.rb +5 -11
  194. data/spec/functional/resource/powershell_spec.rb +40 -5
  195. data/spec/functional/resource/user/useradd_spec.rb +10 -18
  196. data/spec/integration/recipes/lwrp_spec.rb +57 -0
  197. data/spec/integration/recipes/provider_choice.rb +2 -7
  198. data/spec/integration/recipes/recipe_dsl_spec.rb +517 -19
  199. data/spec/spec_helper.rb +1 -1
  200. data/spec/support/lib/chef/provider/openldap_includer.rb +29 -0
  201. data/spec/support/lib/chef/resource/cat.rb +0 -2
  202. data/spec/support/lib/chef/resource/one_two_three_four.rb +0 -6
  203. data/spec/support/lib/chef/resource/openldap_includer.rb +27 -0
  204. data/spec/support/lib/chef/resource/with_state.rb +0 -9
  205. data/spec/support/lib/chef/resource/zen_follower.rb +0 -6
  206. data/spec/support/lib/chef/resource/zen_master.rb +1 -6
  207. data/spec/support/shared/context/client.rb +277 -0
  208. data/spec/support/shared/examples/client.rb +53 -0
  209. data/spec/support/shared/functional/file_resource.rb +0 -4
  210. data/spec/support/shared/functional/securable_resource.rb +0 -24
  211. data/spec/support/shared/functional/securable_resource_with_reporting.rb +4 -4
  212. data/spec/support/shared/functional/windows_script.rb +1 -1
  213. data/spec/support/shared/unit/api_versioning.rb +77 -0
  214. data/spec/support/shared/unit/knife_shared.rb +40 -0
  215. data/spec/support/shared/unit/user_and_client_shared.rb +115 -0
  216. data/spec/unit/api_client_spec.rb +189 -14
  217. data/spec/unit/application/client_spec.rb +0 -5
  218. data/spec/unit/audit/audit_reporter_spec.rb +58 -14
  219. data/spec/unit/audit/logger_spec.rb +42 -0
  220. data/spec/unit/audit/runner_spec.rb +2 -2
  221. data/spec/unit/chef_fs/file_pattern_spec.rb +3 -15
  222. data/spec/unit/client_spec.rb +58 -374
  223. data/spec/unit/cookbook_spec.rb +0 -9
  224. data/spec/unit/cookbook_version_spec.rb +0 -20
  225. data/spec/unit/deprecation_spec.rb +55 -0
  226. data/spec/unit/dsl/resources_spec.rb +85 -0
  227. data/spec/unit/exceptions_spec.rb +2 -2
  228. data/spec/unit/file_content_management/deploy/mv_windows_spec.rb +60 -0
  229. data/spec/unit/formatters/doc_spec.rb +46 -0
  230. data/spec/unit/formatters/error_inspectors/api_error_formatting_spec.rb +12 -10
  231. data/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb +8 -0
  232. data/spec/unit/http/authenticator_spec.rb +11 -2
  233. data/spec/unit/knife/client_create_spec.rb +122 -51
  234. data/spec/unit/knife/core/subcommand_loader_spec.rb +19 -3
  235. data/spec/unit/knife/core/ui_spec.rb +14 -0
  236. data/spec/unit/knife/osc_user_create_spec.rb +93 -0
  237. data/spec/unit/knife/osc_user_delete_spec.rb +44 -0
  238. data/spec/unit/knife/osc_user_edit_spec.rb +52 -0
  239. data/spec/unit/knife/osc_user_list_spec.rb +37 -0
  240. data/spec/unit/knife/osc_user_reregister_spec.rb +58 -0
  241. data/spec/unit/knife/osc_user_show_spec.rb +46 -0
  242. data/spec/unit/knife/user_create_spec.rb +177 -51
  243. data/spec/unit/knife/user_delete_spec.rb +34 -8
  244. data/spec/unit/knife/user_edit_spec.rb +31 -12
  245. data/spec/unit/knife/user_list_spec.rb +7 -3
  246. data/spec/unit/knife/user_reregister_spec.rb +38 -17
  247. data/spec/unit/knife/user_show_spec.rb +35 -11
  248. data/spec/unit/knife_spec.rb +10 -4
  249. data/spec/unit/lwrp_spec.rb +228 -54
  250. data/spec/unit/mixin/api_version_request_handling_spec.rb +127 -0
  251. data/spec/unit/mixin/command_spec.rb +1 -2
  252. data/spec/unit/mixin/powershell_out_spec.rb +70 -0
  253. data/spec/unit/mixin/uris_spec.rb +23 -11
  254. data/spec/unit/node_map_spec.rb +4 -1
  255. data/spec/unit/osc_user_spec.rb +276 -0
  256. data/spec/unit/platform_spec.rb +0 -60
  257. data/spec/unit/provider/deploy_spec.rb +1 -1
  258. data/spec/unit/provider/directory_spec.rb +199 -135
  259. data/spec/unit/provider/ifconfig/debian_spec.rb +0 -10
  260. data/spec/unit/provider/package/aix_spec.rb +16 -16
  261. data/spec/unit/provider/package/dpkg_spec.rb +2 -2
  262. data/spec/unit/provider/package/freebsd/pkg_spec.rb +13 -13
  263. data/spec/unit/provider/package/freebsd/pkgng_spec.rb +9 -9
  264. data/spec/unit/provider/package/freebsd/port_spec.rb +7 -7
  265. data/spec/unit/provider/package/ips_spec.rb +22 -22
  266. data/spec/unit/provider/package/macports_spec.rb +10 -10
  267. data/spec/unit/provider/package/openbsd_spec.rb +4 -26
  268. data/spec/unit/provider/package/pacman_spec.rb +5 -5
  269. data/spec/unit/provider/package/rpm_spec.rb +14 -14
  270. data/spec/unit/provider/package/rubygems_spec.rb +10 -44
  271. data/spec/unit/provider/package/smartos_spec.rb +4 -4
  272. data/spec/unit/provider/package/solaris_spec.rb +11 -11
  273. data/spec/unit/provider/package/zypper_spec.rb +125 -90
  274. data/spec/unit/provider/package_spec.rb +34 -0
  275. data/spec/unit/provider/powershell_spec.rb +53 -11
  276. data/spec/unit/provider/remote_directory_spec.rb +2 -2
  277. data/spec/unit/provider/remote_file/local_file_spec.rb +25 -6
  278. data/spec/unit/provider/service/freebsd_service_spec.rb +0 -12
  279. data/spec/unit/provider/user_spec.rb +3 -3
  280. data/spec/unit/provider_resolver_spec.rb +463 -327
  281. data/spec/unit/recipe_spec.rb +42 -15
  282. data/spec/unit/resource/breakpoint_spec.rb +1 -1
  283. data/spec/unit/resource/erl_call_spec.rb +1 -1
  284. data/spec/unit/resource/file_spec.rb +1 -1
  285. data/spec/unit/resource/ifconfig_spec.rb +10 -6
  286. data/spec/unit/resource/remote_file_spec.rb +5 -0
  287. data/spec/unit/resource/route_spec.rb +1 -1
  288. data/spec/unit/resource/ruby_block_spec.rb +2 -2
  289. data/spec/unit/resource/template_spec.rb +1 -1
  290. data/spec/unit/resource/timestamped_deploy_spec.rb +1 -2
  291. data/spec/unit/resource/windows_service_spec.rb +1 -1
  292. data/spec/unit/resource_spec.rb +99 -13
  293. data/spec/unit/rest_spec.rb +5 -5
  294. data/spec/unit/run_context_spec.rb +41 -0
  295. data/spec/unit/runner_spec.rb +2 -2
  296. data/spec/unit/user_spec.rb +406 -93
  297. data/tasks/maintainers.rb +69 -0
  298. metadata +37 -4
@@ -16,6 +16,8 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
+ require 'chef/audit/logger'
20
+
19
21
  class Chef
20
22
  class Audit
21
23
  class Runner
@@ -115,8 +117,8 @@ class Chef
115
117
  # the output stream to be changed for a formatter once the formatter has
116
118
  # been added.
117
119
  def set_streams
118
- RSpec.configuration.output_stream = Chef::Config[:log_location]
119
- RSpec.configuration.error_stream = Chef::Config[:log_location]
120
+ RSpec.configuration.output_stream = Chef::Audit::Logger
121
+ RSpec.configuration.error_stream = Chef::Audit::Logger
120
122
  end
121
123
 
122
124
  # Add formatters which we use to
@@ -26,6 +26,9 @@
26
26
  # injected" into this class by other objects and do not reference the class symbols in those files
27
27
  # directly and we do not need to require those files here.
28
28
 
29
+ require 'chef/platform/provider_priority_map'
30
+ require 'chef/platform/resource_priority_map'
31
+
29
32
  class Chef
30
33
  class << self
31
34
 
@@ -33,50 +36,74 @@ class Chef
33
36
  # Public API
34
37
  #
35
38
 
39
+ #
36
40
  # Get the node object
37
41
  #
38
42
  # @return [Chef::Node] node object of the chef-client run
43
+ #
39
44
  attr_reader :node
40
45
 
46
+ #
41
47
  # Get the run context
42
48
  #
43
49
  # @return [Chef::RunContext] run_context of the chef-client run
50
+ #
44
51
  attr_reader :run_context
45
52
 
53
+ #
46
54
  # Get the array of providers associated with a resource_name for the current node
47
55
  #
48
56
  # @param resource_name [Symbol] name of the resource as a symbol
57
+ #
49
58
  # @return [Array<Class>] Priority Array of Provider Classes to use for the resource_name on the node
59
+ #
50
60
  def get_provider_priority_array(resource_name)
51
- @provider_priority_map.get_priority_array(node, resource_name).dup
61
+ result = provider_priority_map.get_priority_array(node, resource_name)
62
+ result = result.dup if result
63
+ result
52
64
  end
53
65
 
66
+ #
54
67
  # Get the array of resources associated with a resource_name for the current node
55
68
  #
56
69
  # @param resource_name [Symbol] name of the resource as a symbol
70
+ #
57
71
  # @return [Array<Class>] Priority Array of Resource Classes to use for the resource_name on the node
72
+ #
58
73
  def get_resource_priority_array(resource_name)
59
- @resource_priority_map.get_priority_array(node, resource_name).dup
74
+ result = resource_priority_map.get_priority_array(node, resource_name)
75
+ result = result.dup if result
76
+ result
60
77
  end
61
78
 
79
+ #
62
80
  # Set the array of providers associated with a resource_name for the current node
63
81
  #
64
82
  # @param resource_name [Symbol] name of the resource as a symbol
65
- # @param priority_array [Array<Class>] Array of Classes to set as the priority for resource_name on the node
83
+ # @param priority_array [Class, Array<Class>] Class or Array of Classes to set as the priority for resource_name on the node
66
84
  # @param filter [Hash] Chef::Nodearray-style filter
85
+ #
67
86
  # @return [Array<Class>] Modified Priority Array of Provider Classes to use for the resource_name on the node
68
- def set_provider_priority_array(resource_name, priority_array, *filter)
69
- @provider_priority_map.set_priority_array(resource_name, priority_array, *filter).dup
87
+ #
88
+ def set_provider_priority_array(resource_name, priority_array, *filter, &block)
89
+ result = provider_priority_map.set_priority_array(resource_name, priority_array, *filter, &block)
90
+ result = result.dup if result
91
+ result
70
92
  end
71
93
 
94
+ #
72
95
  # Get the array of resources associated with a resource_name for the current node
73
96
  #
74
97
  # @param resource_name [Symbol] name of the resource as a symbol
75
- # @param priority_array [Array<Class>] Array of Classes to set as the priority for resource_name on the node
98
+ # @param priority_array [Class, Array<Class>] Class or Array of Classes to set as the priority for resource_name on the node
76
99
  # @param filter [Hash] Chef::Nodearray-style filter
100
+ #
77
101
  # @return [Array<Class>] Modified Priority Array of Resource Classes to use for the resource_name on the node
78
- def set_resource_priority_array(resource_name, priority_array, *filter)
79
- @resource_priority_map.set_priority_array(resource_name, priority_array, *filter).dup
102
+ #
103
+ def set_resource_priority_array(resource_name, priority_array, *filter, &block)
104
+ result = resource_priority_map.set_priority_array(resource_name, priority_array, *filter, &block)
105
+ result = result.dup if result
106
+ result
80
107
  end
81
108
 
82
109
  #
@@ -85,22 +112,27 @@ class Chef
85
112
  # *NOT* for public consumption ]
86
113
  #
87
114
 
115
+ #
88
116
  # Sets the resource_priority_map
89
117
  #
90
- # @api private
91
118
  # @param resource_priority_map [Chef::Platform::ResourcePriorityMap]
119
+ #
120
+ # @api private
92
121
  def set_resource_priority_map(resource_priority_map)
93
122
  @resource_priority_map = resource_priority_map
94
123
  end
95
124
 
125
+ #
96
126
  # Sets the provider_priority_map
97
127
  #
98
- # @api private
99
128
  # @param provider_priority_map [Chef::Platform::providerPriorityMap]
129
+ #
130
+ # @api private
100
131
  def set_provider_priority_map(provider_priority_map)
101
132
  @provider_priority_map = provider_priority_map
102
133
  end
103
134
 
135
+ #
104
136
  # Sets the node object
105
137
  #
106
138
  # @api private
@@ -109,14 +141,17 @@ class Chef
109
141
  @node = node
110
142
  end
111
143
 
144
+ #
112
145
  # Sets the run_context object
113
146
  #
114
- # @api private
115
147
  # @param run_context [Chef::RunContext]
148
+ #
149
+ # @api private
116
150
  def set_run_context(run_context)
117
151
  @run_context = run_context
118
152
  end
119
153
 
154
+ #
120
155
  # Resets the internal state
121
156
  #
122
157
  # @api private
@@ -126,5 +161,21 @@ class Chef
126
161
  @provider_priority_map = nil
127
162
  @resource_priority_map = nil
128
163
  end
164
+
165
+ # @api private
166
+ def provider_priority_map
167
+ @provider_priority_map ||= begin
168
+ # these slurp in the resource+provider world, so be exceedingly lazy about requiring them
169
+ Chef::Platform::ProviderPriorityMap.instance
170
+ end
171
+ end
172
+ # @api private
173
+ def resource_priority_map
174
+ @resource_priority_map ||= begin
175
+ Chef::Platform::ResourcePriorityMap.instance
176
+ end
177
+ end
129
178
  end
179
+
180
+ reset!
130
181
  end
@@ -50,6 +50,7 @@ require 'chef/run_lock'
50
50
  require 'chef/policy_builder'
51
51
  require 'chef/request_id'
52
52
  require 'chef/platform/rebooter'
53
+ require 'chef/mixin/deprecation'
53
54
  require 'ohai'
54
55
  require 'rbconfig'
55
56
 
@@ -60,121 +61,273 @@ class Chef
60
61
  class Client
61
62
  include Chef::Mixin::PathSanity
62
63
 
63
- # IO stream that will be used as 'STDOUT' for formatters. Formatters are
64
- # configured during `initialize`, so this provides a convenience for
65
- # setting alternative IO stream during tests.
66
- STDOUT_FD = STDOUT
67
-
68
- # IO stream that will be used as 'STDERR' for formatters. Formatters are
69
- # configured during `initialize`, so this provides a convenience for
70
- # setting alternative IO stream during tests.
71
- STDERR_FD = STDERR
64
+ extend Chef::Mixin::Deprecation
72
65
 
73
- # Clears all notifications for client run status events.
74
- # Primarily for testing purposes.
75
- def self.clear_notifications
76
- @run_start_notifications = nil
77
- @run_completed_successfully_notifications = nil
78
- @run_failed_notifications = nil
79
- end
80
-
81
- # The list of notifications to be run when the client run starts.
82
- def self.run_start_notifications
83
- @run_start_notifications ||= []
84
- end
85
-
86
- # The list of notifications to be run when the client run completes
87
- # successfully.
88
- def self.run_completed_successfully_notifications
89
- @run_completed_successfully_notifications ||= []
90
- end
91
-
92
- # The list of notifications to be run when the client run fails.
93
- def self.run_failed_notifications
94
- @run_failed_notifications ||= []
95
- end
96
-
97
- # Add a notification for the 'client run started' event. The notification
98
- # is provided as a block. The current Chef::RunStatus object will be passed
99
- # to the notification_block when the event is triggered.
100
- def self.when_run_starts(&notification_block)
101
- run_start_notifications << notification_block
102
- end
103
-
104
- # Add a notification for the 'client run success' event. The notification
105
- # is provided as a block. The current Chef::RunStatus object will be passed
106
- # to the notification_block when the event is triggered.
107
- def self.when_run_completes_successfully(&notification_block)
108
- run_completed_successfully_notifications << notification_block
109
- end
66
+ #
67
+ # The status of the Chef run.
68
+ #
69
+ # @return [Chef::RunStatus]
70
+ #
71
+ attr_reader :run_status
110
72
 
111
- # Add a notification for the 'client run failed' event. The notification
112
- # is provided as a block. The current Chef::RunStatus is passed to the
113
- # notification_block when the event is triggered.
114
- def self.when_run_fails(&notification_block)
115
- run_failed_notifications << notification_block
73
+ #
74
+ # The node represented by this client.
75
+ #
76
+ # @return [Chef::Node]
77
+ #
78
+ def node
79
+ run_status.node
116
80
  end
117
-
118
- # Callback to fire notifications that the Chef run is starting
119
- def run_started
120
- self.class.run_start_notifications.each do |notification|
121
- notification.call(run_status)
122
- end
123
- @events.run_started(run_status)
81
+ def node=(value)
82
+ run_status.node = value
124
83
  end
125
84
 
126
- # Callback to fire notifications that the run completed successfully
127
- def run_completed_successfully
128
- success_handlers = self.class.run_completed_successfully_notifications
129
- success_handlers.each do |notification|
130
- notification.call(run_status)
131
- end
132
- end
85
+ #
86
+ # The ohai system used by this client.
87
+ #
88
+ # @return [Ohai::System]
89
+ #
90
+ attr_reader :ohai
133
91
 
134
- # Callback to fire notifications that the Chef run failed
135
- def run_failed
136
- failure_handlers = self.class.run_failed_notifications
137
- failure_handlers.each do |notification|
138
- notification.call(run_status)
139
- end
140
- end
92
+ #
93
+ # The rest object used to communicate with the Chef server.
94
+ #
95
+ # @return [Chef::REST]
96
+ #
97
+ attr_reader :rest
141
98
 
142
- attr_accessor :node
143
- attr_accessor :ohai
144
- attr_accessor :rest
99
+ #
100
+ # The runner used to converge.
101
+ #
102
+ # @return [Chef::Runner]
103
+ #
145
104
  attr_accessor :runner
146
105
 
106
+ #
107
+ # Extra node attributes that were applied to the node.
108
+ #
109
+ # @return [Hash]
110
+ #
147
111
  attr_reader :json_attribs
148
- attr_reader :run_status
112
+
113
+ #
114
+ # The event dispatcher for the Chef run, including any configured output
115
+ # formatters and event loggers.
116
+ #
117
+ # @return [EventDispatch::Dispatcher]
118
+ #
119
+ # @see Chef::Formatters
120
+ # @see Chef::Config#formatters
121
+ # @see Chef::Config#stdout
122
+ # @see Chef::Config#stderr
123
+ # @see Chef::Config#force_logger
124
+ # @see Chef::Config#force_formatter
125
+ # TODO add stdout, stderr, and default formatters to Chef::Config so the
126
+ # defaults aren't calculated here. Remove force_logger and force_formatter
127
+ # from this code.
128
+ # @see Chef::EventLoggers
129
+ # @see Chef::Config#disable_event_logger
130
+ # @see Chef::Config#event_loggers
131
+ # @see Chef::Config#event_handlers
132
+ #
149
133
  attr_reader :events
150
134
 
135
+ #
151
136
  # Creates a new Chef::Client.
137
+ #
138
+ # @param json_attribs [Hash] Node attributes to layer into the node when it is
139
+ # fetched.
140
+ # @param args [Hash] Options:
141
+ # @option args [Array<RunList::RunListItem>] :override_runlist A runlist to
142
+ # use instead of the node's embedded run list.
143
+ # @option args [Array<String>] :specific_recipes A list of recipe file paths
144
+ # to load after the run list has been loaded.
145
+ #
152
146
  def initialize(json_attribs=nil, args={})
153
147
  @json_attribs = json_attribs || {}
154
- @node = nil
155
- @runner = nil
156
148
  @ohai = Ohai::System.new
157
149
 
158
150
  event_handlers = configure_formatters + configure_event_loggers
159
151
  event_handlers += Array(Chef::Config[:event_handlers])
160
152
 
161
153
  @events = EventDispatch::Dispatcher.new(*event_handlers)
154
+ # TODO it seems like a bad idea to be deletin' other peoples' hashes.
162
155
  @override_runlist = args.delete(:override_runlist)
163
156
  @specific_recipes = args.delete(:specific_recipes)
164
- @run_status = Chef::RunStatus.new(node, events)
157
+ @run_status = Chef::RunStatus.new(nil, events)
165
158
 
166
159
  if new_runlist = args.delete(:runlist)
167
160
  @json_attribs["run_list"] = new_runlist
168
161
  end
162
+ end
169
163
 
170
- # these slurp in the resource+provider world, so be exceedingly lazy about requiring them
171
- require 'chef/platform/provider_priority_map' unless defined? Chef::Platform::ProviderPriorityMap
172
- require 'chef/platform/resource_priority_map' unless defined? Chef::Platform::ResourcePriorityMap
164
+ #
165
+ # Do a full run for this Chef::Client.
166
+ #
167
+ # Locks the run while doing its job.
168
+ #
169
+ # Fires run_start before doing anything and fires run_completed or
170
+ # run_failed when finished. Also notifies client listeners of run_started
171
+ # at the beginning of Compile, and run_completed_successfully or run_failed
172
+ # when all is complete.
173
+ #
174
+ # Phase 1: Setup
175
+ # --------------
176
+ # Gets information about the system and the run we are doing.
177
+ #
178
+ # 1. Run ohai to collect system information.
179
+ # 2. Register / connect to the Chef server (unless in solo mode).
180
+ # 3. Retrieve the node (or create a new one).
181
+ # 4. Merge in json_attribs, Chef::Config.environment, and override_run_list.
182
+ #
183
+ # @see #run_ohai
184
+ # @see #load_node
185
+ # @see #build_node
186
+ # @see Chef::Config#lockfile
187
+ # @see Chef::RunLock#acquire
188
+ #
189
+ # Phase 2: Compile
190
+ # ----------------
191
+ # Decides *what* we plan to converge by compiling recipes.
192
+ #
193
+ # 1. Sync required cookbooks to the local cache.
194
+ # 2. Load libraries from all cookbooks.
195
+ # 3. Load attributes from all cookbooks.
196
+ # 4. Load LWRPs from all cookbooks.
197
+ # 5. Load resource definitions from all cookbooks.
198
+ # 6. Load recipes in the run list.
199
+ # 7. Load recipes from the command line.
200
+ #
201
+ # @see #setup_run_context Syncs and compiles cookbooks.
202
+ # @see Chef::CookbookCompiler#compile
203
+ #
204
+ # Phase 3: Converge
205
+ # -----------------
206
+ # Brings the system up to date.
207
+ #
208
+ # 1. Converge the resources built from recipes in Phase 2.
209
+ # 2. Save the node.
210
+ # 3. Reboot if we were asked to.
211
+ #
212
+ # @see #converge_and_save
213
+ # @see Chef::Runner
214
+ #
215
+ # Phase 4: Audit
216
+ # --------------
217
+ # Runs 'control_group' audits in recipes. This entire section can be enabled or disabled with config.
218
+ #
219
+ # 1. 'control_group' DSL collects audits during Phase 2
220
+ # 2. Audits are run using RSpec
221
+ # 3. Errors are collected and reported using the formatters
222
+ #
223
+ # @see #run_audits
224
+ # @see Chef::Audit::Runner#run
225
+ #
226
+ # @raise [Chef::Exceptions::RunFailedWrappingError] If converge or audit failed.
227
+ #
228
+ # @see Chef::Config#enforce_path_sanity
229
+ # @see Chef::Config#solo
230
+ # @see Chef::Config#audit_mode
231
+ #
232
+ # @return Always returns true.
233
+ #
234
+ def run
235
+ run_error = nil
173
236
 
174
- Chef.set_provider_priority_map(Chef::Platform::ProviderPriorityMap.instance)
175
- Chef.set_resource_priority_map(Chef::Platform::ResourcePriorityMap.instance)
237
+ runlock = RunLock.new(Chef::Config.lockfile)
238
+ # TODO feels like acquire should have its own block arg for this
239
+ runlock.acquire
240
+ # don't add code that may fail before entering this section to be sure to release lock
241
+ begin
242
+ runlock.save_pid
243
+
244
+ request_id = Chef::RequestID.instance.request_id
245
+ run_context = nil
246
+ events.run_start(Chef::VERSION)
247
+ Chef::Log.info("*** Chef #{Chef::VERSION} ***")
248
+ Chef::Log.info "Chef-client pid: #{Process.pid}"
249
+ Chef::Log.debug("Chef-client request_id: #{request_id}")
250
+ enforce_path_sanity
251
+ run_ohai
252
+
253
+ register unless Chef::Config[:solo]
254
+
255
+ load_node
256
+
257
+ build_node
258
+
259
+ run_status.run_id = request_id
260
+ run_status.start_clock
261
+ Chef::Log.info("Starting Chef Run for #{node.name}")
262
+ run_started
263
+
264
+ do_windows_admin_check
265
+
266
+ run_context = setup_run_context
267
+
268
+ if Chef::Config[:audit_mode] != :audit_only
269
+ converge_error = converge_and_save(run_context)
270
+ end
271
+
272
+ if Chef::Config[:why_run] == true
273
+ # why_run should probably be renamed to why_converge
274
+ Chef::Log.debug("Not running controls in 'why_run' mode - this mode is used to see potential converge changes")
275
+ elsif Chef::Config[:audit_mode] != :disabled
276
+ audit_error = run_audits(run_context)
277
+ end
278
+
279
+ # Raise converge_error so run_failed reporters/events are processed.
280
+ raise converge_error if converge_error
281
+
282
+ run_status.stop_clock
283
+ Chef::Log.info("Chef Run complete in #{run_status.elapsed_time} seconds")
284
+ run_completed_successfully
285
+ events.run_completed(node)
286
+
287
+ # rebooting has to be the last thing we do, no exceptions.
288
+ Chef::Platform::Rebooter.reboot_if_needed!(node)
289
+ rescue Exception => run_error
290
+ # CHEF-3336: Send the error first in case something goes wrong below and we don't know why
291
+ Chef::Log.debug("Re-raising exception: #{run_error.class} - #{run_error.message}\n#{run_error.backtrace.join("\n ")}")
292
+ # If we failed really early, we may not have a run_status yet. Too early for these to be of much use.
293
+ if run_status
294
+ run_status.stop_clock
295
+ run_status.exception = run_error
296
+ run_failed
297
+ end
298
+ events.run_failed(run_error)
299
+ ensure
300
+ Chef::RequestID.instance.reset_request_id
301
+ request_id = nil
302
+ @run_status = nil
303
+ run_context = nil
304
+ runlock.release
305
+ GC.start
306
+ end
307
+
308
+ # Raise audit, converge, and other errors here so that we exit
309
+ # with the proper exit status code and everything gets raised
310
+ # as a RunFailedWrappingError
311
+ if run_error || converge_error || audit_error
312
+ error = if run_error == converge_error
313
+ Chef::Exceptions::RunFailedWrappingError.new(converge_error, audit_error)
314
+ else
315
+ Chef::Exceptions::RunFailedWrappingError.new(run_error, converge_error, audit_error)
316
+ end
317
+ error.fill_backtrace
318
+ Chef::Application.debug_stacktrace(error)
319
+ raise error
320
+ end
321
+
322
+ true
176
323
  end
177
324
 
325
+ #
326
+ # Private API
327
+ # TODO make this stuff protected or private
328
+ #
329
+
330
+ # @api private
178
331
  def configure_formatters
179
332
  formatters_for_run.map do |formatter_name, output_path|
180
333
  if output_path.nil?
@@ -187,6 +340,7 @@ class Chef
187
340
  end
188
341
  end
189
342
 
343
+ # @api private
190
344
  def formatters_for_run
191
345
  if Chef::Config.formatters.empty?
192
346
  [default_formatter]
@@ -195,6 +349,7 @@ class Chef
195
349
  end
196
350
  end
197
351
 
352
+ # @api private
198
353
  def default_formatter
199
354
  if (STDOUT.tty? && !Chef::Config[:force_logger]) || Chef::Config[:force_formatter]
200
355
  [:doc]
@@ -203,6 +358,7 @@ class Chef
203
358
  end
204
359
  end
205
360
 
361
+ # @api private
206
362
  def configure_event_loggers
207
363
  if Chef::Config.disable_event_logger
208
364
  []
@@ -219,8 +375,9 @@ class Chef
219
375
  end
220
376
  end
221
377
 
222
- # Resource repoters send event information back to the chef server for processing.
223
- # Can only be called after we have a @rest object
378
+ # Resource reporters send event information back to the chef server for
379
+ # processing. Can only be called after we have a @rest object
380
+ # @api private
224
381
  def register_reporters
225
382
  [
226
383
  Chef::ResourceReporter.new(rest),
@@ -230,43 +387,123 @@ class Chef
230
387
  end
231
388
  end
232
389
 
390
+ #
391
+ # Callback to fire notifications that the Chef run is starting
392
+ #
393
+ # @api private
394
+ #
395
+ def run_started
396
+ self.class.run_start_notifications.each do |notification|
397
+ notification.call(run_status)
398
+ end
399
+ events.run_started(run_status)
400
+ end
401
+
402
+ #
403
+ # Callback to fire notifications that the run completed successfully
404
+ #
405
+ # @api private
406
+ #
407
+ def run_completed_successfully
408
+ success_handlers = self.class.run_completed_successfully_notifications
409
+ success_handlers.each do |notification|
410
+ notification.call(run_status)
411
+ end
412
+ end
413
+
414
+ #
415
+ # Callback to fire notifications that the Chef run failed
416
+ #
417
+ # @api private
418
+ #
419
+ def run_failed
420
+ failure_handlers = self.class.run_failed_notifications
421
+ failure_handlers.each do |notification|
422
+ notification.call(run_status)
423
+ end
424
+ end
425
+
426
+ #
233
427
  # Instantiates a Chef::Node object, possibly loading the node's prior state
234
- # when using chef-client. Delegates to policy_builder. Injects the built node
235
- # into the Chef class.
428
+ # when using chef-client. Sets Chef.node to the new node.
236
429
  #
237
430
  # @return [Chef::Node] The node object for this Chef run
431
+ #
432
+ # @see Chef::PolicyBuilder#load_node
433
+ #
434
+ # @api private
435
+ #
238
436
  def load_node
239
437
  policy_builder.load_node
240
- @node = policy_builder.node
241
- Chef.set_node(@node)
438
+ run_status.node = policy_builder.node
439
+ Chef.set_node(policy_builder.node)
242
440
  node
243
441
  end
244
442
 
245
- # Mutates the `node` object to prepare it for the chef run. Delegates to
246
- # policy_builder
443
+ #
444
+ # Mutates the `node` object to prepare it for the chef run.
247
445
  #
248
446
  # @return [Chef::Node] The updated node object
447
+ #
448
+ # @see Chef::PolicyBuilder#build_node
449
+ #
450
+ # @api private
451
+ #
249
452
  def build_node
250
453
  policy_builder.build_node
251
- @run_status.node = node
454
+ run_status.node = node
252
455
  node
253
456
  end
254
457
 
458
+ #
459
+ # Sync cookbooks to local cache.
460
+ #
461
+ # TODO this appears to be unused.
462
+ #
463
+ # @see Chef::PolicyBuilder#sync_cookbooks
464
+ #
465
+ # @api private
466
+ #
467
+ def sync_cookbooks
468
+ policy_builder.sync_cookbooks
469
+ end
470
+
471
+ #
472
+ # Sets up the run context.
473
+ #
474
+ # @see Chef::PolicyBuilder#setup_run_context
475
+ #
476
+ # @return The newly set up run context
477
+ #
478
+ # @api private
255
479
  def setup_run_context
256
- run_context = policy_builder.setup_run_context(@specific_recipes)
480
+ run_context = policy_builder.setup_run_context(specific_recipes)
257
481
  assert_cookbook_path_not_empty(run_context)
258
482
  run_status.run_context = run_context
259
483
  run_context
260
484
  end
261
485
 
262
- def sync_cookbooks
263
- policy_builder.sync_cookbooks
264
- end
265
-
486
+ #
487
+ # The PolicyBuilder strategy for figuring out run list and cookbooks.
488
+ #
489
+ # @return [Chef::PolicyBuilder::Policyfile, Chef::PolicyBuilder::ExpandNodeObject]
490
+ #
491
+ # @api private
492
+ #
266
493
  def policy_builder
267
- @policy_builder ||= Chef::PolicyBuilder.strategy.new(node_name, ohai.data, json_attribs, @override_runlist, events)
494
+ @policy_builder ||= Chef::PolicyBuilder.strategy.new(node_name, ohai.data, json_attribs, override_runlist, events)
268
495
  end
269
496
 
497
+ #
498
+ # Save the updated node to Chef.
499
+ #
500
+ # Does not save if we are in solo mode or using override_runlist.
501
+ #
502
+ # @see Chef::Node#save
503
+ # @see Chef::Config#solo
504
+ #
505
+ # @api private
506
+ #
270
507
  def save_updated_node
271
508
  if Chef::Config[:solo]
272
509
  # nothing to do
@@ -274,16 +511,46 @@ class Chef
274
511
  Chef::Log.warn("Skipping final node save because override_runlist was given")
275
512
  else
276
513
  Chef::Log.debug("Saving the current state of node #{node_name}")
277
- @node.save
514
+ node.save
278
515
  end
279
516
  end
280
517
 
518
+ #
519
+ # Run ohai plugins. Runs all ohai plugins unless minimal_ohai is specified.
520
+ #
521
+ # Sends the ohai_completed event when finished.
522
+ #
523
+ # @see Chef::EventDispatcher#
524
+ # @see Chef::Config#minimal_ohai
525
+ #
526
+ # @api private
527
+ #
281
528
  def run_ohai
282
529
  filter = Chef::Config[:minimal_ohai] ? %w[fqdn machinename hostname platform platform_version os os_version] : nil
283
530
  ohai.all_plugins(filter)
284
- @events.ohai_completed(node)
531
+ events.ohai_completed(node)
285
532
  end
286
533
 
534
+ #
535
+ # Figure out the node name we are working with.
536
+ #
537
+ # It tries these, in order:
538
+ # - Chef::Config.node_name
539
+ # - ohai[:fqdn]
540
+ # - ohai[:machinename]
541
+ # - ohai[:hostname]
542
+ #
543
+ # If we are running against a server with authentication protocol < 1.0, we
544
+ # *require* authentication protocol version 1.1.
545
+ #
546
+ # @raise [Chef::Exceptions::CannotDetermineNodeName] If the node name is not
547
+ # set and cannot be determined via ohai.
548
+ #
549
+ # @see Chef::Config#node_name
550
+ # @see Chef::Config#authentication_protocol_version
551
+ #
552
+ # @api private
553
+ #
287
554
  def node_name
288
555
  name = Chef::Config[:node_name] || ohai[:fqdn] || ohai[:machinename] || ohai[:hostname]
289
556
  Chef::Config[:node_name] = name
@@ -292,6 +559,8 @@ class Chef
292
559
 
293
560
  # node names > 90 bytes only work with authentication protocol >= 1.1
294
561
  # see discussion in config.rb.
562
+ # TODO use a computed default in Chef::Config to determine this instead of
563
+ # setting it.
295
564
  if name.bytesize > 90
296
565
  Chef::Config[:authentication_protocol_version] = "1.1"
297
566
  end
@@ -300,46 +569,86 @@ class Chef
300
569
  end
301
570
 
302
571
  #
303
- # === Returns
304
- # rest<Chef::REST>:: returns Chef::REST connection object
572
+ # Determine our private key and set up the connection to the Chef server.
573
+ #
574
+ # Skips registration and fires the `skipping_registration` event if
575
+ # Chef::Config.client_key is unspecified or already exists.
576
+ #
577
+ # If Chef::Config.client_key does not exist, we register the client with the
578
+ # Chef server and fire the registration_start and registration_completed events.
579
+ #
580
+ # @return [Chef::REST] The server connection object.
581
+ #
582
+ # @see Chef::Config#chef_server_url
583
+ # @see Chef::Config#client_key
584
+ # @see Chef::ApiClient::Registration#run
585
+ # @see Chef::EventDispatcher#skipping_registration
586
+ # @see Chef::EventDispatcher#registration_start
587
+ # @see Chef::EventDispatcher#registration_completed
588
+ # @see Chef::EventDispatcher#registration_failed
589
+ #
590
+ # @api private
591
+ #
305
592
  def register(client_name=node_name, config=Chef::Config)
306
593
  if !config[:client_key]
307
- @events.skipping_registration(client_name, config)
594
+ events.skipping_registration(client_name, config)
308
595
  Chef::Log.debug("Client key is unspecified - skipping registration")
309
596
  elsif File.exists?(config[:client_key])
310
- @events.skipping_registration(client_name, config)
597
+ events.skipping_registration(client_name, config)
311
598
  Chef::Log.debug("Client key #{config[:client_key]} is present - skipping registration")
312
599
  else
313
- @events.registration_start(node_name, config)
600
+ events.registration_start(node_name, config)
314
601
  Chef::Log.info("Client key #{config[:client_key]} is not present - registering")
315
602
  Chef::ApiClient::Registration.new(node_name, config[:client_key]).run
316
- @events.registration_completed
603
+ events.registration_completed
317
604
  end
318
605
  # We now have the client key, and should use it from now on.
319
606
  @rest = Chef::REST.new(config[:chef_server_url], client_name, config[:client_key])
320
607
  register_reporters
321
608
  rescue Exception => e
609
+ # TODO this should probably only ever fire if we *started* registration.
610
+ # Move it to the block above.
322
611
  # TODO: munge exception so a semantic failure message can be given to the
323
612
  # user
324
- @events.registration_failed(client_name, e, config)
613
+ events.registration_failed(client_name, e, config)
325
614
  raise
326
615
  end
327
616
 
328
- # Converges the node.
329
617
  #
330
- # === Returns
331
- # The thrown exception, if there was one. If this returns nil the converge was successful.
618
+ # Converges all compiled resources.
619
+ #
620
+ # Fires the converge_start, converge_complete and converge_failed events.
621
+ #
622
+ # If the exception `:end_client_run_early` is thrown during convergence, it
623
+ # does not mark the run complete *or* failed, and returns `nil`
624
+ #
625
+ # @param run_context The run context.
626
+ #
627
+ # @return The thrown exception, if we are in audit mode. `nil` means the
628
+ # converge was successful or ended early.
629
+ #
630
+ # @raise Any converge exception, unless we are in audit mode, in which case
631
+ # we *return* the exception.
632
+ #
633
+ # @see Chef::Runner#converge
634
+ # @see Chef::Config#audit_mode
635
+ # @see Chef::EventDispatch#converge_start
636
+ # @see Chef::EventDispatch#converge_complete
637
+ # @see Chef::EventDispatch#converge_failed
638
+ #
639
+ # @api private
640
+ #
332
641
  def converge(run_context)
333
642
  converge_exception = nil
334
643
  catch(:end_client_run_early) do
335
644
  begin
336
- @events.converge_start(run_context)
645
+ events.converge_start(run_context)
337
646
  Chef::Log.debug("Converging node #{node_name}")
338
647
  @runner = Chef::Runner.new(run_context)
339
- runner.converge
340
- @events.converge_complete
648
+ @runner.converge
649
+ events.converge_complete
341
650
  rescue Exception => e
342
- @events.converge_failed(e)
651
+ events.converge_failed(e)
343
652
  raise e if Chef::Config[:audit_mode] == :disabled
344
653
  converge_exception = e
345
654
  end
@@ -347,8 +656,28 @@ class Chef
347
656
  converge_exception
348
657
  end
349
658
 
659
+ #
660
+ # Converge the node via and then save it if successful.
661
+ #
662
+ # @param run_context The run context.
663
+ #
664
+ # @return The thrown exception, if we are in audit mode. `nil` means the
665
+ # converge was successful or ended early.
666
+ #
667
+ # @raise Any converge or node save exception, unless we are in audit mode,
668
+ # in which case we *return* the exception.
669
+ #
670
+ # @see #converge
671
+ # @see #save_updated_mode
672
+ # @see Chef::Config#audit_mode
673
+ #
674
+ # @api private
675
+ #
350
676
  # We don't want to change the old API on the `converge` method to have it perform
351
677
  # saving. So we wrap it in this method.
678
+ # TODO given this seems to be pretty internal stuff, how badly do we need to
679
+ # split this stuff up?
680
+ #
352
681
  def converge_and_save(run_context)
353
682
  converge_exception = converge(run_context)
354
683
  unless converge_exception
@@ -362,37 +691,67 @@ class Chef
362
691
  converge_exception
363
692
  end
364
693
 
694
+ #
695
+ # Run the audit phase.
696
+ #
697
+ # Triggers the audit_phase_start, audit_phase_complete and
698
+ # audit_phase_failed events.
699
+ #
700
+ # @param run_context The run context.
701
+ #
702
+ # @return Any thrown exceptions. `nil` if successful.
703
+ #
704
+ # @see Chef::Audit::Runner#run
705
+ # @see Chef::EventDispatch#audit_phase_start
706
+ # @see Chef::EventDispatch#audit_phase_complete
707
+ # @see Chef::EventDispatch#audit_phase_failed
708
+ #
709
+ # @api private
710
+ #
365
711
  def run_audits(run_context)
366
- audit_exception = nil
367
712
  begin
368
- @events.audit_phase_start(run_status)
713
+ events.audit_phase_start(run_status)
369
714
  Chef::Log.info("Starting audit phase")
370
715
  auditor = Chef::Audit::Runner.new(run_context)
371
716
  auditor.run
372
717
  if auditor.failed?
373
- raise Chef::Exceptions::AuditsFailed.new(auditor.num_failed, auditor.num_total)
718
+ audit_exception = Chef::Exceptions::AuditsFailed.new(auditor.num_failed, auditor.num_total)
719
+ @events.audit_phase_failed(audit_exception, Chef::Audit::Logger.read_buffer)
720
+ else
721
+ @events.audit_phase_complete(Chef::Audit::Logger.read_buffer)
374
722
  end
375
- @events.audit_phase_complete
376
723
  rescue Exception => e
377
724
  Chef::Log.error("Audit phase failed with error message: #{e.message}")
378
- @events.audit_phase_failed(e)
725
+ @events.audit_phase_failed(e, Chef::Audit::Logger.read_buffer)
379
726
  audit_exception = e
380
727
  end
381
728
  audit_exception
382
729
  end
383
730
 
384
- # Expands the run list. Delegates to the policy_builder.
385
731
  #
386
- # Normally this does not need to be called from here, it will be called by
387
- # build_node. This is provided so external users (like the chefspec
388
- # project) can inject custom behavior into the run process.
732
+ # Expands the run list.
733
+ #
734
+ # @return [Chef::RunListExpansion] The expanded run list.
735
+ #
736
+ # @see Chef::PolicyBuilder#expand_run_list
389
737
  #
390
- # === Returns
391
- # RunListExpansion: A RunListExpansion or API compatible object.
392
738
  def expanded_run_list
393
739
  policy_builder.expand_run_list
394
740
  end
395
741
 
742
+ #
743
+ # Check if the user has Administrator privileges on windows.
744
+ #
745
+ # Throws an error if the user is not an admin, and
746
+ # `Chef::Config.fatal_windows_admin_check` is true.
747
+ #
748
+ # @raise [Chef::Exceptions::WindowsNotAdmin] If the user is not an admin.
749
+ #
750
+ # @see Chef::platform#windows?
751
+ # @see Chef::Config#fatal_windows_admin_check
752
+ #
753
+ # @api private
754
+ #
396
755
  def do_windows_admin_check
397
756
  if Chef::Platform.windows?
398
757
  Chef::Log.debug("Checking for administrator privileges....")
@@ -412,99 +771,121 @@ class Chef
412
771
  end
413
772
  end
414
773
 
415
- # Do a full run for this Chef::Client. Calls:
416
- #
417
- # * run_ohai - Collect information about the system
418
- # * build_node - Get the last known state, merge with local changes
419
- # * register - If not in solo mode, make sure the server knows about this client
420
- # * sync_cookbooks - If not in solo mode, populate the local cache with the node's cookbooks
421
- # * converge - Bring this system up to date
422
- #
423
- # === Returns
424
- # true:: Always returns true.
425
- def run
426
- runlock = RunLock.new(Chef::Config.lockfile)
427
- runlock.acquire
428
- # don't add code that may fail before entering this section to be sure to release lock
429
- begin
430
- runlock.save_pid
431
-
432
- request_id = Chef::RequestID.instance.request_id
433
- run_context = nil
434
- @events.run_start(Chef::VERSION)
435
- Chef::Log.info("*** Chef #{Chef::VERSION} ***")
436
- Chef::Log.info "Chef-client pid: #{Process.pid}"
437
- Chef::Log.debug("Chef-client request_id: #{request_id}")
438
- enforce_path_sanity
439
- run_ohai
440
-
441
- register unless Chef::Config[:solo]
442
-
443
- load_node
444
-
445
- build_node
774
+ # Notification registration
775
+ class<<self
776
+ #
777
+ # Add a listener for the 'client run started' event.
778
+ #
779
+ # @param notification_block The callback (takes |run_status| parameter).
780
+ # @yieldparam [Chef::RunStatus] run_status The run status.
781
+ #
782
+ def when_run_starts(&notification_block)
783
+ run_start_notifications << notification_block
784
+ end
446
785
 
447
- run_status.run_id = request_id
448
- run_status.start_clock
449
- Chef::Log.info("Starting Chef Run for #{node.name}")
450
- run_started
786
+ #
787
+ # Add a listener for the 'client run success' event.
788
+ #
789
+ # @param notification_block The callback (takes |run_status| parameter).
790
+ # @yieldparam [Chef::RunStatus] run_status The run status.
791
+ #
792
+ def when_run_completes_successfully(&notification_block)
793
+ run_completed_successfully_notifications << notification_block
794
+ end
451
795
 
452
- do_windows_admin_check
796
+ #
797
+ # Add a listener for the 'client run failed' event.
798
+ #
799
+ # @param notification_block The callback (takes |run_status| parameter).
800
+ # @yieldparam [Chef::RunStatus] run_status The run status.
801
+ #
802
+ def when_run_fails(&notification_block)
803
+ run_failed_notifications << notification_block
804
+ end
453
805
 
454
- run_context = setup_run_context
806
+ #
807
+ # Clears all listeners for client run status events.
808
+ #
809
+ # Primarily for testing purposes.
810
+ #
811
+ # @api private
812
+ #
813
+ def clear_notifications
814
+ @run_start_notifications = nil
815
+ @run_completed_successfully_notifications = nil
816
+ @run_failed_notifications = nil
817
+ end
455
818
 
456
- if Chef::Config[:audit_mode] != :audit_only
457
- converge_error = converge_and_save(run_context)
458
- end
819
+ #
820
+ # TODO These seem protected to me.
821
+ #
822
+
823
+ #
824
+ # Listeners to be run when the client run starts.
825
+ #
826
+ # @return [Array<Proc>]
827
+ #
828
+ # @api private
829
+ #
830
+ def run_start_notifications
831
+ @run_start_notifications ||= []
832
+ end
459
833
 
460
- if Chef::Config[:why_run] == true
461
- # why_run should probably be renamed to why_converge
462
- Chef::Log.debug("Not running controls in 'why_run' mode - this mode is used to see potential converge changes")
463
- elsif Chef::Config[:audit_mode] != :disabled
464
- audit_error = run_audits(run_context)
465
- end
834
+ #
835
+ # Listeners to be run when the client run completes successfully.
836
+ #
837
+ # @return [Array<Proc>]
838
+ #
839
+ # @api private
840
+ #
841
+ def run_completed_successfully_notifications
842
+ @run_completed_successfully_notifications ||= []
843
+ end
466
844
 
467
- if converge_error || audit_error
468
- e = Chef::Exceptions::RunFailedWrappingError.new(converge_error, audit_error)
469
- e.fill_backtrace
470
- raise e
471
- end
845
+ #
846
+ # Listeners to be run when the client run fails.
847
+ #
848
+ # @return [Array<Proc>]
849
+ #
850
+ # @api private
851
+ #
852
+ def run_failed_notifications
853
+ @run_failed_notifications ||= []
854
+ end
855
+ end
472
856
 
473
- run_status.stop_clock
474
- Chef::Log.info("Chef Run complete in #{run_status.elapsed_time} seconds")
475
- run_completed_successfully
476
- @events.run_completed(node)
857
+ #
858
+ # IO stream that will be used as 'STDOUT' for formatters. Formatters are
859
+ # configured during `initialize`, so this provides a convenience for
860
+ # setting alternative IO stream during tests.
861
+ #
862
+ # @api private
863
+ #
864
+ STDOUT_FD = STDOUT
477
865
 
478
- # rebooting has to be the last thing we do, no exceptions.
479
- Chef::Platform::Rebooter.reboot_if_needed!(node)
866
+ #
867
+ # IO stream that will be used as 'STDERR' for formatters. Formatters are
868
+ # configured during `initialize`, so this provides a convenience for
869
+ # setting alternative IO stream during tests.
870
+ #
871
+ # @api private
872
+ #
873
+ STDERR_FD = STDERR
480
874
 
481
- true
875
+ #
876
+ # Deprecated writers
877
+ #
482
878
 
483
- rescue Exception => e
484
- # CHEF-3336: Send the error first in case something goes wrong below and we don't know why
485
- Chef::Log.debug("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
486
- # If we failed really early, we may not have a run_status yet. Too early for these to be of much use.
487
- if run_status
488
- run_status.stop_clock
489
- run_status.exception = e
490
- run_failed
491
- end
492
- Chef::Application.debug_stacktrace(e)
493
- @events.run_failed(e)
494
- raise
495
- ensure
496
- Chef::RequestID.instance.reset_request_id
497
- request_id = nil
498
- @run_status = nil
499
- run_context = nil
500
- runlock.release
501
- GC.start
502
- end
503
- true
504
- end
879
+ include Chef::Mixin::Deprecation
880
+ deprecated_attr_writer :ohai, "There is no alternative. Leave ohai alone!"
881
+ deprecated_attr_writer :rest, "There is no alternative. Leave rest alone!"
882
+ deprecated_attr :runner, "There is no alternative. Leave runner alone!"
505
883
 
506
884
  private
507
885
 
886
+ attr_reader :override_runlist
887
+ attr_reader :specific_recipes
888
+
508
889
  def empty_directory?(path)
509
890
  !File.exists?(path) || (Dir.entries(path).size <= 2)
510
891
  end
@@ -536,7 +917,6 @@ class Chef
536
917
 
537
918
  Chef::ReservedNames::Win32::Security.has_admin_privileges?
538
919
  end
539
-
540
920
  end
541
921
  end
542
922