summaryrefslogtreecommitdiff
path: root/lib/chef/provider_resolver.rb
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2017-03-27 11:55:40 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2017-03-27 12:05:17 -0700
commitd82ac7a7c66ffcf6120092f536dd41a9c06db872 (patch)
tree429e9baad7b9e2fe1324945fe42fa755351e1327 /lib/chef/provider_resolver.rb
parentaccb4846106ca4601104a445da0d3544d4c1bf55 (diff)
downloadchef-d82ac7a7c66ffcf6120092f536dd41a9c06db872.tar.gz
Fix Chef-13 action_class bug and cleanup
The old action_class code was doing some magical stuff with the provider accessor in order to determine if the class was supposed to be a custom resource or not and have the action_class autovivifying accessor return nil in cases when the resource wasn't a custom resource and implementing inheritance by walking back up the tree in ways that were difficult to grok. This removes the magic from the provider so that there's no longer any accessor that magically short-circuits to nil if the resource is not supposed to be a custom resource. There is now a simple inherited API for `Chef::Resource.custom_resource?` which just defines if the class is a custom resource or not. Since both `action` and `action_class` call `define_action_class` they both wind up setting this boolean on the class, which is then inherited to subclasses automatically, which eliminates the need to walk up the hierarchy. The superclass.respond_to?(:action_class) checks have also been rendered unnecessary by removing the code that walked up the inheritance hierarchy and also because Chef::Resource is never going to be a custom resource itself, so will never call `define_action_class` so from inside of `define_action_class` you can always rely on the superclass being a resource and implementing `custom_resource?` and `action_class`. The wiring for picking the provider is now moved explicitly to the ProviderResolver -- even though custom resources hardcode a 1:1 resource-to-provider mapping. This reads much clearer to me than the magical wiring to the provider accessor off of the instance. The bug that this fixes was that the way the magical accessor nil-or-action_class was implemented the old way of defining action helpers with class_eval broke: ```ruby action_class.class_eval << EOM def a "foo" end EOM ``` If that came before any action_class-with-a-block or action declaration and the resource did not inherit from another custom resource then the action_class would not be created and it would return nil, which was an API which the magical wiring in the provider accessor required. Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
Diffstat (limited to 'lib/chef/provider_resolver.rb')
-rw-r--r--lib/chef/provider_resolver.rb9
1 files changed, 7 insertions, 2 deletions
diff --git a/lib/chef/provider_resolver.rb b/lib/chef/provider_resolver.rb
index 439a7e9f5f..16e57b00b8 100644
--- a/lib/chef/provider_resolver.rb
+++ b/lib/chef/provider_resolver.rb
@@ -58,6 +58,7 @@ class Chef
def resolve
maybe_explicit_provider(resource) ||
+ maybe_custom_resource(resource) ||
maybe_dynamic_provider_resolution(resource, action) ||
raise(Chef::Exceptions::ProviderNotFound, "Cannot find a provider for #{resource} on #{node["platform"]} version #{node["platform_version"]}")
end
@@ -105,10 +106,14 @@ class Chef
end
end
+ # if its a custom resource, just grab the action class
+ def maybe_custom_resource(resource)
+ resource.class.action_class if resource.class.custom_resource?
+ end
+
# if resource.provider is set, just return one of those objects
def maybe_explicit_provider(resource)
- return nil unless resource.provider
- resource.provider
+ resource.provider if resource.provider
end
# try dynamically finding a provider based on querying the providers to see what they support