chef 10.28.2 → 10.30.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/lib/chef.rb +1 -0
  2. data/lib/chef/application/knife.rb +2 -0
  3. data/lib/chef/client.rb +1 -1
  4. data/lib/chef/config.rb +5 -1
  5. data/lib/chef/cookbook_uploader.rb +7 -14
  6. data/lib/chef/data_bag.rb +2 -3
  7. data/lib/chef/exceptions.rb +9 -1
  8. data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +4 -0
  9. data/lib/chef/knife.rb +3 -0
  10. data/lib/chef/mixin/deep_merge.rb +53 -21
  11. data/lib/chef/monkey_patches/net_http.rb +34 -0
  12. data/lib/chef/monkey_patches/uri.rb +70 -0
  13. data/lib/chef/node.rb +5 -5
  14. data/lib/chef/platform.rb +1 -0
  15. data/lib/chef/provider/cookbook_file.rb +14 -6
  16. data/lib/chef/provider/directory.rb +16 -10
  17. data/lib/chef/provider/file.rb +23 -17
  18. data/lib/chef/provider/group.rb +50 -31
  19. data/lib/chef/provider/group/dscl.rb +26 -4
  20. data/lib/chef/provider/group/gpasswd.rb +14 -19
  21. data/lib/chef/provider/group/groupadd.rb +41 -1
  22. data/lib/chef/provider/group/groupmod.rb +46 -36
  23. data/lib/chef/provider/group/pw.rb +59 -16
  24. data/lib/chef/provider/group/suse.rb +16 -13
  25. data/lib/chef/provider/group/usermod.rb +40 -18
  26. data/lib/chef/provider/group/windows.rb +13 -6
  27. data/lib/chef/provider/package/yum.rb +1 -0
  28. data/lib/chef/provider/remote_file.rb +8 -2
  29. data/lib/chef/provider/ruby_block.rb +1 -1
  30. data/lib/chef/provider/template.rb +11 -5
  31. data/lib/chef/provider/user/useradd.rb +9 -1
  32. data/lib/chef/provider/whyrun_safe_ruby_block.rb +30 -0
  33. data/lib/chef/providers.rb +1 -0
  34. data/lib/chef/resource/group.rb +11 -1
  35. data/lib/chef/resource/whyrun_safe_ruby_block.rb +31 -0
  36. data/lib/chef/resources.rb +1 -0
  37. data/lib/chef/rest.rb +6 -2
  38. data/lib/chef/rest/rest_request.rb +6 -2
  39. data/lib/chef/util/windows/net_group.rb +5 -1
  40. data/lib/chef/version.rb +1 -1
  41. data/spec/functional/resource/base.rb +40 -0
  42. data/spec/functional/resource/group_spec.rb +343 -0
  43. data/spec/spec_helper.rb +4 -0
  44. data/spec/support/platform_helpers.rb +17 -0
  45. data/spec/unit/client_spec.rb +1 -1
  46. data/spec/unit/data_bag_spec.rb +4 -6
  47. data/spec/unit/mixin/deep_merge_spec.rb +416 -190
  48. data/spec/unit/monkey_patches/uri_spec.rb +34 -0
  49. data/spec/unit/node/attribute_spec.rb +49 -14
  50. data/spec/unit/node_spec.rb +31 -0
  51. data/spec/unit/provider/file_spec.rb +27 -27
  52. data/spec/unit/provider/group/dscl_spec.rb +1 -0
  53. data/spec/unit/provider/group/gpasswd_spec.rb +16 -9
  54. data/spec/unit/provider/group/groupadd_spec.rb +3 -4
  55. data/spec/unit/provider/group/groupmod_spec.rb +0 -1
  56. data/spec/unit/provider/group/pw_spec.rb +12 -15
  57. data/spec/unit/provider/group/usermod_spec.rb +21 -6
  58. data/spec/unit/provider/group/windows_spec.rb +0 -8
  59. data/spec/unit/provider/group_spec.rb +26 -4
  60. data/spec/unit/provider/user/useradd_spec.rb +21 -0
  61. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +47 -0
  62. data/spec/unit/rest_spec.rb +55 -22
  63. metadata +119 -44
  64. checksums.yaml +0 -7
