chef 12.5.1 → 12.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -1
  3. data/README.md +6 -4
  4. data/Rakefile +1 -4
  5. data/chef-windows.gemspec +21 -0
  6. data/chef.gemspec +58 -0
  7. data/lib/chef/api_client/registration.rb +9 -4
  8. data/lib/chef/application.rb +3 -84
  9. data/lib/chef/application/apply.rb +9 -2
  10. data/lib/chef/application/client.rb +8 -3
  11. data/lib/chef/application/solo.rb +7 -1
  12. data/lib/chef/application/windows_service.rb +21 -6
  13. data/lib/chef/application/windows_service_manager.rb +2 -3
  14. data/lib/chef/audit/runner.rb +1 -0
  15. data/lib/chef/chef_class.rb +1 -11
  16. data/lib/chef/chef_fs/chef_fs_data_store.rb +181 -2
  17. data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +5 -0
  18. data/lib/chef/chef_fs/file_system/file_system_entry.rb +11 -7
  19. data/lib/chef/client.rb +28 -1
  20. data/lib/chef/cookbook/cookbook_collection.rb +14 -1
  21. data/lib/chef/cookbook/cookbook_version_loader.rb +1 -1
  22. data/lib/chef/cookbook/metadata.rb +115 -9
  23. data/lib/chef/cookbook/remote_file_vendor.rb +1 -1
  24. data/lib/chef/cookbook_version.rb +6 -2
  25. data/lib/chef/data_bag.rb +1 -1
  26. data/lib/chef/data_bag_item.rb +1 -1
  27. data/lib/chef/digester.rb +5 -1
  28. data/lib/chef/dsl/chef_provisioning.rb +57 -0
  29. data/lib/chef/dsl/cheffish.rb +64 -0
  30. data/lib/chef/dsl/declare_resource.rb +108 -0
  31. data/lib/chef/dsl/platform_introspection.rb +3 -3
  32. data/lib/chef/dsl/recipe.rb +3 -73
  33. data/lib/chef/dsl/resources.rb +27 -1
  34. data/lib/chef/event_dispatch/base.rb +3 -0
  35. data/lib/chef/event_dispatch/dispatcher.rb +5 -0
  36. data/lib/chef/event_dispatch/events_output_stream.rb +8 -0
  37. data/lib/chef/exceptions.rb +21 -1
  38. data/lib/chef/file_access_control/unix.rb +12 -12
  39. data/lib/chef/file_content_management/deploy/cp.rb +2 -2
  40. data/lib/chef/file_content_management/deploy/mv_unix.rb +4 -4
  41. data/lib/chef/file_content_management/deploy/mv_windows.rb +1 -1
  42. data/lib/chef/formatters/base.rb +7 -0
  43. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +2 -2
  44. data/lib/chef/formatters/indentable_output_stream.rb +5 -0
  45. data/lib/chef/http.rb +19 -3
  46. data/lib/chef/http/decompressor.rb +2 -2
  47. data/lib/chef/json_compat.rb +1 -0
  48. data/lib/chef/knife.rb +16 -2
  49. data/lib/chef/knife/bootstrap.rb +55 -10
  50. data/lib/chef/knife/cookbook_site_install.rb +5 -1
  51. data/lib/chef/knife/core/bootstrap_context.rb +2 -1
  52. data/lib/chef/knife/core/node_presenter.rb +1 -1
  53. data/lib/chef/knife/ssh.rb +30 -16
  54. data/lib/chef/knife/ssl_check.rb +4 -2
  55. data/lib/chef/knife/ssl_fetch.rb +3 -2
  56. data/lib/chef/knife/status.rb +14 -1
  57. data/lib/chef/log.rb +14 -0
  58. data/lib/chef/mixin/get_source_from_package.rb +7 -2
  59. data/lib/chef/mixin/properties.rb +302 -0
  60. data/lib/chef/mixin/proxified_socket.rb +38 -0
  61. data/lib/chef/mixin/subclass_directive.rb +37 -0
  62. data/lib/chef/node.rb +13 -5
  63. data/lib/chef/platform/query_helpers.rb +14 -3
  64. data/lib/chef/platform/service_helpers.rb +20 -38
  65. data/lib/chef/policy_builder/expand_node_object.rb +3 -0
  66. data/lib/chef/policy_builder/policyfile.rb +1 -0
  67. data/lib/chef/property.rb +51 -12
  68. data/lib/chef/provider.rb +40 -35
  69. data/lib/chef/provider/deploy.rb +1 -1
  70. data/lib/chef/provider/dsc_resource.rb +54 -20
  71. data/lib/chef/provider/execute.rb +25 -4
  72. data/lib/chef/provider/group.rb +1 -1
  73. data/lib/chef/provider/lwrp_base.rb +1 -0
  74. data/lib/chef/provider/package.rb +76 -30
  75. data/lib/chef/provider/package/dpkg.rb +152 -69
  76. data/lib/chef/provider/package/openbsd.rb +6 -8
  77. data/lib/chef/provider/package/solaris.rb +2 -0
  78. data/lib/chef/provider/package/windows.rb +95 -14
  79. data/lib/chef/provider/package/windows/exe.rb +129 -0
  80. data/lib/chef/provider/package/windows/msi.rb +37 -13
  81. data/lib/chef/provider/package/windows/registry_uninstall_entry.rb +89 -0
  82. data/lib/chef/provider/package/yum.rb +13 -3
  83. data/lib/chef/provider/powershell_script.rb +3 -0
  84. data/lib/chef/provider/remote_file/cache_control_data.rb +37 -4
  85. data/lib/chef/provider/remote_file/http.rb +1 -1
  86. data/lib/chef/provider/script.rb +1 -0
  87. data/lib/chef/provider/service.rb +13 -10
  88. data/lib/chef/provider/service/solaris.rb +43 -17
  89. data/lib/chef/provider/service/upstart.rb +3 -3
  90. data/lib/chef/provider/user.rb +1 -1
  91. data/lib/chef/provider/user/dscl.rb +111 -100
  92. data/lib/chef/provider/user/windows.rb +5 -3
  93. data/lib/chef/recipe.rb +3 -5
  94. data/lib/chef/resource.rb +77 -320
  95. data/lib/chef/resource/action_class.rb +4 -0
  96. data/lib/chef/resource/dpkg_package.rb +4 -3
  97. data/lib/chef/resource/dsc_resource.rb +40 -2
  98. data/lib/chef/resource/execute.rb +9 -1
  99. data/lib/chef/resource/ksh.rb +32 -0
  100. data/lib/chef/resource/lwrp_base.rb +6 -10
  101. data/lib/chef/resource/package.rb +8 -9
  102. data/lib/chef/resource/registry_key.rb +1 -1
  103. data/lib/chef/resource/resource_notification.rb +14 -1
  104. data/lib/chef/resource/script.rb +1 -1
  105. data/lib/chef/resource/windows_package.rb +1 -1
  106. data/lib/chef/resource_builder.rb +14 -7
  107. data/lib/chef/resource_reporter.rb +6 -0
  108. data/lib/chef/resources.rb +1 -7
  109. data/lib/chef/rest.rb +1 -1
  110. data/lib/chef/run_context.rb +45 -2
  111. data/lib/chef/run_list/run_list_expansion.rb +47 -0
  112. data/lib/chef/runner.rb +25 -0
  113. data/lib/chef/search/query.rb +16 -2
  114. data/lib/chef/util/diff.rb +2 -2
  115. data/lib/chef/util/powershell/ps_credential.rb +2 -3
  116. data/lib/chef/version.rb +1 -1
  117. data/lib/chef/win32/api/file.rb +51 -1
  118. data/lib/chef/win32/file.rb +5 -0
  119. data/lib/chef/win32/file/version_info.rb +93 -0
  120. data/lib/chef/win32/mutex.rb +1 -1
  121. data/spec/data/apt/chef-integration-test2-1.0/debian/changelog +5 -0
  122. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.debhelper.log +45 -0
  123. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.substvars +1 -0
  124. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/conffiles +1 -0
  125. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/control +10 -0
  126. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/md5sums +1 -0
  127. data/spec/data/apt/chef-integration-test2-1.0/debian/compat +1 -0
  128. data/spec/data/apt/chef-integration-test2-1.0/debian/conffiles +1 -0
  129. data/spec/data/apt/chef-integration-test2-1.0/debian/control +13 -0
  130. data/spec/data/apt/chef-integration-test2-1.0/debian/copyright +34 -0
  131. data/spec/data/apt/chef-integration-test2-1.0/debian/files +1 -0
  132. data/spec/data/apt/chef-integration-test2-1.0/debian/rules +13 -0
  133. data/spec/data/apt/chef-integration-test2-1.0/debian/source/format +1 -0
  134. data/spec/data/apt/chef-integration-test2_1.0-1.debian.tar.gz +0 -0
  135. data/spec/data/apt/chef-integration-test2_1.0-1.dsc +18 -0
  136. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.build +91 -0
  137. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.changes +31 -0
  138. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.deb +0 -0
  139. data/spec/data/apt/chef-integration-test2_1.0.orig.tar.gz +0 -0
  140. data/spec/functional/application_spec.rb +1 -1
  141. data/spec/functional/audit/runner_spec.rb +4 -0
  142. data/spec/functional/knife/ssh_spec.rb +5 -5
  143. data/spec/functional/notifications_spec.rb +74 -4
  144. data/spec/functional/resource/aix_service_spec.rb +2 -2
  145. data/spec/functional/resource/dpkg_package_spec.rb +339 -0
  146. data/spec/functional/resource/ifconfig_spec.rb +3 -1
  147. data/spec/functional/resource/mount_spec.rb +5 -2
  148. data/spec/functional/resource/package_spec.rb +1 -1
  149. data/spec/functional/resource/user/windows_spec.rb +8 -0
  150. data/spec/functional/resource/windows_package_spec.rb +177 -0
  151. data/spec/functional/win32/version_info_spec.rb +50 -0
  152. data/spec/integration/client/client_spec.rb +80 -0
  153. data/spec/integration/knife/download_spec.rb +9 -0
  154. data/spec/integration/knife/upload_spec.rb +28 -1
  155. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +93 -23
  156. data/spec/integration/recipes/resource_action_spec.rb +211 -116
  157. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +72 -0
  158. data/spec/integration/solo/solo_spec.rb +34 -0
  159. data/spec/spec_helper.rb +11 -1
  160. data/spec/support/platform_helpers.rb +8 -0
  161. data/spec/support/shared/integration/integration_helper.rb +6 -0
  162. data/spec/support/shared/unit/execute_resource.rb +5 -0
  163. data/spec/support/shared/unit/platform_introspector.rb +7 -0
  164. data/spec/tiny_server.rb +6 -2
  165. data/spec/unit/api_client/registration_spec.rb +5 -4
  166. data/spec/unit/application_spec.rb +1 -181
  167. data/spec/unit/chef_fs/file_system/cookbook_subdir_spec.rb +34 -0
  168. data/spec/unit/cookbook/metadata_spec.rb +122 -2
  169. data/spec/unit/http_spec.rb +102 -0
  170. data/spec/unit/knife/bootstrap_spec.rb +55 -13
  171. data/spec/unit/knife/core/bootstrap_context_spec.rb +10 -3
  172. data/spec/unit/knife/ssl_check_spec.rb +7 -3
  173. data/spec/unit/knife/ssl_fetch_spec.rb +2 -2
  174. data/spec/unit/knife/status_spec.rb +13 -13
  175. data/spec/unit/knife_spec.rb +26 -2
  176. data/spec/unit/lwrp_spec.rb +1 -1
  177. data/spec/unit/mixin/properties_spec.rb +97 -0
  178. data/spec/unit/mixin/proxified_socket_spec.rb +94 -0
  179. data/spec/unit/mixin/subclass_directive_spec.rb +45 -0
  180. data/spec/unit/node_spec.rb +9 -1
  181. data/spec/unit/policy_builder/policyfile_spec.rb +2 -0
  182. data/spec/unit/property/validation_spec.rb +14 -12
  183. data/spec/unit/property_spec.rb +56 -0
  184. data/spec/unit/provider/deploy_spec.rb +1 -1
  185. data/spec/unit/provider/dsc_resource_spec.rb +63 -24
  186. data/spec/unit/provider/execute_spec.rb +95 -28
  187. data/spec/unit/provider/package/dpkg_spec.rb +185 -96
  188. data/spec/unit/provider/package/windows/exe_spec.rb +251 -0
  189. data/spec/unit/provider/package/windows/msi_spec.rb +94 -10
  190. data/spec/unit/provider/package/windows_spec.rb +227 -26
  191. data/spec/unit/provider/package/yum_spec.rb +6 -0
  192. data/spec/unit/provider/package_spec.rb +495 -366
  193. data/spec/unit/provider/remote_file/cache_control_data_spec.rb +62 -36
  194. data/spec/unit/provider/script_spec.rb +2 -2
  195. data/spec/unit/provider/service/solaris_smf_service_spec.rb +110 -39
  196. data/spec/unit/provider/service/upstart_service_spec.rb +19 -0
  197. data/spec/unit/provider/user/dscl_spec.rb +14 -0
  198. data/spec/unit/provider/user/windows_spec.rb +2 -2
  199. data/spec/unit/provider/user_spec.rb +9 -0
  200. data/spec/unit/provider_resolver_spec.rb +6 -30
  201. data/spec/unit/recipe_spec.rb +46 -20
  202. data/spec/unit/resource/chef_gem_spec.rb +1 -1
  203. data/spec/unit/resource/dsc_resource_spec.rb +14 -3
  204. data/spec/unit/resource/ksh_spec.rb +40 -0
  205. data/spec/unit/resource/registry_key_spec.rb +2 -2
  206. data/spec/unit/resource/resource_notification_spec.rb +44 -45
  207. data/spec/unit/resource_reporter_spec.rb +7 -0
  208. data/spec/unit/resource_spec.rb +268 -253
  209. data/spec/unit/rest_spec.rb +2 -2
  210. data/spec/unit/run_list/run_list_expansion_spec.rb +18 -3
  211. data/spec/unit/search/query_spec.rb +19 -1
  212. data/spec/unit/util/powershell/ps_credential_spec.rb +8 -1
  213. data/spec/unit/windows_service_spec.rb +83 -38
  214. data/tasks/external_tests.rb +19 -9
  215. data/tasks/rspec.rb +1 -1
  216. metadata +64 -15
  217. data/spec/support/pedant/Gemfile +0 -3
  218. data/spec/support/pedant/pedant_config.rb +0 -129
  219. data/spec/support/pedant/run_pedant.rb +0 -63
  220. data/spec/support/pedant/stickywicket.pem +0 -27
  221. data/spec/unit/provider/package_spec.rbe +0 -0
