diff options
Diffstat (limited to 'lib')
30 files changed, 190 insertions, 143 deletions
diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index a0c74f7aec..563e06434b 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -28,6 +28,8 @@ require 'chef/platform/provider_priority_map' require 'chef/platform/resource_priority_map' +require 'chef/platform/provider_handler_map' +require 'chef/platform/resource_handler_map' class Chef class << self @@ -160,20 +162,26 @@ class Chef @node = nil @provider_priority_map = nil @resource_priority_map = nil + @provider_dsl_map = nil + @resource_dsl_map = nil end # @api private def provider_priority_map - @provider_priority_map ||= begin - # these slurp in the resource+provider world, so be exceedingly lazy about requiring them - Chef::Platform::ProviderPriorityMap.instance - end + # these slurp in the resource+provider world, so be exceedingly lazy about requiring them + @provider_priority_map ||= Chef::Platform::ProviderPriorityMap.instance end # @api private def resource_priority_map - @resource_priority_map ||= begin - Chef::Platform::ResourcePriorityMap.instance - end + @resource_priority_map ||= Chef::Platform::ResourcePriorityMap.instance + end + # @api private + def provider_handler_map + @provider_handler_map ||= Chef::Platform::ProviderHandlerMap.instance + end + # @api private + def resource_handler_map + @resource_handler_map ||= Chef::Platform::ResourceHandlerMap.instance end end diff --git a/lib/chef/platform/handler_map.rb b/lib/chef/platform/handler_map.rb new file mode 100644 index 0000000000..001eb3dc8f --- /dev/null +++ b/lib/chef/platform/handler_map.rb @@ -0,0 +1,45 @@ +# +# Author:: John Keiser (<jkeiser@chef.io>) +# Copyright:: Copyright (c) 2015 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'chef/node_map' + +class Chef + class Platform + class HandlerMap < Chef::NodeMap + # + # "provides" lines with identical filters sort by class name (ascending). + # + def compare_matchers(key, new_matcher, matcher) + cmp = super + if cmp == 0 + # Sort by class name (ascending) as well, if all other properties + # are exactly equal + if new_matcher[:value].is_a?(Class) && !new_matcher[:override] + cmp = compare_matcher_properties(new_matcher, matcher) { |m| m[:value].name } + if cmp < 0 + Chef::Log.warn "You are overriding #{key} on #{new_matcher[:filters].inspect} with #{new_matcher[:value].inspect}: used to be #{matcher[:value].inspect}. Use override: true if this is what you intended." + elsif cmp > 0 + Chef::Log.warn "You declared a new resource #{new_matcher[:value].inspect} for resource #{key}, but it comes alphabetically after #{matcher[:value].inspect} and has the same filters (#{new_matcher[:filters].inspect}), so it will not be used. Use override: true if you want to use it for #{key}." + end + end + end + cmp + end + end + end +end diff --git a/lib/chef/platform/priority_map.rb b/lib/chef/platform/priority_map.rb index 73554eafe1..0b050deb59 100644 --- a/lib/chef/platform/priority_map.rb +++ b/lib/chef/platform/priority_map.rb @@ -1,3 +1,21 @@ +# +# Author:: John Keiser (<jkeiser@chef.io>) +# Copyright:: Copyright (c) 2015 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + require 'chef/node_map' class Chef @@ -18,43 +36,6 @@ class Chef set(key, priority_array, *filter, &block) priority_array end - - # @api private - def list_handlers(node, key, **filters) - list(node, key, **filters).flatten(1).uniq - end - - # @api private - def includes_handler?(key, handler) - return false if !map.has_key?(key) - map[key].any? { |m| h = m[:value]; h.is_a?(Array) ? h.include?(handler) : h == handler } - end - - # - # Priority maps have one extra precedence: priority arrays override "provides," - # and "provides" lines with identical filters sort by class name (ascending). - # - def compare_matchers(key, new_matcher, matcher) - # Priority arrays come before "provides" - if new_matcher[:value].is_a?(Array) != matcher[:value].is_a?(Array) - return new_matcher[:value].is_a?(Array) ? -1 : 1 - end - - cmp = super - if cmp == 0 - # Sort by class name (ascending) as well, if all other properties - # are exactly equal - if new_matcher[:value].is_a?(Class) && !new_matcher[:override] - cmp = compare_matcher_properties(new_matcher, matcher) { |m| m[:value].name } - if cmp < 0 - Chef::Log.warn "You are overriding #{key} on #{new_matcher[:filters].inspect} with #{new_matcher[:value].inspect}: used to be #{matcher[:value].inspect}. Use override: true if this is what you intended." - elsif cmp > 0 - Chef::Log.warn "You declared a new resource #{new_matcher[:value].inspect} for resource #{key}, but it comes alphabetically after #{matcher[:value].inspect} and has the same filters (#{new_matcher[:filters].inspect}), so it will not be used. Use override: true if you want to use it for #{key}." - end - end - end - cmp - end end end end diff --git a/lib/chef/platform/provider_handler_map.rb b/lib/chef/platform/provider_handler_map.rb new file mode 100644 index 0000000000..37321268aa --- /dev/null +++ b/lib/chef/platform/provider_handler_map.rb @@ -0,0 +1,11 @@ +require 'singleton' +require 'chef/platform/handler_map' + +class Chef + class Platform + # @api private + class ProviderHandlerMap < Chef::Platform::HandlerMap + include Singleton + end + end +end diff --git a/lib/chef/platform/resource_handler_map.rb b/lib/chef/platform/resource_handler_map.rb new file mode 100644 index 0000000000..532d4ff656 --- /dev/null +++ b/lib/chef/platform/resource_handler_map.rb @@ -0,0 +1,11 @@ +require 'singleton' +require 'chef/platform/handler_map' + +class Chef + class Platform + # @api private + class ResourceHandlerMap < Chef::Platform::HandlerMap + include Singleton + end + end +end diff --git a/lib/chef/platform/resource_priority_map.rb b/lib/chef/platform/resource_priority_map.rb index aa57e3ddf0..5cc86fd2e7 100644 --- a/lib/chef/platform/resource_priority_map.rb +++ b/lib/chef/platform/resource_priority_map.rb @@ -6,12 +6,6 @@ class Chef # @api private class ResourcePriorityMap < Chef::Platform::PriorityMap include Singleton - - # @api private - def get_priority_array(node, resource_name, canonical: nil) - super(node, resource_name.to_sym, canonical: canonical) - end - end end end diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb index 280277d947..dcfc92645b 100644 --- a/lib/chef/provider.rb +++ b/lib/chef/provider.rb @@ -176,7 +176,7 @@ class Chef end def self.provides(short_name, opts={}, &block) - Chef.provider_priority_map.set(short_name, self, opts, &block) + Chef.provider_handler_map.set(short_name, self, opts, &block) end def self.provides?(node, resource) diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb index aca8d0dc3b..880104bff7 100644 --- a/lib/chef/provider/package.rb +++ b/lib/chef/provider/package.rb @@ -491,37 +491,6 @@ class Chef end end - # Set provider priority - require 'chef/chef_class' - require 'chef/provider/package/dpkg' - require 'chef/provider/package/homebrew' - require 'chef/provider/package/macports' - require 'chef/provider/package/apt' - require 'chef/provider/package/yum' - require 'chef/provider/package/zypper' - require 'chef/provider/package/portage' - require 'chef/provider/package/pacman' - require 'chef/provider/package/ips' - require 'chef/provider/package/solaris' - require 'chef/provider/package/smartos' - require 'chef/provider/package/aix' - require 'chef/provider/package/paludis' - - Chef.set_provider_priority_array :package, [ Homebrew, Macports ], os: "darwin" - - Chef.set_provider_priority_array :package, Apt, platform_family: "debian" - Chef.set_provider_priority_array :package, Yum, platform_family: %w(rhel fedora) - Chef.set_provider_priority_array :package, Zypper, platform_family: "suse" - Chef.set_provider_priority_array :package, Portage, platform: "gentoo" - Chef.set_provider_priority_array :package, Pacman, platform: "arch" - Chef.set_provider_priority_array :package, Ips, platform: %w(openindiana opensolaris omnios solaris2) - Chef.set_provider_priority_array :package, Solaris, platform: "nexentacore" - Chef.set_provider_priority_array :package, Solaris, platform: "solaris2", platform_version: '< 5.11' - - Chef.set_provider_priority_array :package, SmartOS, platform: "smartos" - Chef.set_provider_priority_array :package, Aix, platform: "aix" - Chef.set_provider_priority_array :package, Paludis, platform: "exherbo" - private def shell_out_with_timeout(*command_args) diff --git a/lib/chef/provider/package/aix.rb b/lib/chef/provider/package/aix.rb index b97db9d061..5165f4b4ea 100644 --- a/lib/chef/provider/package/aix.rb +++ b/lib/chef/provider/package/aix.rb @@ -26,6 +26,7 @@ class Chef class Package class Aix < Chef::Provider::Package + provides :package, os: "aix" provides :bff_package, os: "aix" include Chef::Mixin::GetSourceFromPackage diff --git a/lib/chef/provider/package/apt.rb b/lib/chef/provider/package/apt.rb index bd6ed283bf..e109c9966a 100644 --- a/lib/chef/provider/package/apt.rb +++ b/lib/chef/provider/package/apt.rb @@ -25,6 +25,7 @@ class Chef class Package class Apt < Chef::Provider::Package + provides :package, platform_family: "debian" provides :apt_package, os: "linux" # return [Hash] mapping of package name to Boolean value diff --git a/lib/chef/provider/package/homebrew.rb b/lib/chef/provider/package/homebrew.rb index beede1c916..e5c45f0a62 100644 --- a/lib/chef/provider/package/homebrew.rb +++ b/lib/chef/provider/package/homebrew.rb @@ -26,6 +26,7 @@ class Chef class Package class Homebrew < Chef::Provider::Package + provides :package, os: "darwin", override: true provides :homebrew_package include Chef::Mixin::HomebrewUser diff --git a/lib/chef/provider/package/ips.rb b/lib/chef/provider/package/ips.rb index 4d7f4a3583..96c2e711d4 100644 --- a/lib/chef/provider/package/ips.rb +++ b/lib/chef/provider/package/ips.rb @@ -27,6 +27,7 @@ class Chef class Package class Ips < Chef::Provider::Package + provides :package, platform: %w(openindiana opensolaris omnios solaris2) provides :ips_package, os: "solaris2" attr_accessor :virtual diff --git a/lib/chef/provider/package/macports.rb b/lib/chef/provider/package/macports.rb index e945211540..c7ea71ac8c 100644 --- a/lib/chef/provider/package/macports.rb +++ b/lib/chef/provider/package/macports.rb @@ -3,6 +3,7 @@ class Chef class Package class Macports < Chef::Provider::Package + provides :package, os: "darwin" provides :macports_package def load_current_resource diff --git a/lib/chef/provider/package/pacman.rb b/lib/chef/provider/package/pacman.rb index bf03e54656..01e3a9cc01 100644 --- a/lib/chef/provider/package/pacman.rb +++ b/lib/chef/provider/package/pacman.rb @@ -25,6 +25,7 @@ class Chef class Package class Pacman < Chef::Provider::Package + provides :package, platform: "arch" provides :pacman_package, os: "linux" def load_current_resource diff --git a/lib/chef/provider/package/paludis.rb b/lib/chef/provider/package/paludis.rb index 407e0d0110..2d6302515b 100644 --- a/lib/chef/provider/package/paludis.rb +++ b/lib/chef/provider/package/paludis.rb @@ -24,6 +24,7 @@ class Chef class Package class Paludis < Chef::Provider::Package + provides :package, platform: "exherbo" provides :paludis_package, os: "linux" def load_current_resource diff --git a/lib/chef/provider/package/portage.rb b/lib/chef/provider/package/portage.rb index 4ba0160bb0..95782a6774 100644 --- a/lib/chef/provider/package/portage.rb +++ b/lib/chef/provider/package/portage.rb @@ -25,6 +25,8 @@ class Chef class Provider class Package class Portage < Chef::Provider::Package + + provides :package, platform: "gentoo" provides :portage_package PACKAGE_NAME_PATTERN = %r{(?:([^/]+)/)?([^/]+)} diff --git a/lib/chef/provider/package/smartos.rb b/lib/chef/provider/package/smartos.rb index 0d5b801c96..71b8a9b9e1 100644 --- a/lib/chef/provider/package/smartos.rb +++ b/lib/chef/provider/package/smartos.rb @@ -29,6 +29,7 @@ class Chef class SmartOS < Chef::Provider::Package attr_accessor :is_virtual_package + provides :package, platform: "smartos" provides :smartos_package, os: "solaris2", platform_family: "smartos" def load_current_resource diff --git a/lib/chef/provider/package/solaris.rb b/lib/chef/provider/package/solaris.rb index 9b10403344..e62f37d27b 100644 --- a/lib/chef/provider/package/solaris.rb +++ b/lib/chef/provider/package/solaris.rb @@ -27,6 +27,8 @@ class Chef include Chef::Mixin::GetSourceFromPackage + provides :package, platform: "nexentacore" + provides :package, platform: "solaris2", platform_version: '< 5.11' provides :solaris_package, os: "solaris2" # def initialize(*args) diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb index 85c2ba683c..e8c0483741 100644 --- a/lib/chef/provider/package/yum.rb +++ b/lib/chef/provider/package/yum.rb @@ -28,6 +28,7 @@ class Chef class Package class Yum < Chef::Provider::Package + provides :package, platform_family: %w(rhel fedora) provides :yum_package, os: "linux" class RPMUtils diff --git a/lib/chef/provider/package/zypper.rb b/lib/chef/provider/package/zypper.rb index c2a3ac4ba8..ac42304ffb 100644 --- a/lib/chef/provider/package/zypper.rb +++ b/lib/chef/provider/package/zypper.rb @@ -29,6 +29,7 @@ class Chef class Package class Zypper < Chef::Provider::Package + provides :package, platform_family: "suse" provides :zypper_package, os: "linux" def load_current_resource diff --git a/lib/chef/provider/service.rb b/lib/chef/provider/service.rb index 9c523b5e66..15dd72cb04 100644 --- a/lib/chef/provider/service.rb +++ b/lib/chef/provider/service.rb @@ -188,29 +188,11 @@ class Chef require 'chef/provider/service/upstart' require 'chef/provider/service/debian' require 'chef/provider/service/invokercd' - require 'chef/provider/service/freebsd' - require 'chef/provider/service/openbsd' - require 'chef/provider/service/solaris' - require 'chef/provider/service/macosx' - - def self.os(os, *providers) - Chef.set_provider_priority_array(:service, providers, os: os) - end - def self.platform_family(platform_family, *providers) - Chef.set_provider_priority_array(:service, providers, platform_family: platform_family) - end - - os %w(freebsd netbsd), Freebsd - os %w(openbsd), Openbsd - os %w(solaris2), Solaris - os %w(darwin), Macosx - os %w(linux), Systemd, Insserv, Redhat - - platform_family %w(arch), Systemd, Arch - platform_family %w(gentoo), Systemd, Gentoo - platform_family %w(debian), Systemd, Upstart, Insserv, Debian, Invokercd - platform_family %w(rhel fedora suse), Systemd, Insserv, Redhat + Chef.set_provider_priority_array :service, [ Systemd, Arch ], platform_family: 'arch' + Chef.set_provider_priority_array :service, [ Systemd, Gentoo ], platform_family: 'gentoo' + Chef.set_provider_priority_array :service, [ Systemd, Upstart, Insserv, Debian, Invokercd ], platform_family: 'debian' + Chef.set_provider_priority_array :service, [ Systemd, Insserv, Redhat ], platform_family: %w(rhel fedora suse) end end end diff --git a/lib/chef/provider/service/debian.rb b/lib/chef/provider/service/debian.rb index c67f3f05da..46c23fdd34 100644 --- a/lib/chef/provider/service/debian.rb +++ b/lib/chef/provider/service/debian.rb @@ -22,6 +22,8 @@ class Chef class Provider class Service class Debian < Chef::Provider::Service::Init + provides :service, platform_family: 'debian' + UPDATE_RC_D_ENABLED_MATCHES = /\/rc[\dS].d\/S|not installed/i UPDATE_RC_D_PRIORITIES = /\/rc([\dS]).d\/([SK])(\d\d)/i diff --git a/lib/chef/provider/service/insserv.rb b/lib/chef/provider/service/insserv.rb index 4534e33f32..2fd2eac38e 100644 --- a/lib/chef/provider/service/insserv.rb +++ b/lib/chef/provider/service/insserv.rb @@ -24,6 +24,8 @@ class Chef class Service class Insserv < Chef::Provider::Service::Init + provides :service, platform_family: %w(debian rhel fedora suse) + def self.provides?(node, resource) super && Chef::Platform::ServiceHelpers.service_resource_providers.include?(:insserv) end diff --git a/lib/chef/provider/service/invokercd.rb b/lib/chef/provider/service/invokercd.rb index fdf4cbc256..39022546b0 100644 --- a/lib/chef/provider/service/invokercd.rb +++ b/lib/chef/provider/service/invokercd.rb @@ -23,6 +23,8 @@ class Chef class Service class Invokercd < Chef::Provider::Service::Init + provides :service, platform_family: 'debian', override: true + def self.provides?(node, resource) super && Chef::Platform::ServiceHelpers.service_resource_providers.include?(:invokercd) end diff --git a/lib/chef/provider/service/openbsd.rb b/lib/chef/provider/service/openbsd.rb index d509ee10ff..173191e01c 100644 --- a/lib/chef/provider/service/openbsd.rb +++ b/lib/chef/provider/service/openbsd.rb @@ -26,7 +26,7 @@ class Chef class Service class Openbsd < Chef::Provider::Service::Init - provides :service, os: [ "openbsd" ] + provides :service, os: "openbsd" include Chef::Mixin::ShellOut diff --git a/lib/chef/provider/service/redhat.rb b/lib/chef/provider/service/redhat.rb index a8deb13aec..2330d88eb7 100644 --- a/lib/chef/provider/service/redhat.rb +++ b/lib/chef/provider/service/redhat.rb @@ -23,6 +23,8 @@ class Chef class Service class Redhat < Chef::Provider::Service::Init + provides :service, platform_family: %w(rhel fedora suse) + CHKCONFIG_ON = /\d:on/ CHKCONFIG_MISSING = /No such/ diff --git a/lib/chef/provider/service/upstart.rb b/lib/chef/provider/service/upstart.rb index d8ce6af649..8809d1c708 100644 --- a/lib/chef/provider/service/upstart.rb +++ b/lib/chef/provider/service/upstart.rb @@ -25,6 +25,9 @@ class Chef class Provider class Service class Upstart < Chef::Provider::Service::Simple + + provides :service, platform_family: 'debian', override: true + UPSTART_STATE_FORMAT = /\w+ \(?(\w+)\)?[\/ ](\w+)/ def self.provides?(node, resource) diff --git a/lib/chef/provider_resolver.rb b/lib/chef/provider_resolver.rb index 8e731ff96a..2fd9d7e8eb 100644 --- a/lib/chef/provider_resolver.rb +++ b/lib/chef/provider_resolver.rb @@ -68,27 +68,39 @@ class Chef potential_handlers.include?(provider_class) end - def self.includes_handler?(resource_name, provider_class) - priority_map.includes_handler?(resource_name, provider_class) - end - def enabled_handlers - @enabled_handlers ||= - potential_handlers.select { |handler| !overrode_provides?(handler) || handler.provides?(node, resource) } + potential_handlers.select { |handler| !overrode_provides?(handler) || handler.provides?(node, resource) } end # TODO deprecate this and allow actions to be passed as a filter to # `provides` so we don't have to have two separate things. # @api private def supported_handlers - @supported_handlers ||= - enabled_handlers.select { |handler| handler.supports?(resource, action) } + enabled_handlers.select { |handler| handler.supports?(resource, action) } end private def potential_handlers - priority_map.list_handlers(node, resource.resource_name) + handler_map.list(node, resource.resource_name).uniq + end + + # The list of handlers, with any in the priority_map moved to the front + def prioritized_handlers + @prioritized_handlers ||= begin + supported_handlers = self.supported_handlers + if supported_handlers.empty? + # if none of the providers specifically support the resource, we still need to pick one of the providers that are + # enabled on the node to handle the why-run use case. FIXME we should only do this in why-run mode then. + Chef::Log.debug "No providers responded true to `supports?` for action #{action} on resource #{resource}, falling back to enabled handlers so we can return something anyway." + supported_handlers = enabled_handlers + end + + prioritized = priority_map.list(node, resource.resource_name).flatten(1) + prioritized &= supported_handlers # Filter the priority map by the actual enabled handlers + prioritized |= supported_handlers # Bring back any handlers that aren't in the priority map, at the *end* (ordered set) + prioritized + end end # if resource.provider is set, just return one of those objects @@ -101,15 +113,7 @@ class Chef def maybe_dynamic_provider_resolution(resource, action) Chef::Log.debug "Providers for generic #{resource.resource_name} resource enabled on node include: #{enabled_handlers}" - handlers = supported_handlers - if handlers.empty? - # if none of the providers specifically support the resource, we still need to pick one of the providers that are - # enabled on the node to handle the why-run use case. FIXME we should only do this in why-run mode then. - Chef::Log.debug "No providers responded true to `supports?` for action #{action} on resource #{resource}, falling back to enabled handlers so we can return something anyway." - handlers = enabled_handlers - end - - handler = handlers.first + handler = prioritized_handlers.first if handler Chef::Log.debug "Provider for action #{action} on resource #{resource} is #{handler}" @@ -125,12 +129,12 @@ class Chef Chef::Platform.find_provider_for_node(node, resource) end - def self.priority_map + def priority_map Chef.provider_priority_map end - def priority_map - Chef.provider_priority_map + def handler_map + Chef.provider_handler_map end def overrode_provides?(handler) diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 5e9ba42703..ac6f5e8923 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -1550,7 +1550,7 @@ class Chef remove_canonical_dsl end - result = Chef.resource_priority_map.set(name, self, options, &block) + result = Chef.resource_handler_map.set(name, self, options, &block) Chef::DSL::Resources.add_resource_dsl(name) result end @@ -1742,7 +1742,7 @@ class Chef def self.remove_canonical_dsl if @resource_name - remaining = Chef.resource_priority_map.delete_canonical(@resource_name, self) + remaining = Chef.resource_handler_map.delete_canonical(@resource_name, self) if !remaining Chef::DSL::Resources.remove_resource_dsl(@resource_name) end diff --git a/lib/chef/resource_resolver.rb b/lib/chef/resource_resolver.rb index 2f27e93a3b..47b3df18af 100644 --- a/lib/chef/resource_resolver.rb +++ b/lib/chef/resource_resolver.rb @@ -83,9 +83,9 @@ class Chef # @api private use Chef::ResourceResolver.resolve instead. def resolve # log this so we know what resources will work for the generic resource on the node (early cut) - Chef::Log.debug "Resources for generic #{resource_name} resource enabled on node include: #{enabled_handlers}" + Chef::Log.debug "Resources for generic #{resource_name} resource enabled on node include: #{prioritized_handlers}" - handler = enabled_handlers.first + handler = prioritized_handlers.first if handler Chef::Log.debug "Resource for #{resource_name} is #{handler}" @@ -98,8 +98,8 @@ class Chef # @api private def list - Chef::Log.debug "Resources for generic #{resource_name} resource enabled on node include: #{enabled_handlers}" - enabled_handlers + Chef::Log.debug "Resources for generic #{resource_name} resource enabled on node include: #{prioritized_handlers}" + prioritized_handlers end # @@ -118,7 +118,7 @@ class Chef # # @api private def self.includes_handler?(resource_name, resource_class) - priority_map.includes_handler?(resource_name, resource_class) + handler_map.list(nil, resource_name).include?(resource_class) end protected @@ -127,19 +127,38 @@ class Chef Chef.resource_priority_map end + def self.handler_map + Chef.resource_handler_map + end + def priority_map Chef.resource_priority_map end + def handler_map + Chef.resource_handler_map + end + # @api private def potential_handlers - priority_map.list_handlers(node, resource_name, canonical: canonical) + handler_map.list(node, resource_name, canonical: canonical).uniq end def enabled_handlers potential_handlers.select { |handler| !overrode_provides?(handler) || handler.provides?(node, resource_name) } end + def prioritized_handlers + @prioritized_handlers ||= begin + enabled_handlers = self.enabled_handlers + + prioritized = priority_map.list(node, resource_name, canonical: canonical).flatten(1) + prioritized &= enabled_handlers # Filter the priority map by the actual enabled handlers + prioritized |= enabled_handlers # Bring back any handlers that aren't in the priority map, at the *end* (ordered set) + prioritized + end + end + def overrode_provides?(handler) handler.method(:provides?).owner != Chef::Resource.method(:provides?).owner end @@ -151,17 +170,15 @@ class Chef end def enabled_handlers - @enabled_handlers ||= begin - handlers = super - if handlers.empty? - handlers = resources.select { |handler| overrode_provides?(handler) && handler.provides?(node, resource_name) } - handlers.each do |handler| - Chef::Log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource_name}, but provides #{resource_name.inspect} was never called!") - Chef::Log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") - end + handlers = super + if handlers.empty? + handlers = resources.select { |handler| overrode_provides?(handler) && handler.provides?(node, resource_name) } + handlers.each do |handler| + Chef::Log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource_name}, but provides #{resource_name.inspect} was never called!") + Chef::Log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") end - handlers end + handlers end end prepend Deprecated |