chef 12.15.19-universal-mingw32 → 12.16.42-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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/VERSION +1 -1
  4. data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +3 -1
  5. data/acceptance/Gemfile.lock +14 -14
  6. data/acceptance/data-collector/test/integration/default/serverspec/default_spec.rb +3 -11
  7. data/distro/common/html/knife_bootstrap.html +1 -1
  8. data/distro/common/man/man1/README.md +2 -2
  9. data/distro/common/man/man1/knife-client.1 +1 -1
  10. data/lib/chef/application.rb +7 -15
  11. data/lib/chef/application/client.rb +2 -2
  12. data/lib/chef/application/solo.rb +1 -1
  13. data/lib/chef/chef_class.rb +1 -0
  14. data/lib/chef/chef_fs/file_system/chef_server/cookbook_file.rb +3 -7
  15. data/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb +1 -1
  16. data/lib/chef/data_collector.rb +83 -9
  17. data/lib/chef/data_collector/messages.rb +2 -1
  18. data/lib/chef/dsl/core.rb +1 -1
  19. data/lib/chef/dsl/declare_resource.rb +10 -4
  20. data/lib/chef/dsl/method_missing.rb +1 -1
  21. data/lib/chef/dsl/recipe.rb +1 -1
  22. data/lib/chef/dsl/universal.rb +1 -1
  23. data/lib/chef/event_dispatch/base.rb +3 -0
  24. data/lib/chef/http.rb +3 -4
  25. data/lib/chef/knife.rb +20 -2
  26. data/lib/chef/knife/core/generic_presenter.rb +18 -4
  27. data/lib/chef/knife/node_show.rb +0 -5
  28. data/lib/chef/knife/osc_user_show.rb +0 -1
  29. data/lib/chef/knife/ssl_fetch.rb +9 -5
  30. data/lib/chef/mixin/powershell_out.rb +1 -1
  31. data/lib/chef/mixin/shell_out.rb +1 -1
  32. data/lib/chef/node.rb +1 -5
  33. data/lib/chef/node/attribute.rb +70 -98
  34. data/lib/chef/node/attribute_collections.rb +28 -19
  35. data/lib/chef/node/common_api.rb +0 -6
  36. data/lib/chef/node/immutable_collections.rb +16 -79
  37. data/lib/chef/node/mixin/deep_merge_cache.rb +61 -0
  38. data/lib/chef/node/mixin/immutablize_array.rb +67 -0
  39. data/lib/chef/node/mixin/immutablize_hash.rb +54 -0
  40. data/lib/chef/node/mixin/state_tracking.rb +93 -0
  41. data/lib/chef/property.rb +4 -4
  42. data/lib/chef/provider/cron.rb +1 -1
  43. data/lib/chef/provider/group/suse.rb +23 -4
  44. data/lib/chef/provider/package.rb +43 -5
  45. data/lib/chef/provider/package/apt.rb +20 -0
  46. data/lib/chef/provider/package/windows/exe.rb +4 -3
  47. data/lib/chef/provider/package/windows/msi.rb +4 -3
  48. data/lib/chef/provider/package/yum.rb +20 -0
  49. data/lib/chef/provider/package/zypper.rb +20 -0
  50. data/lib/chef/provider/ruby_block.rb +1 -1
  51. data/lib/chef/provider/service/upstart.rb +25 -9
  52. data/lib/chef/provider/user.rb +4 -6
  53. data/lib/chef/provider/user/dscl.rb +8 -3
  54. data/lib/chef/provider/user/solaris.rb +5 -12
  55. data/lib/chef/resource.rb +19 -0
  56. data/lib/chef/resource/file.rb +1 -1
  57. data/lib/chef/resource/package.rb +1 -1
  58. data/lib/chef/resource/scm.rb +1 -7
  59. data/lib/chef/resource/yum_repository.rb +1 -1
  60. data/lib/chef/rest.rb +1 -0
  61. data/lib/chef/run_context.rb +12 -0
  62. data/lib/chef/version.rb +1 -1
  63. data/spec/data/trusted_certs/example_no_cn.crt +36 -0
  64. data/spec/functional/resource/group_spec.rb +1 -0
  65. data/spec/functional/resource/user/useradd_spec.rb +4 -2
  66. data/spec/integration/knife/data_bag_create_spec.rb +0 -3
  67. data/spec/integration/knife/environment_show_spec.rb +24 -4
  68. data/spec/integration/knife/node_environment_set_spec.rb +4 -1
  69. data/spec/integration/recipes/accumulator_spec.rb +232 -0
  70. data/spec/integration/recipes/resource_action_spec.rb +1 -1
  71. data/spec/spec_helper.rb +2 -2
  72. data/spec/support/shared/context/client.rb +12 -3
  73. data/spec/support/shared/integration/app_server_support.rb +1 -1
  74. data/spec/support/shared/integration/knife_support.rb +4 -1
  75. data/spec/unit/data_collector/messages_spec.rb +2 -0
  76. data/spec/unit/data_collector_spec.rb +158 -21
  77. data/spec/unit/http_spec.rb +1 -1
  78. data/spec/unit/knife/core/gem_glob_loader_spec.rb +1 -1
  79. data/spec/unit/knife/core/ui_spec.rb +10 -0
  80. data/spec/unit/knife/ssl_fetch_spec.rb +38 -0
  81. data/spec/unit/knife_spec.rb +31 -0
  82. data/spec/unit/mixin/powershell_out_spec.rb +25 -1
  83. data/spec/unit/node/attribute_spec.rb +46 -1
  84. data/spec/unit/node/vivid_mash_spec.rb +27 -89
  85. data/spec/unit/node_spec.rb +134 -3
  86. data/spec/unit/provider/deploy_spec.rb +1 -1
  87. data/spec/unit/provider/group/suse_spec.rb +90 -0
  88. data/spec/unit/provider/package/apt_spec.rb +22 -0
  89. data/spec/unit/provider/package/windows/msi_spec.rb +13 -4
  90. data/spec/unit/provider/package/windows_spec.rb +3 -3
  91. data/spec/unit/provider/package/yum_spec.rb +18 -0
  92. data/spec/unit/provider/package/zypper_spec.rb +64 -0
  93. data/spec/unit/provider/package_spec.rb +58 -0
  94. data/spec/unit/provider/remote_file/content_spec.rb +1 -1
  95. data/spec/unit/provider/service/upstart_service_spec.rb +13 -6
  96. data/spec/unit/provider/user/solaris_spec.rb +36 -9
  97. data/spec/unit/provider/user_spec.rb +6 -0
  98. data/spec/unit/resource/apt_repository_spec.rb +1 -1
  99. metadata +12 -5
