diff options
author | John Keiser <john@johnkeiser.com> | 2015-05-07 16:24:45 -0700 |
---|---|---|
committer | John Keiser <john@johnkeiser.com> | 2015-05-13 13:43:15 -0700 |
commit | 146f0809c1912988751688fff2ef6945c90a4513 (patch) | |
tree | 96e6ac327717318984930b84f69d8690a78b631c /lib | |
parent | 0700ce4cd87825c6a925036ad5143ceb79438d38 (diff) | |
download | chef-146f0809c1912988751688fff2ef6945c90a4513.tar.gz |
Deprecate Chef::Provider::LwrpClass the same way we did Resource
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/provider.rb | 28 | ||||
-rw-r--r-- | lib/chef/provider/lwrp_base.rb | 135 | ||||
-rw-r--r-- | lib/chef/resource.rb | 63 | ||||
-rw-r--r-- | lib/chef/resource/lwrp_base.rb | 8 |
4 files changed, 140 insertions, 94 deletions
diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb index 65a56cf726..3ab4d4d2b1 100644 --- a/lib/chef/provider.rb +++ b/lib/chef/provider.rb @@ -191,5 +191,33 @@ class Chef end end + module DeprecatedLWRPClass + def const_missing(class_name) + if deprecated_constants[class_name.to_sym] + Chef::Log.deprecation("Using an LWRP provider by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::ProviderResolver.new(node, resource, action) instead.") + deprecated_constants[class_name.to_sym] + else + raise NameError, "uninitialized constant Chef::Provider::#{class_name}" + end + end + + # @api private + def register_deprecated_lwrp_class(provider_class, class_name) + # Register Chef::Provider::MyProvider with deprecation warnings if you + # try to access it + if Chef::Provider.const_defined?(class_name, false) + Chef::Log.warn "Chef::Provider::#{class_name} already exists! Cannot create deprecation class for #{provider_class}" + else + deprecated_constants[class_name.to_sym] = provider_class + end + end + + private + + def deprecated_constants + @deprecated_constants ||= {} + end + end + extend DeprecatedLWRPClass end end diff --git a/lib/chef/provider/lwrp_base.rb b/lib/chef/provider/lwrp_base.rb index 0eadfe9467..38430ced6d 100644 --- a/lib/chef/provider/lwrp_base.rb +++ b/lib/chef/provider/lwrp_base.rb @@ -69,9 +69,6 @@ class Chef end - extend Chef::Mixin::ConvertToClassName - extend Chef::Mixin::FromFile - include Chef::DSL::Recipe # These were previously provided by Chef::Mixin::RecipeDefinitionDSLCore. @@ -80,72 +77,92 @@ class Chef include Chef::DSL::PlatformIntrospection include Chef::DSL::DataQuery - def self.build_from_file(cookbook_name, filename, run_context) - provider_class = nil - provider_name = filename_to_qualified_string(cookbook_name, filename) + # no-op `load_current_resource`. Allows simple LWRP providers to work + # without defining this method explicitly (silences + # Chef::Exceptions::Override exception) + def load_current_resource + end + + # class methods + class <<self + include Chef::Mixin::ConvertToClassName + include Chef::Mixin::FromFile + + def build_from_file(cookbook_name, filename, run_context) + if LWRPBase.loaded_lwrps[filename] + Chef::Log.info("LWRP provider #{filename} from cookbook #{cookbook_name} has already been loaded! Skipping the reload.") + return loaded_lwrps[filename] + end - class_name = convert_to_class_name(provider_name) + resource_name = filename_to_qualified_string(cookbook_name, filename) - if Chef::Provider.const_defined?(class_name, false) - Chef::Log.info("#{class_name} light-weight provider is already initialized -- Skipping loading #{filename}!") - Chef::Log.debug("Overriding already defined LWRPs is not supported anymore starting with Chef 12.") - provider_class = Chef::Provider.const_get(class_name) - else + # We load the class first to give it a chance to set its own name provider_class = Class.new(self) - Chef::Provider.const_set(class_name, provider_class) - provider_class.provides provider_name.to_sym + provider_class.provides resource_name.to_sym provider_class.class_from_file(filename) - Chef::Log.debug("Loaded contents of #{filename} into a provider named #{provider_name} defined in Chef::Provider::#{class_name}") - end - provider_class - end + # Respect resource_name set inside the LWRP + provider_class.instance_eval do + define_method(:to_s) do + "LWRP provider #{resource_name} from cookbook #{cookbook_name}" + end + define_method(:inspect) { to_s } + end - # Enables inline evaluation of resources in provider actions. - # - # Without this option, any resources declared inside the LWRP are added - # to the resource collection after the current position at the time the - # action is executed. Because they are added to the primary resource - # collection for the chef run, they can notify other resources outside - # the LWRP, and potentially be notified by resources outside the LWRP - # (but this is complicated by the fact that they don't exist until the - # provider executes). In this mode, it is impossible to correctly set the - # updated_by_last_action flag on the parent LWRP resource, since it - # executes and returns before its component resources are run. - # - # With this option enabled, each action creates a temporary run_context - # with its own resource collection, evaluates the action's code in that - # context, and then converges the resources created. If any resources - # were updated, then this provider's new_resource will be marked updated. - # - # In this mode, resources created within the LWRP cannot interact with - # external resources via notifies, though notifications to other - # resources within the LWRP will work. Delayed notifications are executed - # at the conclusion of the provider's action, *not* at the end of the - # main chef run. - # - # This mode of evaluation is experimental, but is believed to be a better - # set of tradeoffs than the append-after mode, so it will likely become - # the default in a future major release of Chef. - # - def self.use_inline_resources - extend InlineResources::ClassMethods - include InlineResources - end + Chef::Log.debug("Loaded contents of #{filename} into provider #{resource_name} (#{provider_class})") + + LWRPBase.loaded_lwrps[filename] = true - # DSL for defining a provider's actions. - def self.action(name, &block) - define_method("action_#{name}") do - instance_eval(&block) + Chef::Provider.register_deprecated_lwrp_class(provider_class, convert_to_class_name(resource_name)) + + provider_class end - end - # no-op `load_current_resource`. Allows simple LWRP providers to work - # without defining this method explicitly (silences - # Chef::Exceptions::Override exception) - def load_current_resource - end + # Enables inline evaluation of resources in provider actions. + # + # Without this option, any resources declared inside the LWRP are added + # to the resource collection after the current position at the time the + # action is executed. Because they are added to the primary resource + # collection for the chef run, they can notify other resources outside + # the LWRP, and potentially be notified by resources outside the LWRP + # (but this is complicated by the fact that they don't exist until the + # provider executes). In this mode, it is impossible to correctly set the + # updated_by_last_action flag on the parent LWRP resource, since it + # executes and returns before its component resources are run. + # + # With this option enabled, each action creates a temporary run_context + # with its own resource collection, evaluates the action's code in that + # context, and then converges the resources created. If any resources + # were updated, then this provider's new_resource will be marked updated. + # + # In this mode, resources created within the LWRP cannot interact with + # external resources via notifies, though notifications to other + # resources within the LWRP will work. Delayed notifications are executed + # at the conclusion of the provider's action, *not* at the end of the + # main chef run. + # + # This mode of evaluation is experimental, but is believed to be a better + # set of tradeoffs than the append-after mode, so it will likely become + # the default in a future major release of Chef. + # + def use_inline_resources + extend InlineResources::ClassMethods + include InlineResources + end + + # DSL for defining a provider's actions. + def action(name, &block) + define_method("action_#{name}") do + instance_eval(&block) + end + end + + protected + def loaded_lwrps + @loaded_lwrps ||= {} + end + end end end end diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 6030572be6..e62e63a44a 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -32,6 +32,8 @@ require 'chef/node_map' require 'chef/node' require 'chef/platform' require 'chef/resource/resource_notification' +require 'chef/provider_resolver' +require 'chef/resource_resolver' require 'chef/mixin/deprecation' require 'chef/mixin/provides' @@ -684,6 +686,8 @@ class Chef # def provider(arg=nil) klass = if arg.kind_of?(String) || arg.kind_of?(Symbol) + # TODO deprecate. This does class munging. If you know + # the class name, just pass the class. lookup_provider_constant(arg) else arg @@ -1036,7 +1040,6 @@ class Chef end def provider_for_action(action) - require 'chef/provider_resolver' provider = Chef::ProviderResolver.new(node, self, action).resolve.new(self, run_context) provider.action = action provider @@ -1110,7 +1113,6 @@ class Chef # === Returns # <Chef::Resource>:: returns the proper Chef::Resource class def self.resource_for_node(short_name, node) - require 'chef/resource_resolver' klass = Chef::ResourceResolver.new(node, short_name).resolve raise Chef::Exceptions::NoSuchResourceType.new(short_name, node) if klass.nil? klass @@ -1143,43 +1145,42 @@ class Chef end end - def self.const_missing(class_name) - if deprecated_constants[class_name.to_sym] - Chef::Log.deprecation("Using an LWRP by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::Resource.resource_for_node(node, name) instead.") - deprecated_constants[class_name.to_sym] - else - raise NameError, "uninitialized constant Chef::Resource::#{class_name}" + # Implement deprecated LWRP class + module DeprecatedLWRPClass + # @api private + def register_deprecated_lwrp_class(resource_class, class_name) + if Chef::Resource.const_defined?(class_name, false) + Chef::Log.warn "#{class_name} already exists! Cannot create deprecation class for #{resource_class}" + else + deprecated_constants[class_name.to_sym] = resource_class + end end - end - # @api private - def self.create_deprecated_lwrp_class(resource_class) - # Create a class in Chef::Resource::MyResource with deprecation - # warnings if you try to access it - class_name = convert_to_class_name(resource_class.resource_name) - if Chef::Resource.const_defined?(class_name, false) - Chef::Log.warn "#{class_name} already exists! Cannot create deprecation class for #{resource_class}" - else - deprecated_constants[class_name.to_sym] = resource_class + def const_missing(class_name) + if deprecated_constants[class_name.to_sym] + Chef::Log.deprecation("Using an LWRP by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::Resource.resource_for_node(node, name) instead.") + deprecated_constants[class_name.to_sym] + else + raise NameError, "uninitialized constant Chef::Resource::#{class_name}" + end end - end - private + private - def self.deprecated_constants - @deprecated_constants ||= {} + def deprecated_constants + @deprecated_constants ||= {} + end end + extend DeprecatedLWRPClass - def lookup_provider_constant(name) - begin - self.class.provider_base.const_get(convert_to_class_name(name.to_s)) - rescue NameError => e - if e.to_s =~ /#{Regexp.escape(self.class.provider_base.to_s)}/ - raise ArgumentError, "No provider found to match '#{name}'" - else - raise e - end + def lookup_provider_constant(name, action=:nothing) + resource = Chef::Resource.new(self.name, self.run_context) + resource.instance_eval { @resource_name = name } + provider = Chef::ProviderResolver.new(self.node, resource, action).resolve + if !provider + raise ArgumentError, "No provider found to match '#{name}'" end + provider end end end diff --git a/lib/chef/resource/lwrp_base.rb b/lib/chef/resource/lwrp_base.rb index 40c44f83f9..c79c205285 100644 --- a/lib/chef/resource/lwrp_base.rb +++ b/lib/chef/resource/lwrp_base.rb @@ -47,7 +47,7 @@ class Chef def build_from_file(cookbook_name, filename, run_context) if LWRPBase.loaded_lwrps[filename] - Chef::Log.info("LWRP provider #{filename} from cookbook #{cookbook_name} has already been loaded! Skipping the reload.") + Chef::Log.info("LWRP resource #{filename} from cookbook #{cookbook_name} has already been loaded! Skipping the reload.") return loaded_lwrps[filename] end @@ -63,16 +63,16 @@ class Chef # Respect resource_name set inside the LWRP resource_class.instance_eval do define_method(:to_s) do - "LWRP #{resource_name} from cookbook #{cookbook_name}" + "LWRP resource #{resource_name} from cookbook #{cookbook_name}" end define_method(:inspect) { to_s } end - Chef::Log.debug("Loaded contents of #{filename} into #{resource_class}") + Chef::Log.debug("Loaded contents of #{filename} into resource #{resource_name} (#{resource_class})") LWRPBase.loaded_lwrps[filename] = true - Chef::Resource.create_deprecated_lwrp_class(resource_class) + Chef::Resource.register_deprecated_lwrp_class(resource_class, convert_to_class_name(resource_name)) resource_class end |