summaryrefslogtreecommitdiff
path: root/lib/chef/provider_resolver.rb
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2015-05-06 17:56:44 -0700
committerJohn Keiser <john@johnkeiser.com>2015-06-02 09:53:40 -0700
commit71c89b652687021c89a630a00224deccdc5e05a5 (patch)
treed20378764181d448e386ab4de20b3181cdbc1f47 /lib/chef/provider_resolver.rb
parentfa0b9a5a92c477ef5ea84bf90a266943bb1a04c9 (diff)
downloadchef-71c89b652687021c89a630a00224deccdc5e05a5.tar.gz
Remove platform mapping from lookup, add comment about how resolution now works
Diffstat (limited to 'lib/chef/provider_resolver.rb')
-rw-r--r--lib/chef/provider_resolver.rb94
1 files changed, 15 insertions, 79 deletions
diff --git a/lib/chef/provider_resolver.rb b/lib/chef/provider_resolver.rb
index ea28062bac..4b194c5713 100644
--- a/lib/chef/provider_resolver.rb
+++ b/lib/chef/provider_resolver.rb
@@ -24,88 +24,25 @@ class Chef
# Provider Resolution
# ===================
#
- # When you type `service 'myservice' { action :restart }` in a recipe, a whole
- # string of events happens eventually leading to convergence. The overview of
- # that process is described in `Chef::DSL::Recipe`. Provider resolution is
- # the process of taking a Resource object and an action, and determining the
- # Provider class that should be instantiated to handle the action.
+ # Provider resolution is the process of taking a Resource object and an
+ # action, and determining the Provider class that should be instantiated to
+ # handle the action.
#
- # The process happens in three steps:
- #
- # Explicit Provider on the Resource
- # ---------------------------------
# If the resource has its `provider` set, that is used.
#
- # Dynamic Provider Matches
- # ------------------------
- # In this stage, we call `provides?` to see if the Provider supports the
- # resource on this platform, and then we call `supports?` to determine if it
- # can handle the action. It's a little more complicated than that, though:
- #
- # ### Provider.provides?
- #
- # First, we go through all known provider classes (all descendants of
- # `Chef::Provider`), and call `provides?(node, resource)` to determine if it
- # supports this action for this resource on this OS. We get a list of all
- # matches.
- #
- # #### Defining provides
- #
- # The typical way of getting `provides?` is for the Provider class to call
- # `provides :name`.
- #
- # The Provider may pass the OS, platform family, platform, and platform version
- # to `provides`, and they will be matched against the values in the `node`
- # object. The Provider may also pass a block, which allows for custom logic
- # to decide whether it provides the resource or not.
- #
- # Some Providers also override `provides?` with custom logic.
- #
- # ### Provider.supports?
- #
- # Once we have the list of willing providers, we filter it by calling their
- # `supports?(resource, action)` method to see if they support the specific
- # action (`:create`, `:delete`) or not.
- #
- # If no provider supports the specific action, we fall back to the full list
- # of matches from step 1. (TODO The comment says it's for why run. I'm not
- # sure what that means specifically yet.)
- #
- # ### Priority lists: Chef.get_provider_priority_array
- #
- # Once we have the list of matches, we look at `Chef.get_provider_priority_array(node, resource)`
- # to see if anyone has set a *priority list*. This method takes
- # the the first matching priority list for this OS (which is the last list
- # that was registered).
- #
- # If any of our matches are on the priority list, we take the first one.
- #
- # If there is no priority list or no matches on it, we take the first result
- # alphabetically by class name.
- #
- # Chef::Platform Provider Map
- # ---------------------------
- # If we still have no matches, we try `Chef::Platform.find_provider_for_node(node, resource)`.
- # This does two new things:
- #
- # ### System Provider Map
- #
- # The system provider map is a large Hash loaded during `require` time,
- # which shows system-specific providers by os/platform, and platform_version.
- # It keys off of `node[:platform] || node[:os]`, and `node[:platform_version]
- # || node[:os_version] || node[:os_release]`. The version uses typical gem
- # constraints like > and <=.
- #
- # The first platform+version match wins over the first platform-only match,
- # which wins over the default.
- #
- # ### Chef::Provider::FooBar
+ # Otherwise, we take the lists of Providers that have registered as
+ # providing the DSL through `provides :dsl_name, <filters>` or
+ # `Chef.set_resource_priority_array :dsl_name, <filters>`. We filter each
+ # list of Providers through:
#
- # As a last resort, if there are *still* no classes, the system transforms the
- # DSL name `foo_bar` into `Chef::Provider::FooBar`, and returns the class if
- # it is there and descends from `Chef::Provider`.
+ # 1. The filters it was registered with (such as `os: 'linux'` or
+ # `platform_family: 'debian'`)
+ # 2. `provides?(node, resource)`
+ # 3. `supports?(resource, action)`
#
- # NOTE: this behavior is now deprecated.
+ # Anything that passes the filter and returns `true` to provides and supports,
+ # is considered a match. The first matching Provider in the *most recently
+ # registered list* is selected and returned.
#
class ProviderResolver
@@ -121,8 +58,7 @@ class Chef
def resolve
maybe_explicit_provider(resource) ||
- maybe_dynamic_provider_resolution(resource, action) ||
- maybe_chef_platform_lookup(resource)
+ maybe_dynamic_provider_resolution(resource, action)
end
def provided_by?(provider_class)