chef 13.6.4 → 13.7.16
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/acceptance/Gemfile +2 -2
- data/acceptance/top-cookbooks/.acceptance/acceptance-cookbook/libraries/top_cookbooks.rb +1 -6
- data/distro/powershell/chef/chef.psm1 +1 -5
- data/lib/chef/api_client.rb +5 -5
- data/lib/chef/api_client_v1.rb +6 -6
- data/lib/chef/application.rb +3 -2
- data/lib/chef/application/knife.rb +4 -0
- data/lib/chef/chef_class.rb +2 -2
- data/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +1 -1
- data/lib/chef/chef_fs/data_handler/data_handler_base.rb +2 -4
- data/lib/chef/client.rb +3 -3
- data/lib/chef/cookbook/chefignore.rb +4 -0
- data/lib/chef/cookbook/cookbook_collection.rb +2 -2
- data/lib/chef/cookbook/metadata.rb +2 -2
- data/lib/chef/data_bag.rb +1 -1
- data/lib/chef/deprecated.rb +10 -0
- data/lib/chef/event_dispatch/base.rb +2 -2
- data/lib/chef/http.rb +10 -10
- data/lib/chef/knife.rb +16 -15
- data/lib/chef/knife/configure.rb +12 -36
- data/lib/chef/knife/cookbook_upload.rb +4 -4
- data/lib/chef/knife/core/bootstrap_context.rb +1 -1
- data/lib/chef/knife/core/status_presenter.rb +6 -2
- data/lib/chef/knife/core/ui.rb +1 -1
- data/lib/chef/knife/data_bag_secret_options.rb +1 -1
- data/lib/chef/knife/data_bag_show.rb +1 -1
- data/lib/chef/knife/edit.rb +1 -1
- data/lib/chef/knife/ssh.rb +47 -35
- data/lib/chef/knife/user_create.rb +2 -0
- data/lib/chef/knife/user_delete.rb +2 -0
- data/lib/chef/knife/user_edit.rb +2 -0
- data/lib/chef/knife/user_reregister.rb +2 -0
- data/lib/chef/knife/user_show.rb +2 -0
- data/lib/chef/mixin/powershell_out.rb +1 -1
- data/lib/chef/node/attribute.rb +46 -70
- 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 +180 -23
- data/lib/chef/node/mixin/state_tracking.rb +6 -6
- data/lib/chef/node_map.rb +63 -45
- data/lib/chef/property.rb +8 -8
- data/lib/chef/provider.rb +9 -3
- data/lib/chef/provider/apt_preference.rb +1 -1
- data/lib/chef/provider/apt_repository.rb +1 -1
- data/lib/chef/provider/apt_update.rb +1 -1
- data/lib/chef/provider/file.rb +1 -1
- data/lib/chef/provider/group/dscl.rb +6 -2
- data/lib/chef/provider/ifconfig.rb +96 -34
- data/lib/chef/provider/launchd.rb +0 -1
- data/lib/chef/provider/log.rb +3 -13
- data/lib/chef/provider/package/dnf.rb +1 -1
- data/lib/chef/provider/package/smartos.rb +2 -2
- data/lib/chef/provider/reboot.rb +12 -0
- data/lib/chef/provider/remote_directory.rb +1 -1
- data/lib/chef/provider/remote_file/http.rb +3 -2
- data/lib/chef/provider/service/solaris.rb +6 -2
- data/lib/chef/provider/systemd_unit.rb +34 -33
- data/lib/chef/provider/user/dscl.rb +1 -1
- data/lib/chef/provider/windows_path.rb +6 -7
- data/lib/chef/provider/windows_task.rb +89 -33
- data/lib/chef/provider/yum_repository.rb +24 -9
- data/lib/chef/resource/apt_package.rb +1 -0
- data/lib/chef/resource/apt_preference.rb +4 -0
- data/lib/chef/resource/apt_repository.rb +4 -0
- data/lib/chef/resource/apt_update.rb +3 -0
- data/lib/chef/resource/bash.rb +4 -0
- data/lib/chef/resource/batch.rb +5 -0
- data/lib/chef/resource/bff_package.rb +4 -0
- data/lib/chef/resource/breakpoint.rb +6 -0
- data/lib/chef/resource/cab_package.rb +6 -6
- data/lib/chef/resource/chef_gem.rb +13 -0
- data/lib/chef/resource/chocolatey_package.rb +4 -6
- data/lib/chef/resource/cookbook_file.rb +13 -15
- data/lib/chef/resource/cron.rb +2 -0
- data/lib/chef/resource/csh.rb +4 -0
- data/lib/chef/resource/directory.rb +8 -26
- data/lib/chef/resource/dnf_package.rb +5 -0
- data/lib/chef/resource/dpkg_package.rb +2 -0
- data/lib/chef/resource/dsc_resource.rb +5 -0
- data/lib/chef/resource/dsc_script.rb +6 -0
- data/lib/chef/resource/env.rb +3 -0
- data/lib/chef/resource/erl_call.rb +5 -0
- data/lib/chef/resource/execute.rb +5 -1
- data/lib/chef/resource/file.rb +2 -1
- data/lib/chef/resource/file/verification.rb +10 -0
- data/lib/chef/resource/freebsd_package.rb +10 -2
- data/lib/chef/resource/gem_package.rb +2 -0
- data/lib/chef/resource/git.rb +2 -0
- data/lib/chef/resource/group.rb +1 -0
- data/lib/chef/resource/homebrew_package.rb +3 -0
- data/lib/chef/resource/http_request.rb +2 -0
- data/lib/chef/resource/ifconfig.rb +23 -150
- data/lib/chef/resource/ips_package.rb +1 -0
- data/lib/chef/resource/ksh.rb +6 -0
- data/lib/chef/resource/launchd.rb +5 -4
- data/lib/chef/resource/link.rb +10 -0
- data/lib/chef/resource/log.rb +19 -46
- data/lib/chef/resource/macports_package.rb +1 -0
- data/lib/chef/resource/mdadm.rb +4 -0
- data/lib/chef/resource/mount.rb +1 -0
- data/lib/chef/resource/msu_package.rb +7 -8
- data/lib/chef/resource/ohai.rb +2 -0
- data/lib/chef/resource/openbsd_package.rb +3 -0
- data/lib/chef/resource/osx_profile.rb +10 -40
- data/lib/chef/resource/package.rb +6 -0
- data/lib/chef/resource/pacman_package.rb +1 -0
- data/lib/chef/resource/paludis_package.rb +3 -0
- data/lib/chef/resource/perl.rb +4 -0
- data/lib/chef/resource/portage_package.rb +1 -0
- data/lib/chef/resource/powershell_package.rb +5 -0
- data/lib/chef/resource/powershell_script.rb +8 -0
- data/lib/chef/resource/python.rb +4 -0
- data/lib/chef/resource/reboot.rb +14 -20
- data/lib/chef/resource/registry_key.rb +1 -0
- data/lib/chef/resource/remote_directory.rb +3 -0
- data/lib/chef/resource/remote_file.rb +2 -0
- data/lib/chef/resource/resource_notification.rb +17 -0
- data/lib/chef/resource/route.rb +1 -0
- data/lib/chef/resource/rpm_package.rb +1 -0
- data/lib/chef/resource/ruby.rb +4 -0
- data/lib/chef/resource/ruby_block.rb +3 -0
- data/lib/chef/resource/script.rb +4 -0
- data/lib/chef/resource/service.rb +1 -0
- data/lib/chef/resource/smartos_package.rb +1 -0
- data/lib/chef/resource/solaris_package.rb +1 -0
- data/lib/chef/resource/subversion.rb +1 -0
- data/lib/chef/resource/systemd_unit.rb +6 -0
- data/lib/chef/resource/template.rb +9 -0
- data/lib/chef/resource/user.rb +1 -0
- data/lib/chef/resource/windows_package.rb +2 -0
- data/lib/chef/resource/windows_path.rb +5 -10
- data/lib/chef/resource/windows_service.rb +3 -0
- data/lib/chef/resource/windows_task.rb +66 -87
- data/lib/chef/resource/yum_repository.rb +26 -22
- data/lib/chef/resource/zypper_package.rb +2 -0
- data/lib/chef/resource/zypper_repository.rb +6 -1
- data/lib/chef/run_context.rb +8 -2
- data/lib/chef/server_api.rb +1 -0
- data/lib/chef/util/selinux.rb +5 -4
- data/lib/chef/version.rb +1 -1
- data/lib/chef/version/platform.rb +18 -0
- data/lib/chef/version_constraint/platform.rb +2 -0
- data/spec/data/client.d_00/02-strings.rb +2 -0
- data/spec/functional/assets/chefinittest +6 -4
- data/spec/functional/knife/ssh_spec.rb +54 -7
- data/spec/functional/resource/bff_spec.rb +3 -3
- data/spec/functional/resource/ifconfig_spec.rb +1 -1
- data/spec/functional/resource/mount_spec.rb +7 -3
- data/spec/functional/resource/user/useradd_spec.rb +4 -4
- data/spec/functional/resource/windows_task_spec.rb +6 -6
- data/spec/functional/win32/security_spec.rb +7 -33
- data/spec/integration/knife/data_bag_show_spec.rb +1 -1
- data/spec/integration/recipes/noop_resource_spec.rb +1 -1
- data/spec/integration/recipes/recipe_dsl_spec.rb +30 -30
- data/spec/integration/recipes/resource_action_spec.rb +2 -2
- data/spec/integration/recipes/resource_converge_if_changed_spec.rb +71 -15
- data/spec/spec_helper.rb +19 -0
- data/spec/support/shared/functional/execute_resource.rb +1 -1
- data/spec/support/shared/unit/application_dot_d.rb +2 -0
- data/spec/support/shared/unit/execute_resource.rb +8 -1
- data/spec/support/shared/unit/provider/file.rb +9 -1
- data/spec/unit/chef_fs/data_handler/data_bag_item_data_handler.rb +10 -7
- data/spec/unit/chef_fs/file_system/repository/directory_spec.rb +2 -2
- data/spec/unit/client_spec.rb +1 -1
- data/spec/unit/deprecated_spec.rb +4 -4
- data/spec/unit/http_spec.rb +9 -0
- data/spec/unit/knife/bootstrap_spec.rb +5 -0
- data/spec/unit/knife/configure_spec.rb +10 -60
- data/spec/unit/knife/data_bag_create_spec.rb +40 -2
- data/spec/unit/knife/data_bag_show_spec.rb +16 -2
- data/spec/unit/knife/ssh_spec.rb +85 -39
- data/spec/unit/knife_spec.rb +2 -0
- data/spec/unit/lwrp_spec.rb +5 -3
- data/spec/unit/mixin/powershell_type_coercions_spec.rb +7 -6
- data/spec/unit/node/attribute_spec.rb +55 -24
- data/spec/unit/node/immutable_collections_spec.rb +28 -14
- data/spec/unit/node/vivid_mash_spec.rb +27 -10
- data/spec/unit/node_map_spec.rb +34 -0
- data/spec/unit/property_spec.rb +13 -13
- data/spec/unit/provider/group/dscl_spec.rb +14 -5
- data/spec/unit/provider/ifconfig_spec.rb +10 -3
- data/spec/unit/provider/remote_file/http_spec.rb +23 -19
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +6 -5
- data/spec/unit/provider/user/dscl_spec.rb +26 -0
- data/spec/unit/provider/windows_task_spec.rb +148 -4
- data/spec/unit/provider_spec.rb +1 -1
- data/spec/unit/resource/apt_package_spec.rb +1 -1
- data/spec/unit/resource/bash_spec.rb +8 -10
- data/spec/unit/resource/batch_spec.rb +1 -1
- data/spec/unit/resource/cab_package_spec.rb +19 -1
- data/spec/unit/resource/chef_gem_spec.rb +3 -3
- data/spec/unit/resource/chocolatey_package_spec.rb +10 -10
- data/spec/unit/resource/conditional_spec.rb +2 -2
- data/spec/unit/resource/cookbook_file_spec.rb +24 -30
- data/spec/unit/resource/cron_spec.rb +79 -82
- data/spec/unit/resource/csh_spec.rb +8 -10
- data/spec/unit/resource/deploy_spec.rb +1 -1
- data/spec/unit/resource/directory_spec.rb +28 -31
- data/spec/unit/resource/dnf_package_spec.rb +9 -9
- data/spec/unit/resource/env_spec.rb +7 -7
- data/spec/unit/resource/erl_call_spec.rb +9 -9
- data/spec/unit/resource/execute_spec.rb +6 -6
- data/spec/unit/resource/file/verification_spec.rb +18 -4
- data/spec/unit/resource/file_spec.rb +53 -56
- data/spec/unit/resource/freebsd_package_spec.rb +7 -7
- data/spec/unit/resource/gem_package_spec.rb +1 -1
- data/spec/unit/resource/git_spec.rb +7 -9
- data/spec/unit/resource/group_spec.rb +60 -70
- data/spec/unit/resource/http_request_spec.rb +16 -19
- data/spec/unit/resource/ifconfig_spec.rb +3 -3
- data/spec/unit/resource/ips_package_spec.rb +3 -5
- data/spec/unit/resource/ksh_spec.rb +8 -10
- data/spec/unit/resource/launchd_spec.rb +17 -10
- data/spec/unit/resource/link_spec.rb +53 -53
- data/spec/unit/resource/log_spec.rb +24 -28
- data/spec/unit/resource/mdadm_spec.rb +42 -44
- data/spec/unit/resource/mount_spec.rb +97 -99
- data/spec/unit/resource/msu_package_spec.rb +14 -8
- data/spec/unit/resource/ohai_spec.rb +15 -17
- data/spec/unit/resource/openbsd_package_spec.rb +3 -3
- data/spec/unit/resource/osx_profile_spec.rb +7 -7
- data/spec/unit/resource/package_spec.rb +36 -40
- data/spec/unit/resource/perl_spec.rb +8 -11
- data/spec/unit/resource/portage_package_spec.rb +8 -10
- data/spec/unit/resource/powershell_package_spec.rb +9 -9
- data/spec/unit/resource/python_spec.rb +8 -11
- data/spec/unit/resource/reboot_spec.rb +50 -0
- data/spec/unit/resource/registry_key_spec.rb +84 -98
- data/spec/unit/resource/remote_directory_spec.rb +40 -42
- data/spec/unit/resource/remote_file_spec.rb +78 -80
- data/spec/unit/resource/route_spec.rb +42 -44
- data/spec/unit/resource/rpm_package_spec.rb +5 -7
- data/spec/unit/resource/ruby_block_spec.rb +14 -16
- data/spec/unit/resource/ruby_spec.rb +8 -12
- data/spec/unit/resource/scm_spec.rb +66 -69
- data/spec/unit/resource/script_spec.rb +1 -1
- data/spec/unit/resource/service_spec.rb +80 -83
- data/spec/unit/resource/smartos_package_spec.rb +5 -0
- data/spec/unit/resource/solaris_package_spec.rb +3 -5
- data/spec/unit/resource/subversion_spec.rb +18 -16
- data/spec/unit/resource/systemd_unit_spec.rb +50 -54
- data/spec/unit/resource/template_spec.rb +56 -61
- data/spec/unit/resource/user_spec.rb +47 -53
- data/spec/unit/resource/windows_package_spec.rb +1 -1
- data/spec/unit/resource/windows_path_spec.rb +11 -8
- data/spec/unit/resource/windows_task_spec.rb +129 -33
- data/spec/unit/resource/yum_package_spec.rb +1 -1
- data/spec/unit/resource/yum_repository_spec.rb +61 -8
- data/spec/unit/resource/zypper_repository_spec.rb +17 -18
- data/spec/unit/util/selinux_spec.rb +3 -6
- data/tasks/dependencies.rb +0 -5
- data/tasks/rspec.rb +1 -1
- metadata +6 -6
- data/acceptance/top-cookbooks/.kitchen.docker.yml +0 -13
- data/acceptance/top-cookbooks/.kitchen.git.yml +0 -11
@@ -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(__path__)
|
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__)
|
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__)
|
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(__path__)
|
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__)
|
178
178
|
ret
|
179
179
|
end
|
180
180
|
|
data/lib/chef/node/common_api.rb
CHANGED
@@ -30,22 +30,16 @@ class Chef
|
|
30
30
|
e
|
31
31
|
end
|
32
32
|
|
33
|
-
def convert_value(value)
|
33
|
+
def convert_value(value, path = nil)
|
34
34
|
case value
|
35
35
|
when Hash
|
36
|
-
ImmutableMash.new(
|
36
|
+
ImmutableMash.new({}, __root__, __node__, __precedence__, path)
|
37
37
|
when Array
|
38
|
-
ImmutableArray.new(
|
39
|
-
when ImmutableMash, ImmutableArray
|
40
|
-
value
|
38
|
+
ImmutableArray.new([], __root__, __node__, __precedence__, path)
|
41
39
|
else
|
42
40
|
safe_dup(value).freeze
|
43
41
|
end
|
44
42
|
end
|
45
|
-
|
46
|
-
def immutablize(value)
|
47
|
-
convert_value(value)
|
48
|
-
end
|
49
43
|
end
|
50
44
|
|
51
45
|
# == ImmutableArray
|
@@ -59,17 +53,51 @@ class Chef
|
|
59
53
|
# Chef::Node::Attribute's values, it overrides all reader methods to
|
60
54
|
# detect staleness and raise an error if accessed when stale.
|
61
55
|
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
|
+
|
62
64
|
include Immutablize
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
+
methods = Array.instance_methods - Object.instance_methods +
|
67
|
+
[ :!, :!=, :<=>, :==, :===, :eql?, :to_s, :hash, :key, :has_key?, :inspect, :pretty_print, :pretty_print_inspect, :pretty_print_cycle, :pretty_print_instance_variables ]
|
66
68
|
|
67
|
-
|
68
|
-
|
69
|
-
|
69
|
+
methods.each do |method|
|
70
|
+
define_method method do |*args, &block|
|
71
|
+
ensure_generated_cache!
|
72
|
+
super(*args, &block)
|
70
73
|
end
|
71
74
|
end
|
72
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
|
96
|
+
|
97
|
+
def initialize(array_data = [])
|
98
|
+
# Immutable collections no longer have initialized state
|
99
|
+
end
|
100
|
+
|
73
101
|
# For elements like Fixnums, true, nil...
|
74
102
|
def safe_dup(e)
|
75
103
|
e.dup
|
@@ -96,8 +124,81 @@ class Chef
|
|
96
124
|
|
97
125
|
alias_method :to_array, :to_a
|
98
126
|
|
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
|
+
|
99
155
|
private
|
100
156
|
|
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
|
+
|
101
202
|
# needed for __path__
|
102
203
|
def convert_key(key)
|
103
204
|
key
|
@@ -120,19 +221,31 @@ class Chef
|
|
120
221
|
# it is stale.
|
121
222
|
# * Values can be accessed in attr_reader-like fashion via method_missing.
|
122
223
|
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
|
+
|
123
228
|
include Immutablize
|
124
229
|
include CommonAPI
|
125
230
|
|
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
|
+
|
126
241
|
# this is for deep_merge usage, chef users must never touch this API
|
127
242
|
# @api private
|
128
243
|
def internal_set(key, value)
|
129
|
-
regular_writer(key, convert_value(value))
|
244
|
+
regular_writer(key, convert_value(value, __path__ + [ key ]))
|
130
245
|
end
|
131
246
|
|
132
247
|
def initialize(mash_data = {})
|
133
|
-
|
134
|
-
internal_set(key, value)
|
135
|
-
end
|
248
|
+
# Immutable collections no longer have initialized state
|
136
249
|
end
|
137
250
|
|
138
251
|
alias :attribute? :has_key?
|
@@ -168,11 +281,55 @@ class Chef
|
|
168
281
|
|
169
282
|
alias_method :to_hash, :to_h
|
170
283
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
284
|
+
def [](key)
|
285
|
+
ensure_generated_cache!
|
286
|
+
super
|
287
|
+
end
|
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
|
176
333
|
end
|
177
334
|
|
178
335
|
prepend Chef::Node::Mixin::StateTracking
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright:: Copyright 2016, Chef Software
|
2
|
+
# Copyright:: Copyright 2016-2017, 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");
|
@@ -24,11 +24,12 @@ class Chef
|
|
24
24
|
attr_reader :__node__
|
25
25
|
attr_reader :__precedence__
|
26
26
|
|
27
|
-
def initialize(data = nil, root = self, node = nil, precedence = nil)
|
27
|
+
def initialize(data = nil, root = self, node = nil, precedence = nil, path = nil)
|
28
28
|
# __path__ and __root__ must be nil when we call super so it knows
|
29
29
|
# to avoid resetting the cache on construction
|
30
30
|
data.nil? ? super() : super(data)
|
31
|
-
@__path__ =
|
31
|
+
@__path__ = path
|
32
|
+
@__path__ ||= []
|
32
33
|
@__root__ = root
|
33
34
|
@__node__ = node
|
34
35
|
@__precedence__ = precedence
|
@@ -76,9 +77,8 @@ class Chef
|
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
79
|
-
def send_reset_cache(path
|
80
|
-
|
81
|
-
__root__.reset_cache(next_path.first) if !__root__.nil? && __root__.respond_to?(:reset_cache) && !next_path.nil?
|
80
|
+
def send_reset_cache(path)
|
81
|
+
__root__.reset_cache(*path) if !__root__.nil? && __root__.respond_to?(:reset_cache) && !path.nil?
|
82
82
|
end
|
83
83
|
|
84
84
|
def copy_state_to(ret, next_path)
|
data/lib/chef/node_map.rb
CHANGED
@@ -16,6 +16,25 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
+
#
|
20
|
+
# example of a NodeMap entry for the user resource (as typed on the DSL):
|
21
|
+
#
|
22
|
+
# :user=>
|
23
|
+
# [{:klass=>Chef::Resource::User::AixUser, :os=>"aix"},
|
24
|
+
# {:klass=>Chef::Resource::User::DsclUser, :os=>"darwin"},
|
25
|
+
# {:klass=>Chef::Resource::User::PwUser, :os=>"freebsd"},
|
26
|
+
# {:klass=>Chef::Resource::User::LinuxUser, :os=>"linux"},
|
27
|
+
# {:klass=>Chef::Resource::User::SolarisUser,
|
28
|
+
# :os=>["omnios", "solaris2"]},
|
29
|
+
# {:klass=>Chef::Resource::User::WindowsUser, :os=>"windows"}],
|
30
|
+
#
|
31
|
+
# the entries in the array are pre-sorted into priority order (blocks/platform_version/platform/platform_family/os/none) so that
|
32
|
+
# the first entry's :klass that matches the filter is returned when doing a get.
|
33
|
+
#
|
34
|
+
# note that as this examples show filter values may be a scalar string or an array of scalar strings.
|
35
|
+
#
|
36
|
+
# XXX: confusingly, in the *_priority_map the :klass may be an array of Strings of class names
|
37
|
+
#
|
19
38
|
class Chef
|
20
39
|
class NodeMap
|
21
40
|
|
@@ -31,13 +50,12 @@ class Chef
|
|
31
50
|
#
|
32
51
|
# @return [NodeMap] Returns self for possible chaining
|
33
52
|
#
|
34
|
-
def set(key,
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
new_matcher = { value: value, filters: filters }
|
53
|
+
def set(key, klass, platform: nil, platform_version: nil, platform_family: nil, os: nil, canonical: nil, override: nil, &block)
|
54
|
+
new_matcher = { klass: klass }
|
55
|
+
new_matcher[:platform] = platform if platform
|
56
|
+
new_matcher[:platform_version] = platform_version if platform_version
|
57
|
+
new_matcher[:platform_family] = platform_family if platform_family
|
58
|
+
new_matcher[:os] = os if os
|
41
59
|
new_matcher[:block] = block if block
|
42
60
|
new_matcher[:canonical] = canonical if canonical
|
43
61
|
new_matcher[:override] = override if override
|
@@ -48,7 +66,10 @@ class Chef
|
|
48
66
|
map[key] ||= []
|
49
67
|
map[key].each_with_index do |matcher, index|
|
50
68
|
cmp = compare_matchers(key, new_matcher, matcher)
|
51
|
-
|
69
|
+
if cmp && cmp <= 0
|
70
|
+
insert_at = index
|
71
|
+
break
|
72
|
+
end
|
52
73
|
end
|
53
74
|
if insert_at
|
54
75
|
map[key].insert(insert_at, new_matcher)
|
@@ -68,11 +89,14 @@ class Chef
|
|
68
89
|
# @param canonical [Boolean] `true` or `false` to match canonical or
|
69
90
|
# non-canonical values only. `nil` to ignore canonicality. Default: `nil`
|
70
91
|
#
|
71
|
-
# @return [Object]
|
92
|
+
# @return [Object] Class
|
72
93
|
#
|
73
94
|
def get(node, key, canonical: nil)
|
74
|
-
|
75
|
-
|
95
|
+
return nil unless map.has_key?(key)
|
96
|
+
map[key].map do |matcher|
|
97
|
+
return matcher[:klass] if node_matches?(node, matcher) && canonical_matches?(canonical, matcher)
|
98
|
+
end
|
99
|
+
nil
|
76
100
|
end
|
77
101
|
|
78
102
|
#
|
@@ -85,23 +109,22 @@ class Chef
|
|
85
109
|
# @param canonical [Boolean] `true` or `false` to match canonical or
|
86
110
|
# non-canonical values only. `nil` to ignore canonicality. Default: `nil`
|
87
111
|
#
|
88
|
-
# @return [Object]
|
112
|
+
# @return [Object] Class
|
89
113
|
#
|
90
114
|
def list(node, key, canonical: nil)
|
91
|
-
raise ArgumentError, "first argument must be a Chef::Node" unless node.is_a?(Chef::Node) || node.nil?
|
92
115
|
return [] unless map.has_key?(key)
|
93
116
|
map[key].select do |matcher|
|
94
117
|
node_matches?(node, matcher) && canonical_matches?(canonical, matcher)
|
95
|
-
end.map { |matcher| matcher[:
|
118
|
+
end.map { |matcher| matcher[:klass] }
|
96
119
|
end
|
97
120
|
|
98
121
|
# Seriously, don't use this, it's nearly certain to change on you
|
99
122
|
# @return remaining
|
100
123
|
# @api private
|
101
|
-
def delete_canonical(key,
|
124
|
+
def delete_canonical(key, klass)
|
102
125
|
remaining = map[key]
|
103
126
|
if remaining
|
104
|
-
remaining.delete_if { |matcher| matcher[:canonical] && Array(matcher[:
|
127
|
+
remaining.delete_if { |matcher| matcher[:canonical] && Array(matcher[:klass]) == Array(klass) }
|
105
128
|
if remaining.empty?
|
106
129
|
map.delete(key)
|
107
130
|
remaining = nil
|
@@ -143,7 +166,7 @@ class Chef
|
|
143
166
|
|
144
167
|
filter_values.empty? ||
|
145
168
|
Array(filter_values).any? do |v|
|
146
|
-
|
169
|
+
Gem::Requirement.new(v).satisfied_by?(Gem::Version.new(value))
|
147
170
|
end
|
148
171
|
end
|
149
172
|
|
@@ -161,7 +184,7 @@ class Chef
|
|
161
184
|
|
162
185
|
def node_matches?(node, matcher)
|
163
186
|
return true if !node
|
164
|
-
filters_match?(node, matcher
|
187
|
+
filters_match?(node, matcher) && block_matches?(node, matcher[:block])
|
165
188
|
end
|
166
189
|
|
167
190
|
def canonical_matches?(canonical, matcher)
|
@@ -171,17 +194,17 @@ class Chef
|
|
171
194
|
|
172
195
|
# @api private
|
173
196
|
def dispatch_compare_matchers(key, new_matcher, matcher)
|
174
|
-
cmp = compare_matcher_properties(new_matcher, matcher
|
197
|
+
cmp = compare_matcher_properties(new_matcher[:block], matcher[:block])
|
175
198
|
return cmp if cmp != 0
|
176
|
-
cmp = compare_matcher_properties(new_matcher, matcher
|
199
|
+
cmp = compare_matcher_properties(new_matcher[:platform_version], matcher[:platform_version])
|
177
200
|
return cmp if cmp != 0
|
178
|
-
cmp = compare_matcher_properties(new_matcher, matcher
|
201
|
+
cmp = compare_matcher_properties(new_matcher[:platform], matcher[:platform])
|
179
202
|
return cmp if cmp != 0
|
180
|
-
cmp = compare_matcher_properties(new_matcher, matcher
|
203
|
+
cmp = compare_matcher_properties(new_matcher[:platform_family], matcher[:platform_family])
|
181
204
|
return cmp if cmp != 0
|
182
|
-
cmp = compare_matcher_properties(new_matcher, matcher
|
205
|
+
cmp = compare_matcher_properties(new_matcher[:os], matcher[:os])
|
183
206
|
return cmp if cmp != 0
|
184
|
-
cmp = compare_matcher_properties(new_matcher, matcher
|
207
|
+
cmp = compare_matcher_properties(new_matcher[:override], matcher[:override])
|
185
208
|
return cmp if cmp != 0
|
186
209
|
# If all things are identical, return 0
|
187
210
|
0
|
@@ -195,37 +218,32 @@ class Chef
|
|
195
218
|
if cmp == 0
|
196
219
|
# Sort by class name (ascending) as well, if all other properties
|
197
220
|
# are exactly equal
|
198
|
-
|
199
|
-
|
221
|
+
# XXX: remove this in Chef-14 and use last-writer-wins (prepend if they match)
|
222
|
+
if !new_matcher[:override]
|
223
|
+
# we only sort classes, which only sorts the handler array, this magically does not sort
|
224
|
+
# the priority array via the invisible else here.
|
225
|
+
if new_matcher[:klass].is_a?(Class)
|
226
|
+
cmp = compare_matcher_properties(new_matcher[:klass].name, matcher[:klass].name)
|
227
|
+
end
|
200
228
|
end
|
201
229
|
end
|
202
230
|
cmp
|
203
231
|
end
|
204
232
|
|
205
|
-
def compare_matcher_properties(
|
206
|
-
|
207
|
-
|
233
|
+
def compare_matcher_properties(a, b)
|
234
|
+
# falsity comparisons here handle both "nil" and "false"
|
235
|
+
return 1 if !a && b
|
236
|
+
return -1 if !b && a
|
237
|
+
return 0 if !a && !b
|
208
238
|
|
209
|
-
# Check for
|
239
|
+
# Check for blacklists ('!windows'). Those always come *after* positive
|
210
240
|
# whitelists.
|
211
241
|
a_negated = Array(a).any? { |f| f.is_a?(String) && f.start_with?("!") }
|
212
242
|
b_negated = Array(b).any? { |f| f.is_a?(String) && f.start_with?("!") }
|
213
|
-
if a_negated
|
214
|
-
|
215
|
-
return -1 if b_negated
|
216
|
-
end
|
243
|
+
return 1 if a_negated && !b_negated
|
244
|
+
return -1 if b_negated && !a_negated
|
217
245
|
|
218
|
-
|
219
|
-
a = nil if a == false
|
220
|
-
b = nil if b == false
|
221
|
-
cmp = a <=> b
|
222
|
-
# This is the case where one is non-nil, and one is nil. The one that is
|
223
|
-
# nil is "greater" (i.e. it should come last).
|
224
|
-
if cmp.nil?
|
225
|
-
return 1 if a.nil?
|
226
|
-
return -1 if b.nil?
|
227
|
-
end
|
228
|
-
cmp
|
246
|
+
a <=> b
|
229
247
|
end
|
230
248
|
|
231
249
|
def map
|