@@ -35,6 +35,10 @@ class Chef
35
35
  end
36
36
 
37
37
  def load_current_resource
38
+ if @new_resource.gid
39
+ Chef::Log.warn("The 'gid' attribute is not implemented by the Windows platform. Please use the 'group' resource to assign a user to a group.")
40
+ end
41
+
38
42
  @current_resource = Chef::Resource::User.new(@new_resource.name)
39
43
  @current_resource.username(@new_resource.username)
40
44
  user_info = nil
@@ -42,7 +46,6 @@ class Chef
42
46
  user_info = @net_user.get_info
43
47
 
44
48
  @current_resource.uid(user_info[:user_id])
45
- @current_resource.gid(user_info[:primary_group_id])
46
49
  @current_resource.comment(user_info[:full_name])
47
50
  @current_resource.home(user_info[:home_dir])
48
51
  @current_resource.shell(user_info[:script_path])
@@ -65,7 +68,7 @@ class Chef
65
68
  Chef::Log.debug("#{@new_resource} password has changed")
66
69
  return true
67
70
  end
68
- [ :uid, :gid, :comment, :home, :shell ].any? do |user_attrib|
71
+ [ :uid, :comment, :home, :shell ].any? do |user_attrib|
69
72
  !@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib) != @current_resource.send(user_attrib)
