diff options
author | John Keiser <john@johnkeiser.com> | 2015-05-06 07:59:33 -0700 |
---|---|---|
committer | John Keiser <john@johnkeiser.com> | 2015-05-07 17:42:00 -0700 |
commit | 970c0bc62c2b20d076e4b82b10a3766bd2606556 (patch) | |
tree | 5ba720c3d20e06315737434447230e480ced57b7 | |
parent | 993e02415cf401b49e8bd93ba883b02c85d1aa66 (diff) | |
download | chef-970c0bc62c2b20d076e4b82b10a3766bd2606556.tar.gz |
Use the central priority map for `provides`
-rw-r--r-- | lib/chef/chef_class.rb | 33 | ||||
-rw-r--r-- | lib/chef/client.rb | 7 | ||||
-rw-r--r-- | lib/chef/mixin/provides.rb | 27 | ||||
-rw-r--r-- | lib/chef/node_map.rb | 18 | ||||
-rw-r--r-- | lib/chef/platform/provider_priority_map.rb | 72 | ||||
-rw-r--r-- | lib/chef/platform/resource_priority_map.rb | 19 | ||||
-rw-r--r-- | lib/chef/provider.rb | 22 | ||||
-rw-r--r-- | lib/chef/provider/file.rb | 1 | ||||
-rw-r--r-- | lib/chef/provider/package.rb | 5 | ||||
-rw-r--r-- | lib/chef/provider/service.rb | 74 | ||||
-rw-r--r-- | lib/chef/provider/service/init.rb | 1 | ||||
-rw-r--r-- | lib/chef/resource.rb | 10 | ||||
-rw-r--r-- | lib/chef/resource/package.rb | 5 | ||||
-rw-r--r-- | lib/chef/resource_resolver.rb | 5 | ||||
-rw-r--r-- | lib/chef/util/path_helper.rb | 13 | ||||
-rw-r--r-- | spec/functional/resource/template_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/provider_resolver_spec.rb | 1 | ||||
-rw-r--r-- | spec/unit/resource/template_spec.rb | 2 |
18 files changed, 175 insertions, 142 deletions
diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index d3f7ee55c7..96c0899d5d 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -26,6 +26,9 @@ # injected" into this class by other objects and do not reference the class symbols in those files # directly and we do not need to require those files here. +require 'chef/platform/provider_priority_map' +require 'chef/platform/resource_priority_map' + class Chef class << self @@ -48,7 +51,7 @@ class Chef # @param resource_name [Symbol] name of the resource as a symbol # @return [Array<Class>] Priority Array of Provider Classes to use for the resource_name on the node def get_provider_priority_array(resource_name) - @provider_priority_map.get_priority_array(node, resource_name).dup + provider_priority_map.get_priority_array(node, resource_name).dup end # Get the array of resources associated with a resource_name for the current node @@ -56,27 +59,27 @@ class Chef # @param resource_name [Symbol] name of the resource as a symbol # @return [Array<Class>] Priority Array of Resource Classes to use for the resource_name on the node def get_resource_priority_array(resource_name) - @resource_priority_map.get_priority_array(node, resource_name).dup + resource_priority_map.get_priority_array(node, resource_name).dup end # Set the array of providers associated with a resource_name for the current node # # @param resource_name [Symbol] name of the resource as a symbol - # @param priority_array [Array<Class>] Array of Classes to set as the priority for resource_name on the node + # @param priority_array [Class, Array<Class>] Class or Array of Classes to set as the priority for resource_name on the node # @param filter [Hash] Chef::Nodearray-style filter # @return [Array<Class>] Modified Priority Array of Provider Classes to use for the resource_name on the node def set_provider_priority_array(resource_name, priority_array, *filter) - @provider_priority_map.set_priority_array(resource_name, priority_array, *filter).dup + provider_priority_map.set_priority_array(resource_name, priority_array, *filter).dup end # Get the array of resources associated with a resource_name for the current node # # @param resource_name [Symbol] name of the resource as a symbol - # @param priority_array [Array<Class>] Array of Classes to set as the priority for resource_name on the node + # @param priority_array [Class, Array<Class>] Class or Array of Classes to set as the priority for resource_name on the node # @param filter [Hash] Chef::Nodearray-style filter # @return [Array<Class>] Modified Priority Array of Resource Classes to use for the resource_name on the node def set_resource_priority_array(resource_name, priority_array, *filter) - @resource_priority_map.set_priority_array(resource_name, priority_array, *filter).dup + resource_priority_map.set_priority_array(resource_name, priority_array, *filter).dup end # @@ -126,5 +129,23 @@ class Chef @provider_priority_map = nil @resource_priority_map = nil end + + private + + def provider_priority_map + @provider_priority_map ||= begin + # these slurp in the resource+provider world, so be exceedingly lazy about requiring them + require 'chef/platform/provider_priority_map' + Chef::Platform::ProviderPriorityMap.instance + end + end + def resource_priority_map + @resource_priority_map ||= begin + require 'chef/platform/resource_priority_map' + Chef::Platform::ResourcePriorityMap.instance + end + end end + + reset! end diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 0764d3f3ba..5b578c9927 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -166,13 +166,6 @@ class Chef if new_runlist = args.delete(:runlist) @json_attribs["run_list"] = new_runlist end - - # these slurp in the resource+provider world, so be exceedingly lazy about requiring them - require 'chef/platform/provider_priority_map' unless defined? Chef::Platform::ProviderPriorityMap - require 'chef/platform/resource_priority_map' unless defined? Chef::Platform::ResourcePriorityMap - - Chef.set_provider_priority_map(Chef::Platform::ProviderPriorityMap.instance) - Chef.set_resource_priority_map(Chef::Platform::ResourcePriorityMap.instance) end def configure_formatters diff --git a/lib/chef/mixin/provides.rb b/lib/chef/mixin/provides.rb index c39c53a190..c95cb753a8 100644 --- a/lib/chef/mixin/provides.rb +++ b/lib/chef/mixin/provides.rb @@ -4,30 +4,21 @@ require 'chef/mixin/descendants_tracker' class Chef module Mixin module Provides + # TODO no longer needed, remove or deprecate? include Chef::Mixin::DescendantsTracker - def node_map - @node_map ||= Chef::NodeMap.new - end - def provides(short_name, opts={}, &block) - if !short_name.kind_of?(Symbol) - # YAGNI: this is probably completely unnecessary and can be removed? - Chef::Log.deprecation "Passing a non-Symbol to Chef::Resource#provides will be removed" - if short_name.kind_of?(String) - short_name.downcase! - short_name.gsub!(/\s/, "_") - end - short_name = short_name.to_sym - end - node_map.set(short_name, true, opts, &block) + provides_priority_map.priority(short_name, self, opts, &block) end # Check whether this resource provides the resource_name DSL for the given - # node - def provides?(node, resource_name) - resource_name = resource_name.resource_name if resource_name.is_a?(Chef::Resource) - node_map.get(node, resource_name) + # node. + def provides?(node, short_name) + provides_priority_map.list(node, short_name).include?(self) + end + + def provides_priority_map + raise NotImplementedError, :provides_priority_map end # Get the list of recipe DSL this resource is responsible for on the given diff --git a/lib/chef/node_map.rb b/lib/chef/node_map.rb index 17fda4a271..be77ec5f71 100644 --- a/lib/chef/node_map.rb +++ b/lib/chef/node_map.rb @@ -68,14 +68,16 @@ class Chef def get(node, key) # FIXME: real exception raise "first argument must be a Chef::Node" unless node.is_a?(Chef::Node) - return nil unless @map.has_key?(key) - @map[key].each do |matcher| - if filters_match?(node, matcher[:filters]) && - block_matches?(node, matcher[:block]) - return matcher[:value] - end - end - nil + list(node, key).first + end + + def list(node, key) + # FIXME: real exception + raise "first argument must be a Chef::Node" unless node.is_a?(Chef::Node) + return [] unless @map.has_key?(key) + @map[key].select do |matcher| + filters_match?(node, matcher[:filters]) && block_matches?(node, matcher[:block]) + end.map { |matcher| matcher[:value] } end def clear diff --git a/lib/chef/platform/provider_priority_map.rb b/lib/chef/platform/provider_priority_map.rb index 1539f61900..2d250b5006 100644 --- a/lib/chef/platform/provider_priority_map.rb +++ b/lib/chef/platform/provider_priority_map.rb @@ -1,88 +1,28 @@ +require 'singleton' class Chef class Platform class ProviderPriorityMap include Singleton - def initialize - load_default_map - end - def get_priority_array(node, resource_name) priority_map.get(node, resource_name.to_sym) end def set_priority_array(resource_name, priority_array, *filter) - priority(resource_name.to_sym, priority_array.to_a, *filter) + priority(resource_name.to_sym, Array(priority_array), *filter) end def priority(*args) priority_map.set(*args) end - private - - def load_default_map - require 'chef/providers' - - # - # Linux - # - - # default block for linux O/Sen must come before platform_family exceptions - priority :service, [ - Chef::Provider::Service::Systemd, - Chef::Provider::Service::Insserv, - Chef::Provider::Service::Redhat, - ], os: "linux" - - priority :service, [ - Chef::Provider::Service::Systemd, - Chef::Provider::Service::Arch, - ], platform_family: "arch" - - priority :service, [ - Chef::Provider::Service::Systemd, - Chef::Provider::Service::Gentoo, - ], platform_family: "gentoo" - - priority :service, [ - # we can determine what systemd supports accurately - Chef::Provider::Service::Systemd, - # on debian-ish system if an upstart script exists that must win over sysv types - Chef::Provider::Service::Upstart, - Chef::Provider::Service::Insserv, - Chef::Provider::Service::Debian, - Chef::Provider::Service::Invokercd, - ], platform_family: "debian" - - priority :service, [ - Chef::Provider::Service::Systemd, - Chef::Provider::Service::Insserv, - Chef::Provider::Service::Redhat, - ], platform_family: [ "rhel", "fedora", "suse" ] - - # - # BSDen - # - - priority :service, Chef::Provider::Service::Freebsd, os: [ "freebsd", "netbsd" ] - priority :service, Chef::Provider::Service::Openbsd, os: [ "openbsd" ] - - # - # Solaris-en - # - - priority :service, Chef::Provider::Service::Solaris, os: "solaris2" - - # - # Mac - # - - priority :service, Chef::Provider::Service::Macosx, os: "darwin" - priority :package, Chef::Provider::Package::Homebrew, os: "darwin" + def list(node, resource_name) + priority_map.list(node, resource_name).flatten(1).uniq end + private + def priority_map require 'chef/node_map' @priority_map ||= Chef::NodeMap.new diff --git a/lib/chef/platform/resource_priority_map.rb b/lib/chef/platform/resource_priority_map.rb index fc43b3e7db..e692cbb800 100644 --- a/lib/chef/platform/resource_priority_map.rb +++ b/lib/chef/platform/resource_priority_map.rb @@ -1,33 +1,28 @@ +require 'singleton' + class Chef class Platform class ResourcePriorityMap include Singleton - def initialize - load_default_map - end - def get_priority_array(node, resource_name) priority_map.get(node, resource_name.to_sym) end def set_priority_array(resource_name, priority_array, *filter) - priority resource_name.to_sym, priority_array.to_a, *filter + priority resource_name.to_sym, Array(priority_array), *filter end def priority(*args) priority_map.set(*args) end - private - - def load_default_map - require 'chef/resources' - - # MacOSX - priority :package, Chef::Resource::HomebrewPackage, os: "darwin" + def list(*args) + priority_map.list(*args).flatten(1).uniq end + private + def priority_map require 'chef/node_map' @priority_map ||= Chef::NodeMap.new diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb index 3ab4d4d2b1..ad12591c5d 100644 --- a/lib/chef/provider.rb +++ b/lib/chef/provider.rb @@ -17,17 +17,11 @@ # limitations under the License. # -require 'chef/mixin/from_file' -require 'chef/mixin/convert_to_class_name' -require 'chef/mixin/enforce_ownership_and_permissions' -require 'chef/mixin/why_run' -require 'chef/mixin/shell_out' -require 'chef/mixin/provides' -require 'chef/platform/service_helpers' -require 'chef/node_map' - class Chef class Provider + require 'chef/mixin/why_run' + require 'chef/mixin/shell_out' + require 'chef/mixin/provides' include Chef::Mixin::WhyRun include Chef::Mixin::ShellOut extend Chef::Mixin::Provides @@ -167,6 +161,10 @@ class Chef protected + def self.provides_priority_map + Chef::Platform::ResourcePriorityMap.instance + end + def converge_actions @converge_actions ||= ConvergeActions.new(@new_resource, run_context, @action) end @@ -221,3 +219,9 @@ class Chef extend DeprecatedLWRPClass end end + +# Requiring things at the bottom breaks cycles +require 'chef/chef_class' +require 'chef/mixin/why_run' +require 'chef/resource_collection' +require 'chef/runner' diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb index fda8ad2e5e..6adfbd211a 100644 --- a/lib/chef/provider/file.rb +++ b/lib/chef/provider/file.rb @@ -26,6 +26,7 @@ require 'fileutils' require 'chef/scan_access_control' require 'chef/mixin/checksum' require 'chef/mixin/file_class' +require 'chef/mixin/enforce_ownership_and_permissions' require 'chef/util/backup' require 'chef/util/diff' require 'chef/deprecation/provider/file' diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb index 6b429a400d..21294e22a3 100644 --- a/lib/chef/provider/package.rb +++ b/lib/chef/provider/package.rb @@ -487,3 +487,8 @@ class Chef end end end + +require 'chef/chef_class' +require 'chef/provider/package/homebrew' + +Chef.set_provider_priority_array :package, Chef::Provider::Package::Homebrew, os: "darwin" diff --git a/lib/chef/provider/service.rb b/lib/chef/provider/service.rb index 75da2ddb31..4cd7f335dd 100644 --- a/lib/chef/provider/service.rb +++ b/lib/chef/provider/service.rb @@ -171,3 +171,77 @@ class Chef end end end + +# +# Platform-specific versions +# + +# +# Linux +# + +require 'chef/chef_class' +require 'chef/provider/service/systemd' +require 'chef/provider/service/insserv' +require 'chef/provider/service/redhat' +require 'chef/provider/service/arch' +require 'chef/provider/service/gentoo' +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' + +# default block for linux O/Sen must come before platform_family exceptions +Chef.set_provider_priority_array :service, [ + Chef::Provider::Service::Systemd, + Chef::Provider::Service::Insserv, + Chef::Provider::Service::Redhat, +], os: "linux" + +Chef.set_provider_priority_array :service, [ + Chef::Provider::Service::Systemd, + Chef::Provider::Service::Arch, +], platform_family: "arch" + +Chef.set_provider_priority_array :service, [ + Chef::Provider::Service::Systemd, + Chef::Provider::Service::Gentoo, +], platform_family: "gentoo" + +Chef.set_provider_priority_array :service, [ + # we can determine what systemd supports accurately + Chef::Provider::Service::Systemd, + # on debian-ish system if an upstart script exists that must win over sysv types + Chef::Provider::Service::Upstart, + Chef::Provider::Service::Insserv, + Chef::Provider::Service::Debian, + Chef::Provider::Service::Invokercd, +], platform_family: "debian" + +Chef.set_provider_priority_array :service, [ + Chef::Provider::Service::Systemd, + Chef::Provider::Service::Insserv, + Chef::Provider::Service::Redhat, +], platform_family: [ "rhel", "fedora", "suse" ] + +# +# BSDen +# + +Chef.set_provider_priority_array :service, Chef::Provider::Service::Freebsd, os: [ "freebsd", "netbsd" ] +Chef.set_provider_priority_array :service, Chef::Provider::Service::Openbsd, os: [ "openbsd" ] + +# +# Solaris-en +# + +Chef.set_provider_priority_array :service, Chef::Provider::Service::Solaris, os: "solaris2" + +# +# Mac +# + +Chef.set_provider_priority_array :service, Chef::Provider::Service::Macosx, os: "darwin" diff --git a/lib/chef/provider/service/init.rb b/lib/chef/provider/service/init.rb index 0a219a69e1..355e98a0eb 100644 --- a/lib/chef/provider/service/init.rb +++ b/lib/chef/provider/service/init.rb @@ -18,6 +18,7 @@ require 'chef/provider/service/simple' require 'chef/mixin/command' +require 'chef/platform/service_helpers' class Chef class Provider diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 2f5c2b7798..fb8926be15 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -976,7 +976,7 @@ class Chef end end - def self.provides(name, *args, &block) + def self.provides(name, opts={}, &block) result = super Chef::DSL::Resources.add_resource_dsl(name) result @@ -1143,6 +1143,12 @@ class Chef end end + protected + + def self.provides_priority_map + Chef::Platform::ResourcePriorityMap.instance + end + # Implement deprecated LWRP class module DeprecatedLWRPClass # @api private @@ -1163,8 +1169,6 @@ class Chef end end - private - def deprecated_constants @deprecated_constants ||= {} end diff --git a/lib/chef/resource/package.rb b/lib/chef/resource/package.rb index 5bea894a02..d0815c539d 100644 --- a/lib/chef/resource/package.rb +++ b/lib/chef/resource/package.rb @@ -102,3 +102,8 @@ class Chef end end end + +require 'chef/chef_class' +require 'chef/resource/homebrew_package' + +Chef.set_resource_priority_array :package, Chef::Resource::HomebrewPackage, os: "darwin" diff --git a/lib/chef/resource_resolver.rb b/lib/chef/resource_resolver.rb index d4151e7125..c9a4cb0d97 100644 --- a/lib/chef/resource_resolver.rb +++ b/lib/chef/resource_resolver.rb @@ -65,11 +65,6 @@ class Chef # this magic stack ranks the resources by where they appear in the resource_priority_map priority_list = [ get_priority_array(node, resource) ].flatten.compact handlers = handlers.sort_by { |x| i = priority_list.index x; i.nil? ? Float::INFINITY : i } - if priority_list.index(handlers.first).nil? - # if we had more than one and we picked one with a precidence of infinity that means that the resource_priority_map - # entry for this resource is missing -- we should probably raise here and force resolution of the ambiguity. - Chef::Log.warn "Ambiguous resource precedence: #{handlers}, please use Chef.set_resource_priority_array to provide determinism" - end handlers = handlers[0..0] end diff --git a/lib/chef/util/path_helper.rb b/lib/chef/util/path_helper.rb index 66c2e3f19f..3378a3fb0a 100644 --- a/lib/chef/util/path_helper.rb +++ b/lib/chef/util/path_helper.rb @@ -16,6 +16,9 @@ # limitations under the License. # +require 'chef/platform/query_helpers' +require 'chef/exceptions' + class Chef class Util class PathHelper @@ -146,10 +149,10 @@ class Chef # Retrieves the "home directory" of the current user while trying to ascertain the existence # of said directory. The path returned uses / for all separators (the ruby standard format). # If the home directory doesn't exist or an error is otherwise encountered, nil is returned. - # + # # If a set of path elements is provided, they are appended as-is to the home path if the - # homepath exists. - # + # homepath exists. + # # If an optional block is provided, the joined path is passed to that block if the home path is # valid and the result of the block is returned instead. # @@ -221,7 +224,3 @@ class Chef end end end - -# Break a require loop when require chef/util/path_helper -require 'chef/platform' -require 'chef/exceptions' diff --git a/spec/functional/resource/template_spec.rb b/spec/functional/resource/template_spec.rb index 35c5166e31..7cd33ed403 100644 --- a/spec/functional/resource/template_spec.rb +++ b/spec/functional/resource/template_spec.rb @@ -31,6 +31,8 @@ describe Chef::Resource::Template do let(:node) do node = Chef::Node.new + node.normal[:os] = 'linux' + node.normal[:os_version] = '1.0.0' node.normal[:slappiness] = "a warm gun" node end diff --git a/spec/unit/provider_resolver_spec.rb b/spec/unit/provider_resolver_spec.rb index bdf6d06e09..a11625d80a 100644 --- a/spec/unit/provider_resolver_spec.rb +++ b/spec/unit/provider_resolver_spec.rb @@ -19,6 +19,7 @@ require 'spec_helper' require 'chef/mixin/convert_to_class_name' require 'chef/provider_resolver' +require 'chef/platform/service_helpers' include Chef::Mixin::ConvertToClassName diff --git a/spec/unit/resource/template_spec.rb b/spec/unit/resource/template_spec.rb index df5ca94b8a..bfd3034129 100644 --- a/spec/unit/resource/template_spec.rb +++ b/spec/unit/resource/template_spec.rb @@ -183,7 +183,7 @@ describe Chef::Resource::Template do expect { @resource.helpers(ExampleHelpers) { module_code } }.to raise_error(Chef::Exceptions::ValidationFailed) end - it "collects helper modules" do + it "collects helper modules", :focus do @resource.helpers(ExampleHelpers) expect(@resource.helper_modules).to include(ExampleHelpers) end |