@@ -66,7 +66,7 @@ class Chef
66
66
  "entity_uuid" => node_uuid,
67
67
  "expanded_run_list" => reporter_data[:expanded_run_list],
68
68
  "id" => run_status.run_id,
69
- "message_version" => "1.0.0",
69
+ "message_version" => "1.1.0",
70
70
  "message_type" => "run_converge",
71
71
  "node" => run_status.node,
72
72
  "node_name" => run_status.node.name,
@@ -80,6 +80,7 @@ class Chef
80
80
  "status" => reporter_data[:status],
81
81
  "total_resource_count" => reporter_data[:resources].count,
82
82
  "updated_resource_count" => reporter_data[:resources].select { |r| r.report_data["status"] == "updated" }.count,
83
+ "deprecations" => reporter_data[:deprecations],
83
84
  }
84
85
 
85
86
  message["error"] = {
@@ -1,7 +1,7 @@
1
1
  #--
2
2
  # Author:: Adam Jacob (<adam@chef.io>)
3
3
  # Author:: Christopher Walters (<cw@chef.io>)
4
- # Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
4
+ # Copyright:: Copyright 2008-2016 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,7 +1,7 @@
1
1
  #--
2
2
  # Author:: Adam Jacob (<adam@chef.io>)
3
3
  # Author:: Christopher Walters
4
- # Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
4
+ # Copyright:: Copyright 2008-2016 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -47,7 +47,7 @@ class Chef
47
47
  when Chef::RunContext
48
48
  rc
49
49
  when :root
50
- Chef.run_context
50
+ run_context.root_run_context
51
51
  when :parent
52
52
  run_context.parent_run_context
53
53
  else
@@ -119,7 +119,13 @@ class Chef
119
119
  #
120
120
  def edit_resource!(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block)
121
121
  resource = find_resource!(type, name, run_context: run_context)
122
- resource.instance_eval(&resource_attrs_block) if block_given?
122
+ if resource_attrs_block
123
+ if defined?(new_resource)
124
+ resource.instance_exec(new_resource, &resource_attrs_block)
125
+ else
126
+ resource.instance_exec(&resource_attrs_block)
127
+ end
128
+ end
123
129
  resource
124
130
  end
125
131
 
@@ -200,7 +206,7 @@ class Chef
200
206
  def find_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block)