data/lib/chef.rb CHANGED
@@ -39,3 +39,4 @@ require 'chef/monkey_patches/dir'
39
39
  require 'chef/monkey_patches/string'
40
40
  require 'chef/monkey_patches/numeric'
41
41
  require 'chef/monkey_patches/object'
42
+ require 'chef/monkey_patches/uri'
@@ -19,6 +19,8 @@ require 'chef/knife'
19
19
  require 'chef/application'
20
20
  require 'mixlib/log'
21
21
  require 'ohai/config'
22
+ require 'chef/monkey_patches/net_http.rb'
23
+ require 'chef/monkey_patches/uri.rb'
22
24
 
23
25
  class Chef::Application::Knife < Chef::Application
24
26
 
data/lib/chef/client.rb CHANGED
@@ -160,7 +160,7 @@ class Chef
160
160
  # === Returns
161
161
  # boolean:: Return value from #do_run. Should always returns true.
162
162
  def run
163
- if(Chef::Config[:client_fork] && Process.respond_to?(:fork))
163
+ if(Chef::Config[:client_fork] && Process.respond_to?(:fork) && !Chef::Platform.windows?)
164
164
  Chef::Log.info "Forking chef instance to converge..."
165
165
  pid = fork do
166
166
  Chef::Log.info "Forked instance now converging"
data/lib/chef/config.rb CHANGED
@@ -204,7 +204,7 @@ class Chef
204
204
  client_fork false
205
205
  enable_reporting true
206
206
  enable_reporting_url_fatals false
207
-
207
+
208
208
  # Set these to enable SSL authentication / mutual-authentication
209
209
  # with the server
210
210
  ssl_client_cert nil
@@ -326,5 +326,9 @@ class Chef
326
326
  # returns a platform specific path to the user home dir
327
327
  windows_home_path = ENV['SYSTEMDRIVE'] + ENV['HOMEPATH'] if ENV['SYSTEMDRIVE'] && ENV['HOMEPATH']
328
328
  user_home (ENV['HOME'] || windows_home_path || ENV['USERPROFILE'])
329
+
330
+ # CHEF-4631
331
+ # Enables the concatanation behavior instead of merging
332
+ deep_merge_array_concat true
329
333
  end
330
334
  end
@@ -134,24 +134,17 @@ class Chef
134
134
  # but we need the base64 encoding for the content-md5
135
135
  # header
136
136
  checksum64 = Base64.encode64([checksum].pack("H*")).strip
137
- timestamp = Time.now.utc.iso8601
138
137
  file_contents = File.open(file, "rb") {|f| f.read}
139
- # TODO - 5/28/2010, cw: make signing and sending the request streaming
140
- sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(
141
- :http_method => :put,
142
- :path => URI.parse(url).path,
143
- :body => file_contents,
144
- :timestamp => timestamp,
145
- :user_id => rest.client_name
146
- )
147
- headers = { 'content-type' => 'application/x-binary', 'content-md5' => checksum64, :accept => 'application/json' }
148
- headers.merge!(sign_obj.sign(OpenSSL::PKey::RSA.new(rest.signing_key)))
138
+ headers = { 'content-type' => 'application/x-binary', 'content-md5' => checksum64, 'accept' => 'application/json' }
149
139
 
150
140
  begin
151
- RestClient::Resource.new(url, :headers=>headers, :timeout=>1800, :open_timeout=>1800).put(file_contents)
141
+ url = rest.create_url(url)
142
+ rest.raw_http_request(:PUT, url, headers, file_contents)
152
143
  checksums_to_upload.delete(checksum)