70
73
  end
71
74
  end
@@ -100,7 +103,6 @@ class Chef
100
103
  field_list = {
101
104
  'comment' => 'full_name',
102
105
  'home' => 'home_dir',
103
- 'gid' => 'primary_group_id',
104
106
  'uid' => 'user_id',
105
107
  'shell' => 'script_path',
106
108
  'password' => 'password'
@@ -97,10 +97,8 @@ class Chef
97
97
  # true<TrueClass>:: If all the parameters are present
98
98
  # false<FalseClass>:: If any of the parameters are missing
99
99
  def tagged?(*tags)
100
- return false if run_context.node[:tags].nil?
101
-
102
100
  tags.each do |tag|
103
- return false unless run_context.node[:tags].include?(tag)
101
+ return false unless run_context.node.tags.include?(tag)
104
102
  end
105
103
  true
106
104
  end
@@ -111,10 +109,10 @@ class Chef
111
109
  # tags<Array>:: A list of tags
112
110
  #
113
111
  # === Returns
114
- # tags<Array>:: The current list of run_context.node[:tags]
112
+ # tags<Array>:: The current list of run_context.node.tags
115
113
  def untag(*tags)
116
114
  tags.each do |tag|
117
- run_context.node.normal[:tags].delete(tag)
115
+ run_context.node.tags.delete(tag)
118
116
  end
119
117
  end
120
118
 
@@ -19,7 +19,6 @@
19
19
  #
20
20
 
21
21
  require 'chef/exceptions'
22
- require 'chef/mixin/params_validate'
23
22
  require 'chef/dsl/platform_introspection'
24
23
  require 'chef/dsl/data_query'
25
24
  require 'chef/dsl/registry_helper'
@@ -37,9 +36,11 @@ require 'chef/platform'
37
36
  require 'chef/resource/resource_notification'
38
37
  require 'chef/provider_resolver'
39
38
  require 'chef/resource_resolver'
39
+ require 'chef/provider'
40
40
  require 'set'
41
41
 
42
42
  require 'chef/mixin/deprecation'
43
+ require 'chef/mixin/properties'
43
44
  require 'chef/mixin/provides'
44
45
  require 'chef/mixin/shell_out'
45
46
  require 'chef/mixin/powershell_out'
@@ -61,6 +62,34 @@ class Chef
61
62
  include Chef::Mixin::ShellOut
62
63
  include Chef::Mixin::PowershellOut
63
64
 
65
+ # Bring in `property` and `property_type`
66
+ include Chef::Mixin::Properties
67
+
68
+ #
69
+ # The name of this particular resource.
70
+ #
71
+ # This special resource attribute is set automatically from the declaration
72
+ # of the resource, e.g.
73
+ #
74
+ # execute 'Vitruvius' do
75
+ # command 'ls'
76
+ # end
77
+ #
78
+ # Will set the name to "Vitruvius".
79
+ #
80
+ # This is also used in to_s to show the resource name, e.g. `execute[Vitruvius]`.
81
+ #
82
+ # This is also used for resource notifications and subscribes in the same manner.
83
+ #
84
+ # This will coerce any object into a string via #to_s. Arrays are a special case
85
+ # so that `package ["foo", "bar"]` becomes package[foo, bar] instead of the more
86
+ # awkward `package[["foo", "bar"]]` that #to_s would produce.
87
+ #
88
+ # @param name [Object] The name to set, typically a String or Array
89
+ # @return [String] The name of this Resource.
90
+ #
91
+ property :name, String, coerce: proc { |v| v.is_a?(Array) ? v.join(', ') : v.to_s }, desired_state: false
92
+
64
93
  #
65
94
  # The node the current Chef run is using.
66
95
  #
@@ -132,30 +161,6 @@ class Chef
132
161
  @sensitive = false
133
162
  end
134
163
 
135
- #
136
- # The list of properties defined on this resource.
137
- #
138
- # Everything defined with `property` is in this list.
139
- #
140
- # @param include_superclass [Boolean] `true` to include properties defined
141
- # on superclasses; `false` or `nil` to return the list of properties
142
- # directly on this class.
143
- #
144
- # @return [Hash<Symbol,Property>] The list of property names and types.
145
- #
146
- def self.properties(include_superclass=true)
147
- @properties ||= {}
148
- if include_superclass
149
- if superclass.respond_to?(:properties)
150
- superclass.properties.merge(@properties)
151
- else
152
- @properties.dup
153
- end
154
- else
155
- @properties
156
- end
157
- end
158
-
159
164
  #
160
165
  # The action or actions that will be taken when this resource is run.
161
166
  #
@@ -204,6 +209,8 @@ class Chef
204
209
  # actions have been run. This is the default.
205
210
  # - `immediate`, `immediately`: Will run the action on the other resource
206
211
  # immediately (before any other action is run).
212
+ # - `before`: Will run the action on the other resource
213
+ # immediately *before* the action is actually run.
207
214
  #
208
215
  # @example Resource by string
209
216
  # file '/foo.txt' do
@@ -246,9 +253,11 @@ class Chef
246
253
  notifies_delayed(action, resource)
247
254
  when 'immediate', 'immediately'
248
255
  notifies_immediately(action, resource)
256
+ when 'before'
257
+ notifies_before(action, resource)
249
258
  else
250
259
  raise ArgumentError, "invalid timing: #{timing} for notifies(#{action}, #{resources.inspect}, #{timing}) resource #{self} "\
251
- "Valid timings are: :delayed, :immediate, :immediately"
260
+ "Valid timings are: :delayed, :immediate, :immediately, :before"
252
261
  end
253
262
  end
254
263
 
@@ -272,6 +281,8 @@ class Chef
272
281
  # actions have been run. This is the default.
273
282
  # - `immediate`, `immediately`: The action will run immediately following
274
283
  # the other resource being updated.
284
+ # - `before`: The action will run immediately before the
285
+ # other resource is updated.
275
286
  #
276
287
  # @example Resources by string
277
288
  # file '/foo.txt' do
@@ -597,12 +608,26 @@ class Chef
597
608
  events.resource_failed(self, action, e)
598
609
  raise customize_exception(e)
599
610
  end
600
- ensure
601
- @elapsed_time = Time.now - start_time
602
- # Reporting endpoint doesn't accept a negative resource duration so set it to 0.
603
- # A negative value can occur when a resource changes the system time backwards
604
- @elapsed_time = 0 if @elapsed_time < 0
605
- events.resource_completed(self)
611
+ end
612
+ ensure
613
+ @elapsed_time = Time.now - start_time
614
+ # Reporting endpoint doesn't accept a negative resource duration so set it to 0.
615
+ # A negative value can occur when a resource changes the system time backwards
616
+ @elapsed_time = 0 if @elapsed_time < 0
617
+ events.resource_completed(self)
618
+ end
619
+
620
+ #
621
+ # If we are currently initializing the resource, this will be true.
622
+ #
623
+ # Do NOT use this. It may be removed. It is for internal purposes only.
624
+ # @api private
625
+ attr_reader :resource_initializing
626
+ def resource_initializing=(value)
627
+ if value
628
+ @resource_initializing = true
629
+ else
630
+ remove_instance_variable(:@resource_initializing)
606
631
  end
607
632
  end
608
633
 
@@ -660,13 +685,18 @@ class Chef
660
685
  end
661
686
 
662
687
  def to_hash
688
+ # Grab all current state, then any other ivars (backcompat)
689
+ result = {}
690
+ self.class.state_properties.each do |p|
691
+ result[p.name] = p.get(self)
692
+ end
663
693
  safe_ivars = instance_variables.map { |ivar| ivar.to_sym } - FORBIDDEN_IVARS
664
- instance_vars = Hash.new
665
694
  safe_ivars.each do |iv|
666
695
  key = iv.to_s.sub(/^@/,'').to_sym
667
- instance_vars[key] = instance_variable_get(iv)
696
+ next if result.has_key?(key)
697
+ result[key] = instance_variable_get(iv)
668
698
  end
669
- instance_vars
699
+ result
670
700
  end
671
701
 
672
702
  def self.json_create(o)
@@ -681,7 +711,6 @@ class Chef
681
711
  # Resource Definition Interface (for resource developers)
682
712
  #
683
713
 
684
- include Chef::Mixin::ParamsValidate
685
714
  include Chef::Mixin::Deprecation
686
715
 
687
716
  #
@@ -714,240 +743,6 @@ class Chef
714
743
  provider(arg)
715
744
  end
716
745
 
717
- #
718
- # Create a property on this resource class.
719
- #
720
- # If a superclass has this property, or if this property has already been
721
- # defined by this resource, this will *override* the previous value.
722
- #
723
- # @param name [Symbol] The name of the property.
724
- # @param type [Object,Array<Object>] The type(s) of this property.
725
- # If present, this is prepended to the `is` validation option.
726
- # @param options [Hash<Symbol,Object>] Validation options.
727
- # @option options [Object,Array] :is An object, or list of
728
- # objects, that must match the value using Ruby's `===` operator
729
- # (`options[:is].any? { |v| v === value }`).
730
- # @option options [Object,Array] :equal_to An object, or list
731
- # of objects, that must be equal to the value using Ruby's `==`
732
- # operator (`options[:is].any? { |v| v == value }`)
733
- # @option options [Regexp,Array<Regexp>] :regex An object, or
734
- # list of objects, that must match the value with `regex.match(value)`.
735
- # @option options [Class,Array<Class>] :kind_of A class, or
736
- # list of classes, that the value must be an instance of.
737
- # @option options [Hash<String,Proc>] :callbacks A hash of
738
- # messages -> procs, all of which match the value. The proc must
739
- # return a truthy or falsey value (true means it matches).
740
- # @option options [Symbol,Array<Symbol>] :respond_to A method
741
- # name, or list of method names, the value must respond to.
742
- # @option options [Symbol,Array<Symbol>] :cannot_be A property,
743
- # or a list of properties, that the value cannot have (such as `:nil` or
744
- # `:empty`). The method with a questionmark at the end is called on the
745
- # value (e.g. `value.empty?`). If the value does not have this method,
746
- # it is considered valid (i.e. if you don't respond to `empty?` we
747
- # assume you are not empty).
748
- # @option options [Proc] :coerce A proc which will be called to
749
- # transform the user input to canonical form. The value is passed in,
750
- # and the transformed value returned as output. Lazy values will *not*
751
- # be passed to this method until after they are evaluated. Called in the
752
- # context of the resource (meaning you can access other properties).
753
- # @option options [Boolean] :required `true` if this property
754
- # must be present; `false` otherwise. This is checked after the resource
755
- # is fully initialized.
756
- # @option options [Boolean] :name_property `true` if this
757
- # property defaults to the same value as `name`. Equivalent to
758
- # `default: lazy { name }`, except that #property_is_set? will
759
- # return `true` if the property is set *or* if `name` is set.
760
- # @option options [Boolean] :name_attribute Same as `name_property`.
761
- # @option options [Object] :default The value this property
762
- # will return if the user does not set one. If this is `lazy`, it will
763
- # be run in the context of the instance (and able to access other
764
- # properties).
765
- # @option options [Boolean] :desired_state `true` if this property is
766
- # part of desired state. Defaults to `true`.
767
- # @option options [Boolean] :identity `true` if this property
768
- # is part of object identity. Defaults to `false`.
769
- #
770
- # @example Bare property
771
- # property :x
772
- #
773
- # @example With just a type
774
- # property :x, String
775
- #
776
- # @example With just options
777
- # property :x, default: 'hi'
778
- #
779
- # @example With type and options
780
- # property :x, String, default: 'hi'
781
- #
782
- def self.property(name, type=NOT_PASSED, **options)
783
- name = name.to_sym
784
-
785
- options.each { |k,v| options[k.to_sym] = v if k.is_a?(String) }
786
-
787
- options[:instance_variable_name] = :"@#{name}" if !options.has_key?(:instance_variable_name)
788
- options.merge!(name: name, declared_in: self)
789
-
790
- if type == NOT_PASSED
791
- # If a type is not passed, the property derives from the
792
- # superclass property (if any)
793
- if properties.has_key?(name)
794
- property = properties[name].derive(**options)
795
- else
796
- property = property_type(**options)
797
- end
798
-
799
- # If a Property is specified, derive a new one from that.
800
- elsif type.is_a?(Property) || (type.is_a?(Class) && type <= Property)
801
- property = type.derive(**options)
802
-
803
- # If a primitive type was passed, combine it with "is"
804
- else
805
- if options[:is]
806
- options[:is] = ([ type ] + [ options[:is] ]).flatten(1)
807
- else
808
- options[:is] = type
809
- end
810
- property = property_type(**options)
811
- end
812
-
813
- local_properties = properties(false)
814
- local_properties[name] = property
815
-
816
- property.emit_dsl
817
- end
818
-
819
- #
820
- # Create a reusable property type that can be used in multiple properties
821
- # in different resources.
822
- #
823
- # @param options [Hash<Symbol,Object>] Validation options. see #property for
824
- # the list of options.
825
- #
826
- # @example
827
- # property_type(default: 'hi')
828
- #
829
- def self.property_type(**options)
830
- Property.derive(**options)
831
- end
832
-
833
- #
834
- # The name of this particular resource.
835
- #
836
- # This special resource attribute is set automatically from the declaration
837
- # of the resource, e.g.
838
- #
839
- # execute 'Vitruvius' do
840
- # command 'ls'
841
- # end
842
- #
843
- # Will set the name to "Vitruvius".
844
- #
845
- # This is also used in to_s to show the resource name, e.g. `execute[Vitruvius]`.
846
- #
847
- # This is also used for resource notifications and subscribes in the same manner.
848
- #
849
- # This will coerce any object into a string via #to_s. Arrays are a special case
850
- # so that `package ["foo", "bar"]` becomes package[foo, bar] instead of the more
851
- # awkward `package[["foo", "bar"]]` that #to_s would produce.
852
- #
853
- # @param name [Object] The name to set, typically a String or Array
854
- # @return [String] The name of this Resource.
855
- #
856
- property :name, String, coerce: proc { |v| v.is_a?(Array) ? v.join(', ') : v.to_s }, desired_state: false
857
-
858
- #
859
- # Whether this property has been set (or whether it has a default that has
860
- # been retrieved).
861
- #
862
- # @param name [Symbol] The name of the property.
863
- # @return [Boolean] `true` if the property has been set.
864
- #
865
- def property_is_set?(name)
866
- property = self.class.properties[name.to_sym]
867
- raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property
868
- property.is_set?(self)
869
- end
870
-
871
- #
872
- # Clear this property as if it had never been set. It will thereafter return
873
- # the default.
874
- # been retrieved).
875
- #
876
- # @param name [Symbol] The name of the property.
877
- #
878
- def reset_property(name)
879
- property = self.class.properties[name.to_sym]
880
- raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property
881
- property.reset(self)
882
- end
883
-
884
- #
885
- # Create a lazy value for assignment to a default value.
886
- #
887
- # @param block The block to run when the value is retrieved.
888
- #
889
- # @return [Chef::DelayedEvaluator] The lazy value
890
- #
891
- def self.lazy(&block)
892
- DelayedEvaluator.new(&block)
893
- end
894
-
895
- #
896
- # Get or set the list of desired state properties for this resource.
897
- #
898
- # State properties are properties that describe the desired state
899
- # of the system, such as file permissions or ownership.
900
- # In general, state properties are properties that could be populated by
901
- # examining the state of the system (e.g., File.stat can tell you the
902
- # permissions on an existing file). Contrarily, properties that are not
903
- # "state properties" usually modify the way Chef itself behaves, for example
904
- # by providing additional options for a package manager to use when
905
- # installing a package.
906
- #
907
- # This list is used by the Chef client auditing system to extract
908
- # information from resources to describe changes made to the system.
909
- #
910
- # This method is unnecessary when declaring properties with `property`;
911
- # properties are added to state_properties by default, and can be turned off
912
- # with `desired_state: false`.
913
- #
914
- # ```ruby
915
- # property :x # part of desired state
916
- # property :y, desired_state: false # not part of desired state
917
- # ```
918
- #
919
- # @param names [Array<Symbol>] A list of property names to set as desired
920
- # state.
921
- #
922
- # @return [Array<Property>] All properties in desired state.
923
- #
924
- def self.state_properties(*names)
925
- if !names.empty?
926
- names = names.map { |name| name.to_sym }.uniq
927
-
928
- local_properties = properties(false)
929
- # Add new properties to the list.
930
- names.each do |name|
931
- property = properties[name]
932
- if !property
933
- self.property name, instance_variable_name: false, desired_state: true
934
- elsif !property.desired_state?
935
- self.property name, desired_state: true
936
- end
937
- end
938
-
939
- # If state_attrs *excludes* something which is currently desired state,
940
- # mark it as desired_state: false.
941
- local_properties.each do |name,property|
942
- if property.desired_state? && !names.include?(name)
943
- self.property name, desired_state: false
944
- end
945
- end
946
- end
947
-
948
- properties.values.select { |property| property.desired_state? }
949
- end
950
-
951
746
  #
952
747
  # Set or return the list of "state properties" implemented by the Resource
953
748
  # subclass.
@@ -972,56 +767,6 @@ class Chef
972
767
  state_properties(*names).map { |property| property.name }
973
768
  end
974
769
 
975
- #
976
- # Set the identity of this resource to a particular set of properties.
977
- #
978
- # This drives #identity, which returns data that uniquely refers to a given
979
- # resource on the given node (in such a way that it can be correlated
980
- # across Chef runs).
981
- #
982
- # This method is unnecessary when declaring properties with `property`;
983
- # properties can be added to identity during declaration with
984
- # `identity: true`.
985
- #
986
- # ```ruby
987
- # property :x, identity: true # part of identity
988
- # property :y # not part of identity
989
- # ```
990
- #
991
- # If no properties are marked as identity, "name" is considered the identity.
992
- #
993
- # @param names [Array<Symbol>] A list of property names to set as the identity.
994
- #
995
- # @return [Array<Property>] All identity properties.
996
- #
997
- def self.identity_properties(*names)
998
- if !names.empty?
999
- names = names.map { |name| name.to_sym }
1000
-
1001
- # Add or change properties that are not part of the identity.
1002
- names.each do |name|
1003
- property = properties[name]
1004
- if !property
1005
- self.property name, instance_variable_name: false, identity: true
1006
- elsif !property.identity?
1007
- self.property name, identity: true
1008
- end
1009
- end
1010
-
1011
- # If identity_properties *excludes* something which is currently part of
1012
- # the identity, mark it as identity: false.
1013
- properties.each do |name,property|
1014
- if property.identity? && !names.include?(name)
1015
- self.property name, identity: false
1016
- end
1017
- end
1018
- end
1019
-
1020
- result = properties.values.select { |property| property.identity? }
1021
- result = [ properties[:name] ] if result.empty?
1022
- result
1023
- end
1024
-
1025
770
  #
1026
771
  # Set the identity of this resource to a particular property.
1027
772
  #
@@ -1513,6 +1258,9 @@ class Chef
1513
1258
  # resolve_resource_reference on each in turn, causing them to
1514
1259
  # resolve lazy/forward references.
1515
1260
  def resolve_notification_references
1261
+ run_context.before_notifications(self).each { |n|
1262
+ n.resolve_resource_reference(run_context.resource_collection)
1263
+ }
1516
1264
  run_context.immediate_notifications(self).each { |n|
1517
1265
  n.resolve_resource_reference(run_context.resource_collection)
1518
1266
  }
@@ -1521,6 +1269,11 @@ class Chef
1521
1269
  }
1522
1270
  end
1523
1271
 
1272
+ # Helper for #notifies
1273
+ def notifies_before(action, resource_spec)
1274
+ run_context.notifies_before(Notification.new(resource_spec, action, self))
1275
+ end
1276
+
1524
1277
  # Helper for #notifies
1525
1278
  def notifies_immediately(action, resource_spec)
1526
1279
  run_context.notifies_immediately(Notification.new(resource_spec, action, self))
@@ -1616,6 +1369,10 @@ class Chef
1616
1369
  "#{declared_type}[#{@name}]"
1617
1370
  end
1618
1371
 
1372
+ def before_notifications
1373
+ run_context.before_notifications(self)
1374
+ end
1375
+
1619
1376
  def immediate_notifications
1620
1377
  run_context.immediate_notifications(self)
1621
1378
  end