201
207
  find_resource!(type, name, run_context: run_context)
202
208
  rescue Chef::Exceptions::ResourceNotFound
203
- if block_given?
209
+ if resource_attrs_block
204
210
  declare_resource(type, name, created_at, run_context: run_context, &resource_attrs_block)
205
211
  end # returns nil otherwise
206
212
  end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
2
+ # Copyright:: Copyright 2008-2016 Chef Software, Inc.
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,7 +1,7 @@
1
1
  #--
2
2
  # Author:: Adam Jacob (<adam@chef.io>)
3
3
  # Author:: Christopher Walters (<cw@chef.io>)
4
- # Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
4
+ # Copyright:: Copyright 2008-2016 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,7 +1,7 @@
1
1
  #--
2
2
  # Author:: Adam Jacob (<adam@chef.io>)
3
3
  # Author:: Christopher Walters (<cw@chef.io>)
4
- # Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc.
4
+ # Copyright:: Copyright 2008-2016 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -421,6 +421,9 @@ class Chef
421
421
  def msg(message)
422
422
  end
423
423
 
424
+ # Called when an attribute is changed by simple assignment
425
+ def attribute_changed(precedence, keys, value)
426
+ end
424
427
  end
425
428
  end
426
429
  end
@@ -5,7 +5,7 @@
5
5
  # Author:: Christopher Brown (<cb@chef.io>)
6
6
  # Author:: Christopher Walters (<cw@chef.io>)
7
7
  # Author:: Daniel DeLeo (<dan@chef.io>)
8
- # Copyright:: Copyright 2009-2016, 2013-2015 Chef Software, Inc.
8
+ # Copyright:: Copyright 2009-2016 Chef Software, Inc.
9
9
  # License:: Apache License, Version 2.0
10
10
  #
11
11
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -329,10 +329,9 @@ class Chef
329
329
  # Runs a synchronous HTTP request, with no middleware applied (use #request
330
330
  # to have the middleware applied). The entire response will be loaded into memory.
331
331
  # @api private
332
- def send_http_request(method, url, headers, body, &response_handler)
333
- headers = build_headers(method, url, headers, body)
334
-
332
+ def send_http_request(method, url, base_headers, body, &response_handler)
335
333
  retrying_http_errors(url) do
334
+ headers = build_headers(method, url, base_headers, body)
336
335
  client = http_client(url)
337
336
  return_value = nil
338
337
  if block_given?
@@ -408,11 +408,25 @@ class Chef
408
408
  config_loader = self.class.load_config(config[:config_file])
409
409
  config[:config_file] = config_loader.config_location
410
410
 
411
+ # For CLI options like `--config-option key=value`. These have to get
412
+ # parsed and applied separately.
413
+ extra_config_options = config.delete(:config_option)
414
+
411
415
  merge_configs
412
416
  apply_computed_config
413
- Chef::Config.export_proxies
417
+
414
418
  # This has to be after apply_computed_config so that Mixlib::Log is configured
415
419
  Chef::Log.info("Using configuration from #{config[:config_file]}") if config[:config_file]
420
+
421
+ begin
422
+ Chef::Config.apply_extra_config_options(extra_config_options)
423
+ rescue ChefConfig::UnparsableConfigOption => e
424
+ ui.error e.message
425
+ show_usage
426
+ exit(1)
427
+ end
428
+
429
+ Chef::Config.export_proxies
416
430
  end
417
431
 
418
432
  def show_usage
@@ -525,7 +539,11 @@ class Chef
525
539
 
526
540
  # FIXME: yard with @yield
527
541
  def create_object(object, pretty_name = nil, object_class: nil)
528
- output = edit_data(object, object_class: object_class)
542
+ output = if object_class
543
+ edit_data(object, object_class: object_class)
544
+ else
545
+ edit_hash(object)
546
+ end
529
547
 
530
548
  if Kernel.block_given?
531
549
  output = yield(output)
@@ -28,12 +28,19 @@ class Chef
28
28
  # :nodoc:
29
29
  def self.included(includer)
30
30
  includer.class_eval do