153
- rescue RestClient::Exception => e
154
- Chef::Knife.ui.error("Failed to upload #@cookbook : #{e.message}\n#{e.response.body}")
144
+ rescue Net::HTTPServerException, Net::HTTPFatalError, Errno::ECONNREFUSED, Timeout::Error, Errno::ETIMEDOUT, SocketError => e
145
+ error_message = "Failed to upload #{file} (#{checksum}) to #{url} : #{e.message}"
146
+ error_message << "\n#{e.response.body}" if e.respond_to?(:response)
147
+ Chef::Knife.ui.error(error_message)
155
148
  raise
156
149
  end
157
150
  end
data/lib/chef/data_bag.rb CHANGED
@@ -196,11 +196,10 @@ class Chef
196
196
  if Chef::Config[:why_run]
197
197
  Chef::Log.warn("In whyrun mode, so NOT performing data bag save.")
198
198
  else
199
- chef_server_rest.put_rest("data/#{@name}", self)
199
+ create
200
200
  end
201
201
  rescue Net::HTTPServerException => e
202
- raise e unless e.response.code == "404"
203
- chef_server_rest.post_rest("data", self)
202
+ raise e unless e.response.code == "409"
204
203
  end
205
204
  self
206
205
  end
@@ -62,6 +62,7 @@ class Chef
62
62
  class DsclCommandFailed < RuntimeError; end
63
63
  class UserIDNotFound < ArgumentError; end
64
64
  class GroupIDNotFound < ArgumentError; end
65
+ class ConflictingMembersInGroup < ArgumentError; end
65
66
  class InvalidResourceReference < RuntimeError; end
66
67
  class ResourceNotFound < RuntimeError; end
67
68
  class InvalidResourceSpecification < ArgumentError; end
@@ -187,6 +188,13 @@ class Chef
187
188
  result.to_json(*a)
188
189
  end
189
190
  end
190
- end
191
+ end # CookbookVersionSelection
192
+
193
+ # When the server sends a redirect, RFC 2616 states a user-agent should
194
+ # not follow it with a method other than GET or HEAD, unless a specific
195
+ # action is taken by the user. A redirect received as response to a
196
+ # non-GET and non-HEAD request will thus raise an InvalidRedirect.
197
+ class InvalidRedirect < StandardError; end
198
+
191
199
  end
192
200
  end
@@ -40,6 +40,10 @@ readable by chef-client.
40
40
  E
41
41
  error_description.section("Relevant Config Settings:",<<-E)
42
42
  validation_key "#{api_key}"
43
+ E
44
+ when Chef::Exceptions::InvalidRedirect
45
+ error_description.section("Invalid Redirect:",<<-E)
46
+ Change your server location in client.rb to the server's FQDN to avoid unwanted redirections.
43
47
  E
44
48
  else
45
49
  "#{exception.class.name}: #{exception.message}"
data/lib/chef/knife.rb CHANGED
@@ -429,6 +429,9 @@ class Chef
429
429
  when Chef::Exceptions::PrivateKeyMissing
430
430
  ui.error "Your private key could not be loaded from #{api_key}"
431
431
  ui.info "Check your configuration file and ensure that your private key is readable"
432
+ when Chef::Exceptions::InvalidRedirect
433
+ ui.error "Invalid Redirect: #{e.message}"
434
+ ui.info "Change your server location in knife.rb to the server's FQDN to avoid unwanted redirections."
432
435
  else
433
436
  ui.error "#{e.class.name}: #{e.message}"
434
437
  end
@@ -8,9 +8,9 @@
8
8
  # Licensed under the Apache License, Version 2.0 (the "License");
9
9
  # you may not use this file except in compliance with the License.
10
10
  # You may obtain a copy of the License at
11
- #
11
+ #
12
12
  # http://www.apache.org/licenses/LICENSE-2.0
13
- #
13
+ #
14
14
  # Unless required by applicable law or agreed to in writing, software
15
15
  # distributed under the License is distributed on an "AS IS" BASIS,
