summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2015-05-01 21:35:34 -0700
committerJohn Keiser <john@johnkeiser.com>2015-05-07 17:02:12 -0700
commit47ca29fdc5a72ac41c189df17d687b2bb4e67b06 (patch)
tree35c43017fc78f8c739e53c476b26f672f5da01e9
parent3c3fd120627fa6083d51592a9c89d3b7145a4139 (diff)
downloadchef-47ca29fdc5a72ac41c189df17d687b2bb4e67b06.tar.gz
Add `provides` to remaining provider resources
-rw-r--r--lib/chef/provider/cron/unix.rb1
-rw-r--r--lib/chef/provider/ohai.rb1
-rw-r--r--lib/chef/provider/reboot.rb1
-rw-r--r--lib/chef/provider/registry_key.rb2
-rw-r--r--lib/chef/provider/remote_file.rb1
-rw-r--r--lib/chef/provider_resolver.rb87
6 files changed, 93 insertions, 0 deletions
diff --git a/lib/chef/provider/cron/unix.rb b/lib/chef/provider/cron/unix.rb
index 0750c0420b..01c61e4253 100644
--- a/lib/chef/provider/cron/unix.rb
+++ b/lib/chef/provider/cron/unix.rb
@@ -20,6 +20,7 @@
require 'chef/log'
require 'chef/provider'
+require 'chef/provider/cron'
class Chef
class Provider
diff --git a/lib/chef/provider/ohai.rb b/lib/chef/provider/ohai.rb
index a6b5ab5daa..b7f4aa704b 100644
--- a/lib/chef/provider/ohai.rb
+++ b/lib/chef/provider/ohai.rb
@@ -21,6 +21,7 @@ require 'ohai'
class Chef
class Provider
class Ohai < Chef::Provider
+ provides :ohai
def whyrun_supported?
true
diff --git a/lib/chef/provider/reboot.rb b/lib/chef/provider/reboot.rb
index 8dde4653ec..22e77dcc13 100644
--- a/lib/chef/provider/reboot.rb
+++ b/lib/chef/provider/reboot.rb
@@ -22,6 +22,7 @@ require 'chef/provider'
class Chef
class Provider
class Reboot < Chef::Provider
+ provides :reboot
def whyrun_supported?
true
diff --git a/lib/chef/provider/registry_key.rb b/lib/chef/provider/registry_key.rb
index 94f4e2655b..cd62f7c56f 100644
--- a/lib/chef/provider/registry_key.rb
+++ b/lib/chef/provider/registry_key.rb
@@ -31,6 +31,8 @@ class Chef
class Provider
class RegistryKey < Chef::Provider
+ provides :registry_key
+
include Chef::Mixin::Checksum
def whyrun_supported?
diff --git a/lib/chef/provider/remote_file.rb b/lib/chef/provider/remote_file.rb
index da2573dacb..c4643edc0b 100644
--- a/lib/chef/provider/remote_file.rb
+++ b/lib/chef/provider/remote_file.rb
@@ -24,6 +24,7 @@ require 'chef/deprecation/warnings'
class Chef
class Provider
class RemoteFile < Chef::Provider::File
+ provides :remote_file
extend Chef::Deprecation::Warnings
include Chef::Deprecation::Provider::RemoteFile
diff --git a/lib/chef/provider_resolver.rb b/lib/chef/provider_resolver.rb
index 5e887225e4..7c7bac0443 100644
--- a/lib/chef/provider_resolver.rb
+++ b/lib/chef/provider_resolver.rb
@@ -20,6 +20,93 @@ require 'chef/exceptions'
require 'chef/platform/provider_priority_map'
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.
+ #
+ # 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
+ #
+ # 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`.
+ #
+ # NOTE: this behavior is now deprecated.
+ #
class ProviderResolver
attr_reader :node