31
- @attrs_to_show = []
31
+ option :field_separator,
32
+ :short => "-S SEPARATOR",
33
+ :long => "--field-separator SEPARATOR",
34
+ :description => "Character separator used to delineate nesting in --attribute filters (default \".\")"
35
+
32
36
  option :attribute,
33
37
  :short => "-a ATTR1 [-a ATTR2]",
34
38
  :long => "--attribute ATTR1 [--attribute ATTR2] ",
35
- :proc => lambda { |val| @attrs_to_show << val },
36
- :description => "Show one or more attributes"
39
+ :description => "Show one or more attributes",
40
+ :proc => Proc.new { |a|
41
+ Chef::Config[:knife][:attribute] ||= []
42
+ Chef::Config[:knife][:attribute].push(a)
43
+ }
37
44
  end
38
45
  end
39
46
  end
@@ -173,8 +180,15 @@ class Chef
173
180
  config[:attribute] || config[:run_list]
174
181
  end
175
182
 
183
+ # GenericPresenter is used in contexts where MultiAttributeReturnOption
184
+ # is not, so we need to set the default value here rather than as part
185
+ # of the CLI option.
186
+ def attribute_field_separator
187
+ config[:field_separator] || "."
188
+ end
189
+
176
190
  def extract_nested_value(data, nested_value_spec)
177
- nested_value_spec.split(".").each do |attr|
191
+ nested_value_spec.split(attribute_field_separator).each do |attr|
178
192
  data =
179
193
  if data.is_a?(Array)
180
194
  data[attr.to_i]
@@ -55,11 +55,6 @@ class Chef
55
55
 
56
56
  node = Chef::Node.load(@node_name)
57
57
  output(format_for_display(node))
58
- self.class.attrs_to_show = []
59
- end
60
-
61
- def self.attrs_to_show=(attrs)
62
- @attrs_to_show = attrs
63
58
  end
64
59
  end
65
60
  end
@@ -48,7 +48,6 @@ class Chef
48
48
  user = Chef::User.load(@user_name)
49
49
  output(format_for_display(user))
50
50
  end
51
-
52
51
  end
53
52
  end
54
53
  end
@@ -89,8 +89,11 @@ class Chef
89
89
 
90
90
  def cn_of(certificate)
91
91
  subject = certificate.subject
92
- cn_field_tuple = subject.to_a.find { |field| field[0] == "CN" }
93
- cn_field_tuple[1]
92
+ if cn_field_tuple = subject.to_a.find { |field| field[0] == "CN" }
93
+ cn_field_tuple[1]
94
+ else
95
+ nil
96
+ end
94
97
  end
95
98
 
96
99
  # Convert the CN of a certificate into something that will work well as a
@@ -117,9 +120,10 @@ class Chef
117
120
  def write_cert(cert)
118
121
  FileUtils.mkdir_p(trusted_certs_dir)
119
122
  cn = cn_of(cert)
120
- filename = File.join(trusted_certs_dir, "#{normalize_cn(cn)}.crt")
121
- ui.msg("Adding certificate for #{cn} in #{filename}")
122
- File.open(filename, File::CREAT | File::TRUNC | File::RDWR, 0644) do |f|
123
+ filename = cn.nil? ? "#{host}_#{Time.new.to_i}" : normalize_cn(cn)
124
+ full_path = File.join(trusted_certs_dir, "#{filename}.crt")
125
+ ui.msg("Adding certificate for #{filename} in #{full_path}")
126
+ File.open(full_path, File::CREAT | File::TRUNC | File::RDWR, 0644) do |f|
123
127
  f.print(cert.to_s)
124
128
  end
125
129
  end
@@ -91,7 +91,7 @@ class Chef
91
91
  "-InputFormat None",
92
92
  ]
93
93
 
94
- "powershell.exe #{flags.join(' ')} -Command \"#{script}\""
94
+ "powershell.exe #{flags.join(' ')} -Command \"#{script.gsub('"', '\"')}\""
95
95
  end
96
96
  end
97
97
  end
@@ -61,7 +61,7 @@ class Chef
61
61
  [:command_log_prepend, :log_tag] ]
62
62
 
63
63
  # CHEF-3090: Deprecate command_log_level and command_log_prepend
64
- # Patterned after https://github.com/opscode/chef/commit/e1509990b559984b43e428d4d801c394e970f432
64
+ # Patterned after https://github.com/chef/chef/commit/e1509990b559984b43e428d4d801c394e970f432
65
65
  def run_command_compatible_options(command_args)