16
16
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -35,17 +35,24 @@ class Chef
35
35
  DeepMerge.deep_merge(second, first, {:preserve_unmergeables => false})
36
36
  end
37
37
 
38
+ def horizontal_merge(first, second)
39
+ first = Mash.new(first) unless first.kind_of?(Mash)
40
+ second = Mash.new(second) unless second.kind_of?(Mash)
41
+
42
+ DeepMerge.deep_merge(second, first, {:preserve_unmergeables => false, :horizontal_precedence => true})
43
+ end
44
+
38
45
  # Inherited roles use the knockout_prefix array subtraction functionality
39
46
  # This is likely to go away in Chef >= 0.11
40
47
  def role_merge(first, second)
41
48
  first = Mash.new(first) unless first.kind_of?(Mash)
42
49
  second = Mash.new(second) unless second.kind_of?(Mash)
43
50
 
44
- DeepMerge.deep_merge(second, first, {:knockout_prefix => "!merge", :preserve_unmergeables => false})
51
+ DeepMerge.deep_merge(second, first, {:preserve_unmergeables => false, :knockout_prefix => "!merge", :horizontal_precedence => true})
45
52
  end
46
-
53
+
47
54
  class InvalidParameter < StandardError; end
48
-
55
+
49
56
  # Deep Merge core documentation.
50
57
  # deep_merge! method permits merging of arbitrary child elements. The two top level
51
58
  # elements must be hashes. These hashes can contain unlimited (to stack limit) levels
@@ -60,7 +67,7 @@ class Chef
60
67
  # Results: {:x => [1,2,3,4,5,'6'], :y => 2}
61
68
  # By default, "deep_merge!" will overwrite any unmergeables and merge everything else.
62
69
  # To avoid this, use "deep_merge" (no bang/exclamation mark)
63
- #
70
+ #
64
71
  # Options:
65
72
  # Options are specified in the last parameter passed, which should be in hash format:
66
73
  # hash.deep_merge!({:x => [1,2]}, {:knockout_prefix => '!merge'})
@@ -78,7 +85,7 @@ class Chef
78
85
  # Set to true to get console output of merge process for debugging
79
86
  #
80
87
  # Selected Options Details:
81
- # :knockout_prefix => The purpose of this is to provide a way to remove elements
88
+ # :knockout_prefix => The purpose of this is to provide a way to remove elements
82
89
  # from existing Hash by specifying them in a special way in incoming hash
83
90
  # source = {:x => ['!merge:1', '2']}
84
91
  # dest = {:x => ['1', '3']}
@@ -96,9 +103,9 @@ class Chef
96
103
  # dest = {:x => ['5','6','7,8']}
97
104
  # dest.deep_merge!(source, {:unpack_arrays => ','})
98
105
  # Results: {:x => ['1','2','3','4','5','6','7','8'}
99
- # Why: If receiving data from an HTML form, this makes it easy for a checkbox
106
+ # Why: If receiving data from an HTML form, this makes it easy for a checkbox
100
107
  # to pass multiple values from within a single HTML element
101
- #
108
+ #
102
109
  # There are many tests for this library - and you can learn more about the features
103
110
  # and usages of deep_merge! by just browsing the test examples
104
111
  def deep_merge!(source, dest, options = {})
@@ -131,13 +138,15 @@ class Chef
131
138
  dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(:debug_indent => di + ' '))
132
139
  else # dest[src_key] doesn't exist so we want to create and overwrite it (but we do this via deep_merge!)
133
140
  puts "#{di} ==>merging over: #{src_key.inspect} => #{src_value.inspect}" if merge_debug
