chef 13.7.16 → 13.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/distro/common/man/man8/chef-solo.8 +1 -1
- data/lib/chef/chef_fs/data_handler/organization_invites_data_handler.rb +1 -1
- data/lib/chef/knife/bootstrap.rb +1 -1
- data/lib/chef/knife/search.rb +3 -1
- data/lib/chef/knife/ssh.rb +5 -7
- data/lib/chef/node/attribute.rb +70 -46
- data/lib/chef/node/attribute_collections.rb +5 -5
- data/lib/chef/node/common_api.rb +1 -1
- data/lib/chef/node/immutable_collections.rb +23 -180
- data/lib/chef/node/mixin/state_tracking.rb +6 -6
- data/lib/chef/node_map.rb +26 -0
- data/lib/chef/provider/remote_file/http.rb +8 -3
- data/lib/chef/resource/log.rb +1 -1
- data/lib/chef/resource/windows_task.rb +4 -4
- data/lib/chef/version.rb +1 -1
- data/spec/functional/mixin/powershell_out_spec.rb +5 -21
- data/spec/spec_helper.rb +19 -1
- data/spec/unit/daemon_spec.rb +21 -12
- data/spec/unit/mixin/powershell_type_coercions_spec.rb +6 -7
- data/spec/unit/node/attribute_spec.rb +24 -55
- data/spec/unit/node/immutable_collections_spec.rb +16 -30
- data/spec/unit/node/vivid_mash_spec.rb +10 -27
- data/spec/unit/node_map_spec.rb +29 -4
- data/spec/unit/provider/remote_file/http_spec.rb +6 -8
- data/spec/unit/resource/windows_task_spec.rb +9 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4cf91005817c8edd084d2eef52e54b9a320c79e8
|
4
|
+
data.tar.gz: d64f227f12314884d0f77a6a16fac2465251cd1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6593a7a47e0e16c9bae832c21f7fe19eab191fb005160f8094b88303a42bb8c0709e806c9d35a18ae15155782b1936454c58ec426089c995ceafe8fd95442da6
|
7
|
+
data.tar.gz: 802c38b93e6acf6e95961f854aa14ae65eed72f8d4b64b4dd80ba7835812b87ae3239ee657cb2f501ff40987ae872908cb2106c7451e98b06f8dca1aaeed7f74
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
13.
|
1
|
+
13.8.0
|
@@ -79,7 +79,7 @@ The configuration file to use.
|
|
79
79
|
.B \fB\-d\fP, \fB\-\-daemonize\fP
|
80
80
|
Use to run the executable as a daemon. This option may not be used in the same command with the \fB\-\-[no\-]fork\fP option.
|
81
81
|
.sp
|
82
|
-
This option is only available on machines that run in UNIX or Linux environments. For machines that are running Microsoft Windows that require similar functionality, use the \fBchef\-client::service\fP recipe in the \fBchef\-client\fP cookbook: \fI\%http://community.opscode.com/cookbooks/chef\-client\fP\&.
|
82
|
+
This option is only available on machines that run in UNIX or Linux environments. For machines that are running Microsoft Windows that require similar functionality, use the \fBchef\-client::service\fP recipe in the \fBchef\-client\fP cookbook: \fI\%http://community.opscode.com/cookbooks/chef\-client\fP\&. This will install a chef\-client service under Microsoft Windows using the Windows Service Wrapper\&.
|
83
83
|
.TP
|
84
84
|
.B \fB\-E ENVIRONMENT_NAME\fP, \fB\-\-environment ENVIRONMENT_NAME\fP
|
85
85
|
The name of the environment.
|
@@ -5,7 +5,7 @@ class Chef
|
|
5
5
|
module DataHandler
|
6
6
|
class OrganizationInvitesDataHandler < DataHandlerBase
|
7
7
|
def normalize(invites, entry)
|
8
|
-
invites.map { |invite| invite.is_a?(Hash) ? invite["username"] : invite }.sort.uniq
|
8
|
+
invites.map { |invite| invite.is_a?(Hash) ? invite["username"] : invite }.compact.sort.uniq
|
9
9
|
end
|
10
10
|
|
11
11
|
def minimize(invites, entry)
|
data/lib/chef/knife/bootstrap.rb
CHANGED
@@ -448,7 +448,7 @@ class Chef
|
|
448
448
|
ssh.config[:ssh_identity_file] = config[:ssh_identity_file] || config[:identity_file]
|
449
449
|
ssh.config[:manual] = true
|
450
450
|
ssh.config[:host_key_verify] = config[:host_key_verify]
|
451
|
-
ssh.config[:on_error] =
|
451
|
+
ssh.config[:on_error] = true
|
452
452
|
ssh
|
453
453
|
end
|
454
454
|
|
data/lib/chef/knife/search.rb
CHANGED
@@ -98,7 +98,9 @@ class Chef
|
|
98
98
|
begin
|
99
99
|
q.search(@type, @query, search_args) do |item|
|
100
100
|
formatted_item = Hash.new
|
101
|
-
if
|
101
|
+
if config[:id_only]
|
102
|
+
formatted_item = format_for_display({ "id" => item["__display_name"] })
|
103
|
+
elsif item.is_a?(Hash)
|
102
104
|
# doing a little magic here to set the correct name
|
103
105
|
formatted_item[item["__display_name"]] = item.reject { |k| k == "__display_name" }
|
104
106
|
else
|
data/lib/chef/knife/ssh.rb
CHANGED
@@ -125,7 +125,7 @@ class Chef
|
|
125
125
|
:long => "--exit-on-error",
|
126
126
|
:description => "Immediately exit if an error is encountered",
|
127
127
|
:boolean => true,
|
128
|
-
:
|
128
|
+
:default => false
|
129
129
|
|
130
130
|
option :tmux_split,
|
131
131
|
:long => "--tmux-split",
|
@@ -134,15 +134,13 @@ class Chef
|
|
134
134
|
:default => false
|
135
135
|
|
136
136
|
def session
|
137
|
-
config[:on_error] ||= :skip
|
138
137
|
ssh_error_handler = Proc.new do |server|
|
139
|
-
|
140
|
-
when :skip
|
141
|
-
ui.warn "Failed to connect to #{server.host} -- #{$!.class.name}: #{$!.message}"
|
142
|
-
$!.backtrace.each { |l| Chef::Log.debug(l) }
|
143
|
-
when :raise
|
138
|
+
if config[:on_error]
|
144
139
|
#Net::SSH::Multi magic to force exception to be re-raised.
|
145
140
|
throw :go, :raise
|
141
|
+
else
|
142
|
+
ui.warn "Failed to connect to #{server.host} -- #{$!.class.name}: #{$!.message}"
|
143
|
+
$!.backtrace.each { |l| Chef::Log.debug(l) }
|
146
144
|
end
|
147
145
|
end
|
148
146
|
|
data/lib/chef/node/attribute.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
|
20
|
+
require "chef/node/mixin/deep_merge_cache"
|
20
21
|
require "chef/node/mixin/immutablize_hash"
|
21
22
|
require "chef/node/mixin/state_tracking"
|
22
23
|
require "chef/node/immutable_collections"
|
@@ -44,6 +45,7 @@ class Chef
|
|
44
45
|
# expects. This include should probably be deleted?
|
45
46
|
include Enumerable
|
46
47
|
|
48
|
+
include Chef::Node::Mixin::DeepMergeCache
|
47
49
|
include Chef::Node::Mixin::StateTracking
|
48
50
|
include Chef::Node::Mixin::ImmutablizeHash
|
49
51
|
|
@@ -185,9 +187,6 @@ class Chef
|
|
185
187
|
# return the automatic level attribute component
|
186
188
|
attr_reader :automatic
|
187
189
|
|
188
|
-
# return the immutablemash deep merge cache
|
189
|
-
attr_reader :deep_merge_cache
|
190
|
-
|
191
190
|
def initialize(normal, default, override, automatic, node = nil)
|
192
191
|
@default = VividMash.new(default, self, node, :default)
|
193
192
|
@env_default = VividMash.new({}, self, node, :env_default)
|
@@ -203,8 +202,7 @@ class Chef
|
|
203
202
|
|
204
203
|
@automatic = VividMash.new(automatic, self, node, :automatic)
|
205
204
|
|
206
|
-
|
207
|
-
@__node__ = node
|
205
|
+
super(nil, self, node, :merged)
|
208
206
|
end
|
209
207
|
|
210
208
|
# Debug what's going on with an attribute. +args+ is a path spec to the
|
@@ -228,22 +226,6 @@ class Chef
|
|
228
226
|
end
|
229
227
|
end
|
230
228
|
|
231
|
-
def reset
|
232
|
-
@deep_merge_cache = ImmutableMash.new({}, self, @__node__, :merged)
|
233
|
-
end
|
234
|
-
|
235
|
-
def reset_cache(*path)
|
236
|
-
if path.empty?
|
237
|
-
reset
|
238
|
-
else
|
239
|
-
container = read(*path)
|
240
|
-
case container
|
241
|
-
when Hash, Array
|
242
|
-
container.reset
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
229
|
# Set the cookbook level default attribute component to +new_data+.
|
248
230
|
def default=(new_data)
|
249
231
|
reset
|
@@ -308,7 +290,7 @@ class Chef
|
|
308
290
|
|
309
291
|
# clears attributes from all precedence levels
|
310
292
|
def rm(*args)
|
311
|
-
with_deep_merged_return_value(
|
293
|
+
with_deep_merged_return_value(self, *args) do
|
312
294
|
rm_default(*args)
|
313
295
|
rm_normal(*args)
|
314
296
|
rm_override(*args)
|
@@ -355,9 +337,6 @@ class Chef
|
|
355
337
|
def with_deep_merged_return_value(obj, *path, last)
|
356
338
|
hash = obj.read(*path)
|
357
339
|
return nil unless hash.is_a?(Hash)
|
358
|
-
# coerce from immutablemash/vividmash to plain-old Hash
|
359
|
-
# also de-immutablizes and dup's the return value correctly in chef-13
|
360
|
-
hash = hash.to_hash
|
361
340
|
ret = hash[last]
|
362
341
|
yield
|
363
342
|
ret
|
@@ -419,16 +398,16 @@ class Chef
|
|
419
398
|
# all of node['foo'] even if the user only requires node['foo']['bar']['baz'].
|
420
399
|
#
|
421
400
|
|
422
|
-
def
|
423
|
-
|
401
|
+
def merged_attributes(*path)
|
402
|
+
merge_all(path)
|
424
403
|
end
|
425
404
|
|
426
|
-
def
|
427
|
-
|
405
|
+
def combined_override(*path)
|
406
|
+
immutablize(merge_overrides(path))
|
428
407
|
end
|
429
408
|
|
430
409
|
def combined_default(*path)
|
431
|
-
merge_defaults(path)
|
410
|
+
immutablize(merge_defaults(path))
|
432
411
|
end
|
433
412
|
|
434
413
|
def normal_unless(*args)
|
@@ -497,14 +476,6 @@ class Chef
|
|
497
476
|
merged_attributes.to_s
|
498
477
|
end
|
499
478
|
|
500
|
-
def [](key)
|
501
|
-
@deep_merge_cache[key]
|
502
|
-
end
|
503
|
-
|
504
|
-
def merged_attributes
|
505
|
-
@deep_merge_cache
|
506
|
-
end
|
507
|
-
|
508
479
|
def inspect
|
509
480
|
"#<#{self.class} " << (COMPONENTS + [:@merged_attributes, :@properties]).map do |iv|
|
510
481
|
"#{iv}=#{instance_variable_get(iv).inspect}"
|
@@ -513,14 +484,7 @@ class Chef
|
|
513
484
|
|
514
485
|
private
|
515
486
|
|
516
|
-
|
517
|
-
def safe_dup(e)
|
518
|
-
e.dup
|
519
|
-
rescue TypeError
|
520
|
-
e
|
521
|
-
end
|
522
|
-
|
523
|
-
# Helper method for merge_defaults/merge_overrides.
|
487
|
+
# Helper method for merge_all/merge_defaults/merge_overrides.
|
524
488
|
#
|
525
489
|
# apply_path(thing, [ "foo", "bar", "baz" ]) = thing["foo"]["bar"]["baz"]
|
526
490
|
#
|
@@ -550,6 +514,34 @@ class Chef
|
|
550
514
|
end
|
551
515
|
end
|
552
516
|
|
517
|
+
# For elements like Fixnums, true, nil...
|
518
|
+
def safe_dup(e)
|
519
|
+
e.dup
|
520
|
+
rescue TypeError
|
521
|
+
e
|
522
|
+
end
|
523
|
+
|
524
|
+
# Deep merge all attribute levels using hash-only merging between different precidence
|
525
|
+
# levels (so override arrays completely replace arrays set at any default level).
|
526
|
+
#
|
527
|
+
# The path allows for selectively deep-merging a subtree of the node object.
|
528
|
+
#
|
529
|
+
# @param path [Array] Array of args to method chain to descend into the node object
|
530
|
+
# @return [attr] Deep Merged values (may be VividMash, Hash, Array, etc) from the node object
|
531
|
+
def merge_all(path)
|
532
|
+
components = [
|
533
|
+
merge_defaults(path),
|
534
|
+
apply_path(@normal, path),
|
535
|
+
merge_overrides(path),
|
536
|
+
apply_path(@automatic, path),
|
537
|
+
]
|
538
|
+
|
539
|
+
ret = components.inject(NIL) do |merged, component|
|
540
|
+
hash_only_merge!(merged, component)
|
541
|
+
end
|
542
|
+
ret == NIL ? nil : ret
|
543
|
+
end
|
544
|
+
|
553
545
|
# Deep merge the default attribute levels with array merging.
|
554
546
|
#
|
555
547
|
# The path allows for selectively deep-merging a subtree of the node object.
|
@@ -621,6 +613,38 @@ class Chef
|
|
621
613
|
end
|
622
614
|
end
|
623
615
|
|
616
|
+
# @api private
|
617
|
+
def hash_only_merge!(merge_onto, merge_with)
|
618
|
+
# If there are two Hashes, recursively merge.
|
619
|
+
if merge_onto.kind_of?(Hash) && merge_with.kind_of?(Hash)
|
620
|
+
merge_with.each do |key, merge_with_value|
|
621
|
+
value =
|
622
|
+
if merge_onto.has_key?(key)
|
623
|
+
hash_only_merge!(safe_dup(merge_onto[key]), merge_with_value)
|
624
|
+
else
|
625
|
+
merge_with_value
|
626
|
+
end
|
627
|
+
|
628
|
+
# internal_set bypasses converting keys, does convert values and allows writing to immutable mashes
|
629
|
+
merge_onto.internal_set(key, value)
|
630
|
+
end
|
631
|
+
merge_onto
|
632
|
+
|
633
|
+
# If merge_with is nil, don't replace merge_onto
|
634
|
+
elsif merge_with.nil?
|
635
|
+
merge_onto
|
636
|
+
|
637
|
+
# In all other cases, replace merge_onto with merge_with
|
638
|
+
else
|
639
|
+
if merge_with.kind_of?(Hash)
|
640
|
+
Chef::Node::ImmutableMash.new(merge_with)
|
641
|
+
elsif merge_with.kind_of?(Array)
|
642
|
+
Chef::Node::ImmutableArray.new(merge_with)
|
643
|
+
else
|
644
|
+
merge_with
|
645
|
+
end
|
646
|
+
end
|
647
|
+
end
|
624
648
|
end
|
625
649
|
end
|
626
650
|
end
|
@@ -63,13 +63,13 @@ class Chef
|
|
63
63
|
MUTATOR_METHODS.each do |mutator|
|
64
64
|
define_method(mutator) do |*args, &block|
|
65
65
|
ret = super(*args, &block)
|
66
|
-
send_reset_cache
|
66
|
+
send_reset_cache
|
67
67
|
ret
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
71
|
def delete(key, &block)
|
72
|
-
send_reset_cache(__path__)
|
72
|
+
send_reset_cache(__path__, key)
|
73
73
|
super
|
74
74
|
end
|
75
75
|
|
@@ -147,13 +147,13 @@ class Chef
|
|
147
147
|
# object.
|
148
148
|
|
149
149
|
def delete(key, &block)
|
150
|
-
send_reset_cache(__path__)
|
150
|
+
send_reset_cache(__path__, key)
|
151
151
|
super
|
152
152
|
end
|
153
153
|
|
154
154
|
MUTATOR_METHODS.each do |mutator|
|
155
155
|
define_method(mutator) do |*args, &block|
|
156
|
-
send_reset_cache
|
156
|
+
send_reset_cache
|
157
157
|
super(*args, &block)
|
158
158
|
end
|
159
159
|
end
|
@@ -174,7 +174,7 @@ class Chef
|
|
174
174
|
|
175
175
|
def []=(key, value)
|
176
176
|
ret = super
|
177
|
-
send_reset_cache(__path__)
|
177
|
+
send_reset_cache(__path__, key)
|
178
178
|
ret
|
179
179
|
end
|
180
180
|
|
data/lib/chef/node/common_api.rb
CHANGED
@@ -30,16 +30,22 @@ class Chef
|
|
30
30
|
e
|
31
31
|
end
|
32
32
|
|
33
|
-
def convert_value(value
|
33
|
+
def convert_value(value)
|
34
34
|
case value
|
35
35
|
when Hash
|
36
|
-
ImmutableMash.new(
|
36
|
+
ImmutableMash.new(value, __root__, __node__, __precedence__)
|
37
37
|
when Array
|
38
|
-
ImmutableArray.new(
|
38
|
+
ImmutableArray.new(value, __root__, __node__, __precedence__)
|
39
|
+
when ImmutableMash, ImmutableArray
|
40
|
+
value
|
39
41
|
else
|
40
42
|
safe_dup(value).freeze
|
41
43
|
end
|
42
44
|
end
|
45
|
+
|
46
|
+
def immutablize(value)
|
47
|
+
convert_value(value)
|
48
|
+
end
|
43
49
|
end
|
44
50
|
|
45
51
|
# == ImmutableArray
|
@@ -53,49 +59,15 @@ class Chef
|
|
53
59
|
# Chef::Node::Attribute's values, it overrides all reader methods to
|
54
60
|
# detect staleness and raise an error if accessed when stale.
|
55
61
|
class ImmutableArray < Array
|
56
|
-
alias_method :internal_clear, :clear
|
57
|
-
alias_method :internal_replace, :replace
|
58
|
-
alias_method :internal_push, :<<
|
59
|
-
alias_method :internal_to_a, :to_a
|
60
|
-
alias_method :internal_each, :each
|
61
|
-
private :internal_push, :internal_replace, :internal_clear, :internal_each
|
62
|
-
protected :internal_to_a
|
63
|
-
|
64
62
|
include Immutablize
|
65
63
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
methods.each do |method|
|
70
|
-
define_method method do |*args, &block|
|
71
|
-
ensure_generated_cache!
|
72
|
-
super(*args, &block)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def each
|
77
|
-
ensure_generated_cache!
|
78
|
-
# aggressively pre generate the cache, works around ruby being too smart and fiddling with internals
|
79
|
-
internal_each { |i| i.ensure_generated_cache! if i.respond_to?(:ensure_generated_cache!) }
|
80
|
-
super
|
81
|
-
end
|
82
|
-
|
83
|
-
# because sometimes ruby gives us back Arrays or ImmutableArrays out of objects from things like #uniq or array slices
|
84
|
-
def return_normal_array(array)
|
85
|
-
if array.respond_to?(:internal_to_a, true)
|
86
|
-
array.internal_to_a
|
87
|
-
else
|
88
|
-
array.to_a
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def uniq
|
93
|
-
ensure_generated_cache!
|
94
|
-
return_normal_array(super)
|
95
|
-
end
|
64
|
+
alias :internal_push :<<
|
65
|
+
private :internal_push
|
96
66
|
|
97
67
|
def initialize(array_data = [])
|
98
|
-
|
68
|
+
array_data.each do |value|
|
69
|
+
internal_push(immutablize(value))
|
70
|
+
end
|
99
71
|
end
|
100
72
|
|
101
73
|
# For elements like Fixnums, true, nil...
|
@@ -124,81 +96,8 @@ class Chef
|
|
124
96
|
|
125
97
|
alias_method :to_array, :to_a
|
126
98
|
|
127
|
-
def [](*args)
|
128
|
-
ensure_generated_cache!
|
129
|
-
args.length > 1 ? return_normal_array(super) : super # correctly handle array slices
|
130
|
-
end
|
131
|
-
|
132
|
-
def reset
|
133
|
-
@generated_cache = false
|
134
|
-
@short_circuit_attr_level = nil
|
135
|
-
internal_clear # redundant?
|
136
|
-
end
|
137
|
-
|
138
|
-
# @api private
|
139
|
-
def ensure_generated_cache!
|
140
|
-
generate_cache unless @generated_cache
|
141
|
-
@generated_cache = true
|
142
|
-
end
|
143
|
-
|
144
|
-
# This can be set to e.g. [ :@default ] by the parent container to cause this container
|
145
|
-
# to only use the default level and to bypass deep merging (the common case is either
|
146
|
-
# default-level or automatic-level and we aren't doing any deep merging). Right now it
|
147
|
-
# "optimized" for the case where we're no longer merging anything and only tracking a
|
148
|
-
# single level, and setting this to anything other than a size=1 array would behave
|
149
|
-
# in a broken fashion. That could be fixed, but the perf boost would likely not be
|
150
|
-
# that large in the typical case.
|
151
|
-
#
|
152
|
-
# @api private
|
153
|
-
attr_accessor :short_circuit_attr_levels
|
154
|
-
|
155
99
|
private
|
156
100
|
|
157
|
-
# deep merging of array attribute within normal and override where they are merged together
|
158
|
-
def combined_components(components)
|
159
|
-
combined_values = nil
|
160
|
-
components.each do |component|
|
161
|
-
values = __node__.attributes.instance_variable_get(component).read(*__path__)
|
162
|
-
next unless values.is_a?(Array)
|
163
|
-
@tracked_components << component
|
164
|
-
combined_values ||= []
|
165
|
-
combined_values += values
|
166
|
-
end
|
167
|
-
combined_values
|
168
|
-
end
|
169
|
-
|
170
|
-
def get_array(component)
|
171
|
-
array = __node__.attributes.instance_variable_get(component).read(*__path__)
|
172
|
-
if array.is_a?(Array)
|
173
|
-
@tracked_components << component
|
174
|
-
array
|
175
|
-
end # else nil
|
176
|
-
end
|
177
|
-
|
178
|
-
def generate_cache
|
179
|
-
internal_clear
|
180
|
-
components = []
|
181
|
-
@tracked_components = []
|
182
|
-
if short_circuit_attr_levels
|
183
|
-
components << get_array(short_circuit_attr_levels.first)
|
184
|
-
else
|
185
|
-
components << combined_components(Attribute::DEFAULT_COMPONENTS)
|
186
|
-
components << get_array(:@normal)
|
187
|
-
components << combined_components(Attribute::OVERRIDE_COMPONENTS)
|
188
|
-
components << get_array(:@automatic)
|
189
|
-
end
|
190
|
-
highest = components.compact.last
|
191
|
-
if highest.is_a?(Array)
|
192
|
-
internal_replace( highest.each_with_index.map { |x, i| convert_value(x, __path__ + [ i ] ) } )
|
193
|
-
end
|
194
|
-
if @tracked_components.size == 1
|
195
|
-
# tracked_components is accurate enough to tell us if we're not really merging
|
196
|
-
internal_each do |key, value|
|
197
|
-
value.short_circuit_attr_levels = @tracked_components if value.respond_to?(:short_circuit_attr_levels)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
101
|
# needed for __path__
|
203
102
|
def convert_key(key)
|
204
103
|
key
|
@@ -221,31 +120,19 @@ class Chef
|
|
221
120
|
# it is stale.
|
222
121
|
# * Values can be accessed in attr_reader-like fashion via method_missing.
|
223
122
|
class ImmutableMash < Mash
|
224
|
-
alias_method :internal_clear, :clear
|
225
|
-
alias_method :internal_key?, :key? # FIXME: could bypass convert_key in Mash for perf
|
226
|
-
alias_method :internal_each, :each
|
227
|
-
|
228
123
|
include Immutablize
|
229
124
|
include CommonAPI
|
230
125
|
|
231
|
-
methods = Hash.instance_methods - Object.instance_methods +
|
232
|
-
[ :!, :!=, :<=>, :==, :===, :eql?, :to_s, :hash, :key, :has_key?, :inspect, :pretty_print, :pretty_print_inspect, :pretty_print_cycle, :pretty_print_instance_variables ]
|
233
|
-
|
234
|
-
methods.each do |method|
|
235
|
-
define_method method do |*args, &block|
|
236
|
-
ensure_generated_cache!
|
237
|
-
super(*args, &block)
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
126
|
# this is for deep_merge usage, chef users must never touch this API
|
242
127
|
# @api private
|
243
128
|
def internal_set(key, value)
|
244
|
-
regular_writer(key, convert_value(value
|
129
|
+
regular_writer(key, convert_value(value))
|
245
130
|
end
|
246
131
|
|
247
132
|
def initialize(mash_data = {})
|
248
|
-
|
133
|
+
mash_data.each do |key, value|
|
134
|
+
internal_set(key, value)
|
135
|
+
end
|
249
136
|
end
|
250
137
|
|
251
138
|
alias :attribute? :has_key?
|
@@ -281,55 +168,11 @@ class Chef
|
|
281
168
|
|
282
169
|
alias_method :to_hash, :to_h
|
283
170
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
alias_method :to_hash, :to_h
|
290
|
-
|
291
|
-
def reset
|
292
|
-
@generated_cache = false
|
293
|
-
@short_circuit_attr_level = nil
|
294
|
-
internal_clear # redundant?
|
295
|
-
end
|
296
|
-
|
297
|
-
# @api private
|
298
|
-
def ensure_generated_cache!
|
299
|
-
generate_cache unless @generated_cache
|
300
|
-
@generated_cache = true
|
301
|
-
end
|
302
|
-
|
303
|
-
# @api private
|
304
|
-
attr_accessor :short_circuit_attr_levels
|
305
|
-
|
306
|
-
private
|
307
|
-
|
308
|
-
def generate_cache
|
309
|
-
internal_clear
|
310
|
-
components = short_circuit_attr_levels ? short_circuit_attr_levels : Attribute::COMPONENTS.reverse
|
311
|
-
# tracked_components is not entirely accurate due to the short-circuit
|
312
|
-
tracked_components = []
|
313
|
-
components.each do |component|
|
314
|
-
subhash = __node__.attributes.instance_variable_get(component).read(*__path__)
|
315
|
-
unless subhash.nil? # FIXME: nil is used for not present
|
316
|
-
tracked_components << component
|
317
|
-
if subhash.kind_of?(Hash)
|
318
|
-
subhash.keys.each do |key|
|
319
|
-
next if internal_key?(key)
|
320
|
-
internal_set(key, subhash[key])
|
321
|
-
end
|
322
|
-
else
|
323
|
-
break
|
324
|
-
end
|
325
|
-
end
|
326
|
-
end
|
327
|
-
if tracked_components.size == 1
|
328
|
-
# tracked_components is accurate enough to tell us if we're not really merging
|
329
|
-
internal_each do |key, value|
|
330
|
-
value.short_circuit_attr_levels = tracked_components if value.respond_to?(:short_circuit_attr_levels)
|
331
|
-
end
|
332
|
-
end
|
171
|
+
# For elements like Fixnums, true, nil...
|
172
|
+
def safe_dup(e)
|
173
|
+
e.dup
|
174
|
+
rescue TypeError
|
175
|
+
e
|
333
176
|
end
|
334
177
|
|
335
178
|
prepend Chef::Node::Mixin::StateTracking
|