66
66
  return command_args unless command_args.last.is_a?(Hash)
67
67
 
@@ -78,7 +78,7 @@ class Chef
78
78
  @policy_name = nil
79
79
  @policy_group = nil
80
80
 
81
- @attributes = Chef::Node::Attribute.new({}, {}, {}, {})
81
+ @attributes = Chef::Node::Attribute.new({}, {}, {}, {}, self)
82
82
 
83
83
  @run_state = {}
84
84
  end
@@ -197,7 +197,6 @@ class Chef
197
197
  # Set a normal attribute of this node, but auto-vivify any Mashes that
198
198
  # might be missing
199
199
  def normal
200
- attributes.top_level_breadcrumb = nil
201
200
  attributes.normal
202
201
  end
203
202
 
@@ -209,14 +208,12 @@ class Chef
209
208
  # Set a default of this node, but auto-vivify any Mashes that might
210
209
  # be missing
211
210
  def default
212
- attributes.top_level_breadcrumb = nil
213
211
  attributes.default
214
212
  end
215
213
 
216
214
  # Set an override attribute of this node, but auto-vivify any Mashes that
217
215
  # might be missing
218
216
  def override
219
- attributes.top_level_breadcrumb = nil
220
217
  attributes.override
221
218
  end
222
219
 
@@ -237,7 +234,6 @@ class Chef
237
234
  end
238
235
 
239
236
  def automatic_attrs
240
- attributes.top_level_breadcrumb = nil
241
237
  attributes.automatic
242
238
  end
243
239
 
@@ -17,6 +17,9 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
+ require "chef/node/mixin/deep_merge_cache"
21
+ require "chef/node/mixin/immutablize_hash"
22
+ require "chef/node/mixin/state_tracking"
20
23
  require "chef/node/immutable_collections"
21
24
  require "chef/node/attribute_collections"
22
25
  require "chef/decorator/unchain"
@@ -34,9 +37,18 @@ class Chef
34
37
  class Attribute < Mash
35
38
 
36
39
  include Immutablize
37
-
40
+ # FIXME: what is include Enumerable doing up here, when down below we delegate
41
+ # most of the Enumerable/Hash things to the underlying merged ImmutableHash. That
42
+ # is, in fact, the correct, thing to do, while including Enumerable to try to create
43
+ # a hash-like API gets lots of things wrong because of the difference between the
44
+ # Hash `each do |key, value|` vs the Array-like `each do |value|` API that Enumerable
45
+ # expects. This include should probably be deleted?
38
46
  include Enumerable
39
47
 
48
+ include Chef::Node::Mixin::DeepMergeCache
49
+ include Chef::Node::Mixin::StateTracking
50
+ include Chef::Node::Mixin::ImmutablizeHash
51
+
40
52
  # List of the component attribute hashes, in order of precedence, low to
41
53
  # high.