134
- # note: we rescue here b/c some classes respond to "dup" but don't implement it (Numeric, TrueClass, FalseClass, NilClass among maybe others)
135
- begin
136
- src_dup = src_value.dup # we dup src_value if possible because we're going to merge into it (since dest is empty)
137
- rescue TypeError
138
- src_dup = src_value
139
- end
140
- dest[src_key] = deep_merge!(src_value, src_dup, options.merge(:debug_indent => di + ' '))
141
+ # NOTE: We are doing this via deep_merge! because the
142
+ # src_value can still contain merge directives such as
143
+ # knockout_prefix.
144
+ # Historically we have been dup'ing the src_value here
145
+ # and merging src_value with src_value.dup. This logic
146
+ # is not applicable anymore because it results in
147
+ # duplicates when merging two array values with
148
+ # :horizontal_precedence = true.
149
+ dest[src_key] = deep_merge!(src_value, { }, options.merge(:debug_indent => di + ' '))
141
150
  end
142
151
  else # dest isn't a hash, so we overwrite it completely (if permitted)
143
152
  if overwrite_unmergeable
@@ -181,7 +190,30 @@ class Chef
181
190
  puts if merge_debug
182
191
  end
183
192
  puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
184
- dest = dest | source
193
+ # Behavior of merging arrays has changed with CHEF-4631.
194
+ # Old behavior was to deduplicate and merge the
195
+ # arrays. New behavior is to concatanate the arrays if the
196
+ # merge is happening on the same attribute precedence
197
+ # level and pick the value from the higher precedence
198
+ # level if merge is being done across the precedence
199
+ # levels.
200
+ # Old behavior can still be used by setting
201
+ # :deep_merge_array_concat to false in config.
202
+ if Chef::Config[:deep_merge_array_concat]
203
+ # If :horizontal_precedence is set, this means we are
204
+ # merging two arrays at the same precendence level so
205
+ # concatanate them. Otherwise this is a merge across
206
+ # precedence levels which means we will pick the one
207
+ # from higher precedence level.
208
+ if options[:horizontal_precedence]
209
+ dest += source
210
+ else
211
+ dest = source
212
+ end
213
+ else
214
+ # Pre CHEF-4631 behavior for array merging
215
+ dest = dest | source
216
+ end
185
217
  dest.sort! if sort_merged_arrays
186
218
  elsif overwrite_unmergeable
187
219
  puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
@@ -194,7 +226,7 @@ class Chef
194
226
  puts "#{di}Returning #{dest.inspect}" if merge_debug
195
227
  dest
196
228
  end # deep_merge!
197
-
229
+
198
230
  # allows deep_merge! to uniformly handle overwriting of unmergeable entities
199
231
  def overwrite_unmergeables(source, dest, options)
200
232
  merge_debug = options[:merge_debug] || false
@@ -229,7 +261,7 @@ class Chef
229
261
  def deep_merge(source, dest, options = {})
230
262
  deep_merge!(source.dup, dest.dup, options)
231
263
  end
232
-
264
+
233
265
  def clear_or_nil(obj)
234
266
  if obj.respond_to?(:clear)
235
267
  obj.clear
@@ -238,9 +270,9 @@ class Chef
238
270
  end
239
271
  obj
240
272
  end
241
-
273
+
242
274
  end
243
-
275
+
244
276
  end
245
277
  end
246
278
 
@@ -20,3 +20,37 @@ module Net
20
20
  include ChefNetHTTPExceptionExtensions
21
21
  end
22
22
  end
23
+
24
+ if Net::HTTP.instance_methods.map {|m| m.to_s}.include?("proxy_uri")
25
+ begin
26
+ # Ruby 2.0 changes the way proxy support is implemented in Net::HTTP.
27
+ # The implementation does not work correctly with IPv6 literals because it
28
+ # concatenates the address into a URI without adding square brackets for
29
+ # IPv6 addresses.
30
+ #
31
+ # If the bug is present, a call to Net::HTTP#proxy_uri when the host is an
32
+ # IPv6 address will fail by creating an invalid URI, like so:
33
+ #
34
+ # ruby -r'net/http' -e 'Net::HTTP.new("::1", 80).proxy_uri'
35
+ # /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:214:in `initialize': the scheme http does not accept registry part: ::1:80 (or bad hostname?) (URI::InvalidURIError)
36
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:84:in `initialize'
37
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:214:in `new'
38
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:214:in `parse'
39
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:747:in `parse'
40
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:994:in `URI'
41
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1027:in `proxy_uri'
42
+ # from -e:1:in `<main>'
43
+ #
44
+ # https://bugs.ruby-lang.org/issues/9129
45
+ Net::HTTP.new("::1", 80).proxy_uri
46
+ rescue URI::InvalidURIError
47
+ class Net::HTTP
48
+
49
+ def proxy_uri # :nodoc:
50
+ ipv6_safe_addr = address.to_s.include?(":") ? "[#{address}]" : address
51
+ @proxy_uri ||= URI("http://#{ipv6_safe_addr}:#{port}").find_proxy
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,70 @@
1
+ # Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ # You can redistribute it and/or modify it under either the terms of the
3
+ # 2-clause BSDL (see the file BSDL), or the conditions below:
4
+ #
5
+ # 1. You may make and give away verbatim copies of the source form of the
6
+ # software without restriction, provided that you duplicate all of the
7
+ # original copyright notices and associated disclaimers.
8
+ #
9
+ # 2. You may modify your copy of the software in any way, provided that
10
+ # you do at least ONE of the following:
11
+ #
12
+ # a) place your modifications in the Public Domain or otherwise
13
+ # make them Freely Available, such as by posting said
14
+ # modifications to Usenet or an equivalent medium, or by allowing
15
+ # the author to include your modifications in the software.
16
+ #
17
+ # b) use the modified software only within your corporation or
18
+ # organization.
19
+ #
20
+ # c) give non-standard binaries non-standard names, with
21
+ # instructions on where to get the original software distribution.
22
+ #
23
+ # d) make other distribution arrangements with the author.
24
+ #
25
+ # 3. You may distribute the software in object code or binary form,
26
+ # provided that you do at least ONE of the following:
27
+ #
28
+ # a) distribute the binaries and library files of the software,
29
+ # together with instructions (in the manual page or equivalent)
30
+ # on where to get the original distribution.
31
+ #
32
+ # b) accompany the distribution with the machine-readable source of
33
+ # the software.
34
+ #
35
+ # c) give non-standard binaries non-standard names, with
36
+ # instructions on where to get the original software distribution.
37
+ #
38
+ # d) make other distribution arrangements with the author.
39
+ #
40
+ # 4. You may modify and include the part of the software into any other
41
+ # software (possibly commercial). But some files in the distribution
42
+ # are not written by the author, so that they are not under these terms.
43
+ #
44
+ # For the list of those files and their copying conditions, see the
45
+ # file LEGAL.
46
+ #
47
+ # 5. The scripts and library files supplied as input to or produced as
48
+ # output from the software do not automatically fall under the
49
+ # copyright of the software, but belong to whomever generated them,
50
+ # and may be sold commercially, and may be aggregated with this
51
+ # software.
52
+ #
53
+ # 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ # PURPOSE.
57
+
58
+ require 'uri'
59
+
60
+ unless URI::Generic.instance_methods.map {|m| m.to_s}.include?("hostname")
61
+
62
+ class URI::Generic
63
+ # Copied from the MRI source for Ruby 1.9.3
64
+ # File lib/uri/generic.rb, line 659
65
+ def hostname
66
+ v = self.host
67
+ /\A\[(.*)\]\z/ =~ v ? $1 : v
68
+ end
69
+ end
70
+ end
data/lib/chef/node.rb CHANGED
@@ -391,7 +391,7 @@ class Chef
391
391
  def consume_attributes(attrs)
392
392
  normal_attrs_to_merge = consume_run_list(attrs)
393
393
  Chef::Log.debug("Applying attributes from json file")
394
- @normal_attrs = Chef::Mixin::DeepMerge.merge(@normal_attrs,normal_attrs_to_merge)
394
+ @normal_attrs = Chef::Mixin::DeepMerge.horizontal_merge(@normal_attrs,normal_attrs_to_merge)
395
395
  self.tags # make sure they're defined