42
54
  COMPONENTS = [
@@ -175,39 +187,22 @@ class Chef
175
187
  # return the automatic level attribute component
176
188
  attr_reader :automatic
177
189
 
178
- # This is used to track the top level key as we descend through method chaining into
179
- # a precedence level (e.g. node.default['foo']['bar']['baz']= results in 'foo' here). We
180
- # need this so that when we hit the end of a method chain which results in a mutator method
181
- # that we can invalidate the whole top-level deep merge cache for the top-level key. It is
182
- # the responsibility of the accessor on the Chef::Node object to reset this to nil, and then
183
- # the first VividMash#[] call can ||= and set this to the first key we encounter.
184
- attr_accessor :top_level_breadcrumb
185
-
186
- # Cache of deep merged values by top-level key. This is a simple hash which has keys that are the
187
- # top-level keys of the node object, and we save the computed deep-merge for that key here. There is
188
- # no cache of subtrees.
189
- attr_accessor :deep_merge_cache
190
+ def initialize(normal, default, override, automatic, node = nil)
191
+ @default = VividMash.new(default, self, node, :default)
192
+ @env_default = VividMash.new({}, self, node, :env_default)
193
+ @role_default = VividMash.new({}, self, node, :role_default)
194
+ @force_default = VividMash.new({}, self, node, :force_default)
190
195
 
191
- def initialize(normal, default, override, automatic)
192
- @default = VividMash.new(self, default)
193
- @env_default = VividMash.new(self, {})
194
- @role_default = VividMash.new(self, {})
195
- @force_default = VividMash.new(self, {})
196
+ @normal = VividMash.new(normal, self, node, :normal)
196
197
 
197
- @normal = VividMash.new(self, normal)
198
+ @override = VividMash.new(override, self, node, :override)
199
+ @role_override = VividMash.new({}, self, node, :role_override)
200
+ @env_override = VividMash.new({}, self, node, :env_override)
201
+ @force_override = VividMash.new({}, self, node, :force_override)
198
202
 
199
- @override = VividMash.new(self, override)
200
- @role_override = VividMash.new(self, {})
201
- @env_override = VividMash.new(self, {})
202
- @force_override = VividMash.new(self, {})
203
+ @automatic = VividMash.new(automatic, self, node, :automatic)
203
204
 
204
- @automatic = VividMash.new(self, automatic)
205
-
206
- @merged_attributes = nil
207
- @combined_override = nil
208
- @combined_default = nil
209
- @top_level_breadcrumb = nil
210
- @deep_merge_cache = {}
205
+ super(nil, self, node, :merged)
211
206
  end
212
207
 
213
208
  # Debug what's going on with an attribute. +args+ is a path spec to the
@@ -235,76 +230,62 @@ class Chef
235
230
  end
236
231
  end
237
232
 
238
- # Invalidate a key in the deep_merge_cache. If called with nil, or no arg, this will invalidate
239
- # the entire deep_merge cache. In the case of the user doing node.default['foo']['bar']['baz']=
240
- # that eventually results in a call to reset_cache('foo') here. A node.default=hash_thing call
241
- # must invalidate the entire cache and re-deep-merge the entire node object.
242
- def reset_cache(path = nil)
243
- if path.nil?
244
- @deep_merge_cache = {}
245
- else
246
- deep_merge_cache.delete(path.to_s)
247
- end
248
- end
249
-
250
- alias :reset :reset_cache
251
-
252
233
  # Set the cookbook level default attribute component to +new_data+.
253
234
  def default=(new_data)
254
235
  reset
255
- @default = VividMash.new(self, new_data)
236
+ @default = VividMash.new(new_data, self, __node__, :default)
256
237
  end
257
238
 
258
239
  # Set the role level default attribute component to +new_data+
259
240
  def role_default=(new_data)
260
241
  reset
261
- @role_default = VividMash.new(self, new_data)
242
+ @role_default = VividMash.new(new_data, self, __node__, :role_default)
262
243
  end
263
244
 
264
245
  # Set the environment level default attribute component to +new_data+
265
246
  def env_default=(new_data)
266
247
  reset
267
- @env_default = VividMash.new(self, new_data)
248
+ @env_default = VividMash.new(new_data, self, __node__, :env_default)
268
249
  end
269
250
 
270
251
  # Set the force_default (+default!+) level attributes to +new_data+
271
252
  def force_default=(new_data)
272
253
  reset
273
- @force_default = VividMash.new(self, new_data)
254
+ @force_default = VividMash.new(new_data, self, __node__, :force_default)
274
255
  end
275
256
 
276
257
  # Set the normal level attribute component to +new_data+
277
258
  def normal=(new_data)
278
259
  reset
279
- @normal = VividMash.new(self, new_data)
260
+ @normal = VividMash.new(new_data, self, __node__, :normal)
280
261
  end
281
262
 
282
263
  # Set the cookbook level override attribute component to +new_data+
283
264
  def override=(new_data)
284
265
  reset
285
- @override = VividMash.new(self, new_data)
266
+ @override = VividMash.new(new_data, self, __node__, :override)
286
267
  end
287
268
 
288
269
  # Set the role level override attribute component to +new_data+
289
270
  def role_override=(new_data)
290
271
  reset
291
- @role_override = VividMash.new(self, new_data)
272
+ @role_override = VividMash.new(new_data, self, __node__, :role_override)
292
273
  end
293
274
 
294
275
  # Set the environment level override attribute component to +new_data+
295
276
  def env_override=(new_data)
296
277
  reset
297
- @env_override = VividMash.new(self, new_data)
278
+ @env_override = VividMash.new(new_data, self, __node__, :env_override)
298
279
  end
299
280
 
300
281
  def force_override=(new_data)
301
282
  reset
302
- @force_override = VividMash.new(self, new_data)
283
+ @force_override = VividMash.new(new_data, self, __node__, :force_override)
303
284
  end
304
285
 
305
286
  def automatic=(new_data)
306
287
  reset
307
- @automatic = VividMash.new(self, new_data)
288
+ @automatic = VividMash.new(new_data, self, __node__, :automatic)
308
289
  end
309
290
 
310
291
  #
@@ -413,36 +394,6 @@ class Chef
413
394
  write(:force_override, *args, value)
414
395
  end
415
396
 
416
- # method-style access to attributes
417
-
418
- def read(*path)
419
- merged_attributes.read(*path)
420
- end
421
-
422
- def read!(*path)
423
- merged_attributes.read!(*path)
424
- end
425
-
426
- def exist?(*path)
427
- merged_attributes.exist?(*path)
428
- end
429
-
430
- def write(level, *args, &block)
431
- self.send(level).write(*args, &block)
432
- end
433
-
434
- def write!(level, *args, &block)
435
- self.send(level).write!(*args, &block)
436
- end
437
-
438
- def unlink(level, *path)
439
- self.send(level).unlink(*path)
440
- end
441
-
442
- def unlink!(level, *path)
443
- self.send(level).unlink!(*path)
444
- end
445
-
446
397
  #
447
398
  # Accessing merged attributes.
448
399
  #
@@ -484,24 +435,39 @@ class Chef
484
435
  write(:normal, *args) if read(*args[0...-1]).nil?
485
436
  end
486
437
 
487
- def [](key)
488
- if deep_merge_cache.has_key?(key.to_s)
489
- # return the cache of the deep merged values by top-level key
490
- deep_merge_cache[key.to_s]
491
- else
492
- # save all the work of computing node[key]
493
- deep_merge_cache[key.to_s] = merged_attributes(key)
438
+ def has_key?(key)
439
+ COMPONENTS.any? do |component_ivar|
440
+ instance_variable_get(component_ivar).has_key?(key)
494
441
  end
495
442
  end
443
+ # method-style access to attributes (has to come after the prepended ImmutablizeHash)
496
444
 
497
- def []=(key, value)
498
- raise Exceptions::ImmutableAttributeModification
445
+ def read(*path)
446
+ merged_attributes.read(*path)
499
447
  end
500
448
 
501
- def has_key?(key)
502
- COMPONENTS.any? do |component_ivar|
503
- instance_variable_get(component_ivar).has_key?(key)
504
- end
449
+ def read!(*path)
450
+ merged_attributes.read!(*path)
451
+ end
452
+
453
+ def exist?(*path)
454
+ merged_attributes.exist?(*path)
455
+ end
456
+
457
+ def write(level, *args, &block)
458
+ self.send(level).write(*args, &block)
459
+ end
460
+
461
+ def write!(level, *args, &block)
462
+ self.send(level).write!(*args, &block)
463
+ end
464
+
465
+ def unlink(level, *path)
466
+ self.send(level).unlink(*path)
467
+ end
468
+
469
+ def unlink!(level, *path)
470
+ self.send(level).unlink!(*path)
505
471
  end
506
472
 
507
473
  alias :attribute? :has_key?
@@ -515,6 +481,7 @@ class Chef
515
481
  if symbol == :to_ary
516
482
  merged_attributes.send(symbol, *args)
517
483
  elsif args.empty?
484
+ puts symbol
518
485
  Chef.log_deprecation %q{method access to node attributes (node.foo.bar) is deprecated and will be removed in Chef 13, please use bracket syntax (node["foo"]["bar"])}
519
486
  if key?(symbol)
520
487
  self[symbol]
@@ -600,7 +567,7 @@ class Chef
600
567
 
601
568
  return nil if components.compact.empty?
602
569
 
603
- components.inject(ImmutableMash.new({})) do |merged, component|
570
+ components.inject(ImmutableMash.new({}, self, __node__, :merged)) do |merged, component|
604
571
  Chef::Mixin::DeepMerge.hash_only_merge!(merged, component)
605
572
  end
606
573
  end
@@ -631,6 +598,11 @@ class Chef
631
598
  end
632
599
  end
633
600
 
601
+ # needed for __path__
602
+ def convert_key(key)
603
+ key.kind_of?(Symbol) ? key.to_s : key
604
+ end
605
+
634
606
  end
635
607
 
636
608
  end