396
396
  end
397
397
 
@@ -450,11 +450,11 @@ class Chef
450
450
  def apply_expansion_attributes(expansion)
451
451
  load_chef_environment_object = (chef_environment == "_default" ? nil : Chef::Environment.load(chef_environment))
452
452
  environment_default_attrs = load_chef_environment_object.nil? ? {} : load_chef_environment_object.default_attributes
453
- default_before_roles = Chef::Mixin::DeepMerge.merge(default_attrs, environment_default_attrs)
454
- @default_attrs = Chef::Mixin::DeepMerge.merge(default_before_roles, expansion.default_attrs)
453
+ default_before_roles = Chef::Mixin::DeepMerge.horizontal_merge(default_attrs, environment_default_attrs)
454
+ @default_attrs = Chef::Mixin::DeepMerge.horizontal_merge(default_before_roles, expansion.default_attrs)
455
455
  environment_override_attrs = load_chef_environment_object.nil? ? {} : load_chef_environment_object.override_attributes
456
- overrides_before_environments = Chef::Mixin::DeepMerge.merge(override_attrs, expansion.override_attrs)
457
- @override_attrs = Chef::Mixin::DeepMerge.merge(overrides_before_environments, environment_override_attrs)
456
+ overrides_before_environments = Chef::Mixin::DeepMerge.horizontal_merge(override_attrs, expansion.override_attrs)
457
+ @override_attrs = Chef::Mixin::DeepMerge.horizontal_merge(overrides_before_environments, environment_override_attrs)
458
458
  end
459
459
 
460
460
  # Transform the node to a Hash
data/lib/chef/platform.rb CHANGED
@@ -331,6 +331,7 @@ class Chef
331
331
  :route => Chef::Provider::Route,
332
332
  :ifconfig => Chef::Provider::Ifconfig,
333
333
  :ruby_block => Chef::Provider::RubyBlock,
334
+ :whyrun_safe_ruby_block => Chef::Provider::WhyrunSafeRubyBlock,
334
335
  :erl_call => Chef::Provider::ErlCall,
335
336
  :log => Chef::Provider::Log::ChefLog
336
337
  }
@@ -33,7 +33,7 @@ class Chef
33
33
  end
34
34
 
35
35
  def action_create
36
- if file_cache_location && content_stale?
36
+ if file_cache_location && content_stale?
37
37
  description = []
38
38
  description << "create a new cookbook_file #{@new_resource.path}"
39
39
  description << diff_current(file_cache_location)
@@ -83,22 +83,30 @@ class Chef
83
83
  # On the Windows platform, files in the temp directory
84
84
  # default to not inherit unless the new resource specifies rights of
85
85
  # some sort. Here we ensure that even when no rights are
86
- # specified, the dacl's inheritance flag is set.
86
+ # specified, the dacl's inheritance flag is set.
87
87
  if Chef::Platform.windows? &&
88
88
  @new_resource.rights.nil? &&
89
89
  @new_resource.group.nil? &&
90
90
  @new_resource.owner.nil? &&
91
91
  @new_resource.deny_rights.nil?
92
-
92
+
93
93
  securable_tempfile = Chef::ReservedNames::Win32::Security::SecurableObject.new(tempfile_path)
94
94
 
95
95
  # No rights were specified, so the dacl will have no explicit aces
96
96
  default_dacl = Chef::ReservedNames::Win32::Security::ACL.create([])
97
97
 
98
- # In setting this default dacl, set inheritance to true
98
+ # In setting this default dacl, set inheritance to true
99
99
  securable_tempfile.set_dacl(default_dacl, true)
100
- end
101
- end
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ def managing_content?
106
+ return true if @new_resource.checksum
107
+ return true if !@new_resource.source.nil? && @action != :create_if_missing
108
+ false
109
+ end
102
110
 
103
111
  end
104
112
  end