diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/client.rb | 2 | ||||
-rw-r--r-- | lib/chef/knife/core/ui.rb | 2 | ||||
-rw-r--r-- | lib/chef/platform.rb | 495 | ||||
-rw-r--r-- | lib/chef/platform/provider_mapping.rb | 516 | ||||
-rw-r--r-- | lib/chef/platform/query_helpers.rb | 42 | ||||
-rw-r--r-- | lib/chef/resource/file.rb | 2 | ||||
-rw-r--r-- | lib/chef/rest.rb | 2 | ||||
-rw-r--r-- | lib/chef/runner.rb | 1 |
8 files changed, 565 insertions, 497 deletions
diff --git a/lib/chef/client.rb b/lib/chef/client.rb index da5683840b..24f4448053 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -25,7 +25,7 @@ require 'chef/log' require 'chef/rest' require 'chef/api_client' require 'chef/api_client/registration' -require 'chef/platform' +require 'chef/platform/query_helpers' require 'chef/node' require 'chef/role' require 'chef/file_cache' diff --git a/lib/chef/knife/core/ui.rb b/lib/chef/knife/core/ui.rb index 6af5f17fcb..f18d30a039 100644 --- a/lib/chef/knife/core/ui.rb +++ b/lib/chef/knife/core/ui.rb @@ -19,7 +19,7 @@ # require 'forwardable' -require 'chef/platform' +require 'chef/platform/query_helpers' require 'chef/knife/core/generic_presenter' class Chef diff --git a/lib/chef/platform.rb b/lib/chef/platform.rb index ac89efce5f..4049219897 100644 --- a/lib/chef/platform.rb +++ b/lib/chef/platform.rb @@ -16,478 +16,14 @@ # limitations under the License. # -require 'chef/config' -require 'chef/log' -require 'chef/mixin/params_validate' -require 'chef/version_constraint/platform' - -# This file depends on nearly every provider in chef, but requiring them -# directly causes circular requires resulting in uninitialized constant errors. -require 'chef/provider' -require 'chef/provider/log' -require 'chef/provider/user' -require 'chef/provider/group' -require 'chef/provider/mount' -require 'chef/provider/service' -require 'chef/provider/package' - +require 'chef/platform/provider_mapping' +require 'chef/platform/query_helpers' class Chef class Platform - class << self - attr_writer :platforms - - def platforms - @platforms ||= { - :mac_os_x => { - :default => { - :package => Chef::Provider::Package::Macports, - :service => Chef::Provider::Service::Macosx, - :user => Chef::Provider::User::Dscl, - :group => Chef::Provider::Group::Dscl - } - }, - :mac_os_x_server => { - :default => { - :package => Chef::Provider::Package::Macports, - :service => Chef::Provider::Service::Macosx, - :user => Chef::Provider::User::Dscl, - :group => Chef::Provider::Group::Dscl - } - }, - :freebsd => { - :default => { - :group => Chef::Provider::Group::Pw, - :package => Chef::Provider::Package::Freebsd, - :service => Chef::Provider::Service::Freebsd, - :user => Chef::Provider::User::Pw, - :cron => Chef::Provider::Cron - } - }, - :ubuntu => { - :default => { - :package => Chef::Provider::Package::Apt, - :service => Chef::Provider::Service::Debian, - :cron => Chef::Provider::Cron, - :mdadm => Chef::Provider::Mdadm - } - }, - :gcel => { - :default => { - :package => Chef::Provider::Package::Apt, - :service => Chef::Provider::Service::Debian, - :cron => Chef::Provider::Cron, - :mdadm => Chef::Provider::Mdadm - } - }, - :linaro => { - :default => { - :package => Chef::Provider::Package::Apt, - :service => Chef::Provider::Service::Debian, - :cron => Chef::Provider::Cron, - :mdadm => Chef::Provider::Mdadm - } - }, - :raspbian => { - :default => { - :package => Chef::Provider::Package::Apt, - :service => Chef::Provider::Service::Debian, - :cron => Chef::Provider::Cron, - :mdadm => Chef::Provider::Mdadm - } - }, - :linuxmint => { - :default => { - :package => Chef::Provider::Package::Apt, - :service => Chef::Provider::Service::Upstart, - :cron => Chef::Provider::Cron, - :mdadm => Chef::Provider::Mdadm - } - }, - :debian => { - :default => { - :package => Chef::Provider::Package::Apt, - :service => Chef::Provider::Service::Debian, - :cron => Chef::Provider::Cron, - :mdadm => Chef::Provider::Mdadm - }, - ">= 6.0" => { - :service => Chef::Provider::Service::Insserv - } - }, - :xenserver => { - :default => { - :service => Chef::Provider::Service::Redhat, - :cron => Chef::Provider::Cron, - :package => Chef::Provider::Package::Yum, - :mdadm => Chef::Provider::Mdadm - } - }, - :xcp => { - :default => { - :service => Chef::Provider::Service::Redhat, - :cron => Chef::Provider::Cron, - :package => Chef::Provider::Package::Yum, - :mdadm => Chef::Provider::Mdadm - } - }, - :centos => { - :default => { - :service => Chef::Provider::Service::Redhat, - :cron => Chef::Provider::Cron, - :package => Chef::Provider::Package::Yum, - :mdadm => Chef::Provider::Mdadm - } - }, - :amazon => { - :default => { - :service => Chef::Provider::Service::Redhat, - :cron => Chef::Provider::Cron, - :package => Chef::Provider::Package::Yum, - :mdadm => Chef::Provider::Mdadm - } - }, - :scientific => { - :default => { - :service => Chef::Provider::Service::Redhat, - :cron => Chef::Provider::Cron, - :package => Chef::Provider::Package::Yum, - :mdadm => Chef::Provider::Mdadm - } - }, - :fedora => { - :default => { - :service => Chef::Provider::Service::Redhat, - :cron => Chef::Provider::Cron, - :package => Chef::Provider::Package::Yum, - :mdadm => Chef::Provider::Mdadm - } - }, - :suse => { - :default => { - :service => Chef::Provider::Service::Redhat, - :cron => Chef::Provider::Cron, - :package => Chef::Provider::Package::Zypper, - :group => Chef::Provider::Group::Suse - } - }, - :oracle => { - :default => { - :service => Chef::Provider::Service::Redhat, - :cron => Chef::Provider::Cron, - :package => Chef::Provider::Package::Yum, - :mdadm => Chef::Provider::Mdadm - } - }, - :redhat => { - :default => { - :service => Chef::Provider::Service::Redhat, - :cron => Chef::Provider::Cron, - :package => Chef::Provider::Package::Yum, - :mdadm => Chef::Provider::Mdadm - } - }, - :gentoo => { - :default => { - :package => Chef::Provider::Package::Portage, - :service => Chef::Provider::Service::Gentoo, - :cron => Chef::Provider::Cron, - :mdadm => Chef::Provider::Mdadm - } - }, - :arch => { - :default => { - :package => Chef::Provider::Package::Pacman, - :service => Chef::Provider::Service::Arch, - :cron => Chef::Provider::Cron, - :mdadm => Chef::Provider::Mdadm - } - }, - :mswin => { - :default => { - :env => Chef::Provider::Env::Windows, - :service => Chef::Provider::Service::Windows, - :user => Chef::Provider::User::Windows, - :group => Chef::Provider::Group::Windows, - :mount => Chef::Provider::Mount::Windows - } - }, - :mingw32 => { - :default => { - :env => Chef::Provider::Env::Windows, - :service => Chef::Provider::Service::Windows, - :user => Chef::Provider::User::Windows, - :group => Chef::Provider::Group::Windows, - :mount => Chef::Provider::Mount::Windows - } - }, - :windows => { - :default => { - :env => Chef::Provider::Env::Windows, - :service => Chef::Provider::Service::Windows, - :user => Chef::Provider::User::Windows, - :group => Chef::Provider::Group::Windows, - :mount => Chef::Provider::Mount::Windows - } - }, - :solaris => {}, - :openindiana => { - :default => { - :service => Chef::Provider::Service::Solaris, - :package => Chef::Provider::Package::Ips, - :cron => Chef::Provider::Cron::Solaris, - :group => Chef::Provider::Group::Usermod - } - }, - :opensolaris => { - :default => { - :service => Chef::Provider::Service::Solaris, - :package => Chef::Provider::Package::Ips, - :cron => Chef::Provider::Cron::Solaris, - :group => Chef::Provider::Group::Usermod - } - }, - :nexentacore => { - :default => { - :service => Chef::Provider::Service::Solaris, - :package => Chef::Provider::Package::Solaris, - :cron => Chef::Provider::Cron::Solaris, - :group => Chef::Provider::Group::Usermod - } - }, - :omnios => { - :default => { - :service => Chef::Provider::Service::Solaris, - :package => Chef::Provider::Package::Ips, - :cron => Chef::Provider::Cron::Solaris, - :group => Chef::Provider::Group::Usermod, - :user => Chef::Provider::User::Solaris, - } - }, - :solaris2 => { - :default => { - :service => Chef::Provider::Service::Solaris, - :package => Chef::Provider::Package::Ips, - :cron => Chef::Provider::Cron::Solaris, - :group => Chef::Provider::Group::Usermod, - :user => Chef::Provider::User::Solaris, - }, - ">= 5.9" => { - :service => Chef::Provider::Service::Solaris, - :package => Chef::Provider::Package::Solaris, - :cron => Chef::Provider::Cron::Solaris, - :group => Chef::Provider::Group::Usermod, - :user => Chef::Provider::User::Solaris, - } - }, - :smartos => { - :default => { - :service => Chef::Provider::Service::Solaris, - :package => Chef::Provider::Package::SmartOS, - :cron => Chef::Provider::Cron::Solaris, - :group => Chef::Provider::Group::Usermod - } - }, - :netbsd => { - :default => { - :service => Chef::Provider::Service::Freebsd, - :group => Chef::Provider::Group::Groupmod - } - }, - :openbsd => { - :default => { - :group => Chef::Provider::Group::Usermod - } - }, - :hpux => { - :default => { - :group => Chef::Provider::Group::Usermod - } - }, - :aix => { - :default => { - :group => Chef::Provider::Group::Aix - } - }, - :default => { - :file => Chef::Provider::File, - :directory => Chef::Provider::Directory, - :link => Chef::Provider::Link, - :template => Chef::Provider::Template, - :remote_directory => Chef::Provider::RemoteDirectory, - :execute => Chef::Provider::Execute, - :mount => Chef::Provider::Mount::Mount, - :script => Chef::Provider::Script, - :service => Chef::Provider::Service::Init, - :perl => Chef::Provider::Script, - :python => Chef::Provider::Script, - :ruby => Chef::Provider::Script, - :bash => Chef::Provider::Script, - :csh => Chef::Provider::Script, - :user => Chef::Provider::User::Useradd, - :group => Chef::Provider::Group::Gpasswd, - :http_request => Chef::Provider::HttpRequest, - :route => Chef::Provider::Route, - :ifconfig => Chef::Provider::Ifconfig, - :ruby_block => Chef::Provider::RubyBlock, - :erl_call => Chef::Provider::ErlCall, - :log => Chef::Provider::Log::ChefLog - } - } - end - - include Chef::Mixin::ParamsValidate - - def find(name, version) - provider_map = platforms[:default].clone - - name_sym = name - if name.kind_of?(String) - name.downcase! - name.gsub!(/\s/, "_") - name_sym = name.to_sym - end - - if platforms.has_key?(name_sym) - platform_versions = platforms[name_sym].select {|k, v| k != :default } - if platforms[name_sym].has_key?(:default) - provider_map.merge!(platforms[name_sym][:default]) - end - platform_versions.each do |platform_version, provider| - begin - version_constraint = Chef::VersionConstraint::Platform.new(platform_version) - if version_constraint.include?(version) - Chef::Log.debug("Platform #{name.to_s} version #{version} found") - provider_map.merge!(provider) - end - rescue Chef::Exceptions::InvalidPlatformVersion - Chef::Log.debug("Chef::Version::Comparable does not know how to parse the platform version: #{version}") - end - end - else - Chef::Log.debug("Platform #{name} not found, using all defaults. (Unsupported platform?)") - end - provider_map - end - - def find_platform_and_version(node) - platform = nil - version = nil - - if node[:platform] - platform = node[:platform] - elsif node.attribute?("os") - platform = node[:os] - end - - raise ArgumentError, "Cannot find a platform for #{node}" unless platform - - if node[:platform_version] - version = node[:platform_version] - elsif node[:os_version] - version = node[:os_version] - elsif node[:os_release] - version = node[:os_release] - end - - raise ArgumentError, "Cannot find a version for #{node}" unless version - - return platform, version - end - - def provider_for_resource(resource, action=:nothing) - node = resource.run_context && resource.run_context.node - raise ArgumentError, "Cannot find the provider for a resource with no run context set" unless node - provider = find_provider_for_node(node, resource).new(resource, resource.run_context) - provider.action = action - provider - end - - def provider_for_node(node, resource_type) - raise NotImplementedError, "#{self.class.name} no longer supports #provider_for_node" - find_provider_for_node(node, resource_type).new(node, resource_type) - end - - def find_provider_for_node(node, resource_type) - platform, version = find_platform_and_version(node) - provider = find_provider(platform, version, resource_type) - end - - def set(args) - validate( - args, - { - :platform => { - :kind_of => Symbol, - :required => false, - }, - :version => { - :kind_of => String, - :required => false, - }, - :resource => { - :kind_of => Symbol, - }, - :provider => { - :kind_of => [ String, Symbol, Class ], - } - } - ) - if args.has_key?(:platform) - if args.has_key?(:version) - if platforms.has_key?(args[:platform]) - if platforms[args[:platform]].has_key?(args[:version]) - platforms[args[:platform]][args[:version]][args[:resource].to_sym] = args[:provider] - else - platforms[args[:platform]][args[:version]] = { - args[:resource].to_sym => args[:provider] - } - end - else - platforms[args[:platform]] = { - args[:version] => { - args[:resource].to_sym => args[:provider] - } - } - end - else - if platforms.has_key?(args[:platform]) - if platforms[args[:platform]].has_key?(:default) - platforms[args[:platform]][:default][args[:resource].to_sym] = args[:provider] - else - platforms[args[:platform]] = { :default => { args[:resource].to_sym => args[:provider] } } - end - else - platforms[args[:platform]] = { - :default => { - args[:resource].to_sym => args[:provider] - } - } - end - end - else - if platforms.has_key?(:default) - platforms[:default][args[:resource].to_sym] = args[:provider] - else - platforms[:default] = { - args[:resource].to_sym => args[:provider] - } - end - end - end - - def find_provider(platform, version, resource_type) - pmap = Chef::Platform.find(platform, version) - provider_klass = explicit_provider(platform, version, resource_type) || - platform_provider(platform, version, resource_type) || - resource_matching_provider(platform, version, resource_type) - - raise ArgumentError, "Cannot find a provider for #{resource_type} on #{platform} version #{version}" if provider_klass.nil? - - provider_klass - end + class << self def windows? if RUBY_PLATFORM =~ /mswin|mingw|windows/ true @@ -504,31 +40,6 @@ class Chef host = WMI::Win32_OperatingSystem.find(:first) (host.version && host.version.start_with?("5.2")) end - - private - - def explicit_provider(platform, version, resource_type) - resource_type.kind_of?(Chef::Resource) ? resource_type.provider : nil - end - - def platform_provider(platform, version, resource_type) - pmap = Chef::Platform.find(platform, version) - rtkey = resource_type.kind_of?(Chef::Resource) ? resource_type.resource_name.to_sym : resource_type - pmap.has_key?(rtkey) ? pmap[rtkey] : nil - end - - def resource_matching_provider(platform, version, resource_type) - if resource_type.kind_of?(Chef::Resource) - begin - Chef::Provider.const_get(resource_type.class.to_s.split('::').last) - rescue NameError - nil - end - else - nil - end - end - end end diff --git a/lib/chef/platform/provider_mapping.rb b/lib/chef/platform/provider_mapping.rb new file mode 100644 index 0000000000..fb3530fab7 --- /dev/null +++ b/lib/chef/platform/provider_mapping.rb @@ -0,0 +1,516 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 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/config' +require 'chef/log' +require 'chef/mixin/params_validate' +require 'chef/version_constraint/platform' + +# This file depends on nearly every provider in chef, but requiring them +# directly causes circular requires resulting in uninitialized constant errors. +require 'chef/provider' +require 'chef/provider/log' +require 'chef/provider/user' +require 'chef/provider/group' +require 'chef/provider/mount' +require 'chef/provider/service' +require 'chef/provider/package' + + +class Chef + class Platform + + class << self + attr_writer :platforms + + def platforms + @platforms ||= { + :mac_os_x => { + :default => { + :package => Chef::Provider::Package::Macports, + :service => Chef::Provider::Service::Macosx, + :user => Chef::Provider::User::Dscl, + :group => Chef::Provider::Group::Dscl + } + }, + :mac_os_x_server => { + :default => { + :package => Chef::Provider::Package::Macports, + :service => Chef::Provider::Service::Macosx, + :user => Chef::Provider::User::Dscl, + :group => Chef::Provider::Group::Dscl + } + }, + :freebsd => { + :default => { + :group => Chef::Provider::Group::Pw, + :package => Chef::Provider::Package::Freebsd, + :service => Chef::Provider::Service::Freebsd, + :user => Chef::Provider::User::Pw, + :cron => Chef::Provider::Cron + } + }, + :ubuntu => { + :default => { + :package => Chef::Provider::Package::Apt, + :service => Chef::Provider::Service::Debian, + :cron => Chef::Provider::Cron, + :mdadm => Chef::Provider::Mdadm + } + }, + :gcel => { + :default => { + :package => Chef::Provider::Package::Apt, + :service => Chef::Provider::Service::Debian, + :cron => Chef::Provider::Cron, + :mdadm => Chef::Provider::Mdadm + } + }, + :linaro => { + :default => { + :package => Chef::Provider::Package::Apt, + :service => Chef::Provider::Service::Debian, + :cron => Chef::Provider::Cron, + :mdadm => Chef::Provider::Mdadm + } + }, + :raspbian => { + :default => { + :package => Chef::Provider::Package::Apt, + :service => Chef::Provider::Service::Debian, + :cron => Chef::Provider::Cron, + :mdadm => Chef::Provider::Mdadm + } + }, + :linuxmint => { + :default => { + :package => Chef::Provider::Package::Apt, + :service => Chef::Provider::Service::Upstart, + :cron => Chef::Provider::Cron, + :mdadm => Chef::Provider::Mdadm + } + }, + :debian => { + :default => { + :package => Chef::Provider::Package::Apt, + :service => Chef::Provider::Service::Debian, + :cron => Chef::Provider::Cron, + :mdadm => Chef::Provider::Mdadm + }, + ">= 6.0" => { + :service => Chef::Provider::Service::Insserv + } + }, + :xenserver => { + :default => { + :service => Chef::Provider::Service::Redhat, + :cron => Chef::Provider::Cron, + :package => Chef::Provider::Package::Yum, + :mdadm => Chef::Provider::Mdadm + } + }, + :xcp => { + :default => { + :service => Chef::Provider::Service::Redhat, + :cron => Chef::Provider::Cron, + :package => Chef::Provider::Package::Yum, + :mdadm => Chef::Provider::Mdadm + } + }, + :centos => { + :default => { + :service => Chef::Provider::Service::Redhat, + :cron => Chef::Provider::Cron, + :package => Chef::Provider::Package::Yum, + :mdadm => Chef::Provider::Mdadm + } + }, + :amazon => { + :default => { + :service => Chef::Provider::Service::Redhat, + :cron => Chef::Provider::Cron, + :package => Chef::Provider::Package::Yum, + :mdadm => Chef::Provider::Mdadm + } + }, + :scientific => { + :default => { + :service => Chef::Provider::Service::Redhat, + :cron => Chef::Provider::Cron, + :package => Chef::Provider::Package::Yum, + :mdadm => Chef::Provider::Mdadm + } + }, + :fedora => { + :default => { + :service => Chef::Provider::Service::Redhat, + :cron => Chef::Provider::Cron, + :package => Chef::Provider::Package::Yum, + :mdadm => Chef::Provider::Mdadm + } + }, + :suse => { + :default => { + :service => Chef::Provider::Service::Redhat, + :cron => Chef::Provider::Cron, + :package => Chef::Provider::Package::Zypper, + :group => Chef::Provider::Group::Suse + } + }, + :oracle => { + :default => { + :service => Chef::Provider::Service::Redhat, + :cron => Chef::Provider::Cron, + :package => Chef::Provider::Package::Yum, + :mdadm => Chef::Provider::Mdadm + } + }, + :redhat => { + :default => { + :service => Chef::Provider::Service::Redhat, + :cron => Chef::Provider::Cron, + :package => Chef::Provider::Package::Yum, + :mdadm => Chef::Provider::Mdadm + } + }, + :gentoo => { + :default => { + :package => Chef::Provider::Package::Portage, + :service => Chef::Provider::Service::Gentoo, + :cron => Chef::Provider::Cron, + :mdadm => Chef::Provider::Mdadm + } + }, + :arch => { + :default => { + :package => Chef::Provider::Package::Pacman, + :service => Chef::Provider::Service::Arch, + :cron => Chef::Provider::Cron, + :mdadm => Chef::Provider::Mdadm + } + }, + :mswin => { + :default => { + :env => Chef::Provider::Env::Windows, + :service => Chef::Provider::Service::Windows, + :user => Chef::Provider::User::Windows, + :group => Chef::Provider::Group::Windows, + :mount => Chef::Provider::Mount::Windows + } + }, + :mingw32 => { + :default => { + :env => Chef::Provider::Env::Windows, + :service => Chef::Provider::Service::Windows, + :user => Chef::Provider::User::Windows, + :group => Chef::Provider::Group::Windows, + :mount => Chef::Provider::Mount::Windows + } + }, + :windows => { + :default => { + :env => Chef::Provider::Env::Windows, + :service => Chef::Provider::Service::Windows, + :user => Chef::Provider::User::Windows, + :group => Chef::Provider::Group::Windows, + :mount => Chef::Provider::Mount::Windows + } + }, + :solaris => {}, + :openindiana => { + :default => { + :service => Chef::Provider::Service::Solaris, + :package => Chef::Provider::Package::Ips, + :cron => Chef::Provider::Cron::Solaris, + :group => Chef::Provider::Group::Usermod + } + }, + :opensolaris => { + :default => { + :service => Chef::Provider::Service::Solaris, + :package => Chef::Provider::Package::Ips, + :cron => Chef::Provider::Cron::Solaris, + :group => Chef::Provider::Group::Usermod + } + }, + :nexentacore => { + :default => { + :service => Chef::Provider::Service::Solaris, + :package => Chef::Provider::Package::Solaris, + :cron => Chef::Provider::Cron::Solaris, + :group => Chef::Provider::Group::Usermod + } + }, + :omnios => { + :default => { + :service => Chef::Provider::Service::Solaris, + :package => Chef::Provider::Package::Ips, + :cron => Chef::Provider::Cron::Solaris, + :group => Chef::Provider::Group::Usermod, + :user => Chef::Provider::User::Solaris, + } + }, + :solaris2 => { + :default => { + :service => Chef::Provider::Service::Solaris, + :package => Chef::Provider::Package::Ips, + :cron => Chef::Provider::Cron::Solaris, + :group => Chef::Provider::Group::Usermod, + :user => Chef::Provider::User::Solaris, + }, + ">= 5.9" => { + :service => Chef::Provider::Service::Solaris, + :package => Chef::Provider::Package::Solaris, + :cron => Chef::Provider::Cron::Solaris, + :group => Chef::Provider::Group::Usermod, + :user => Chef::Provider::User::Solaris, + } + }, + :smartos => { + :default => { + :service => Chef::Provider::Service::Solaris, + :package => Chef::Provider::Package::SmartOS, + :cron => Chef::Provider::Cron::Solaris, + :group => Chef::Provider::Group::Usermod + } + }, + :netbsd => { + :default => { + :service => Chef::Provider::Service::Freebsd, + :group => Chef::Provider::Group::Groupmod + } + }, + :openbsd => { + :default => { + :group => Chef::Provider::Group::Usermod + } + }, + :hpux => { + :default => { + :group => Chef::Provider::Group::Usermod + } + }, + :aix => { + :default => { + :group => Chef::Provider::Group::Aix + } + }, + :default => { + :file => Chef::Provider::File, + :directory => Chef::Provider::Directory, + :link => Chef::Provider::Link, + :template => Chef::Provider::Template, + :remote_directory => Chef::Provider::RemoteDirectory, + :execute => Chef::Provider::Execute, + :mount => Chef::Provider::Mount::Mount, + :script => Chef::Provider::Script, + :service => Chef::Provider::Service::Init, + :perl => Chef::Provider::Script, + :python => Chef::Provider::Script, + :ruby => Chef::Provider::Script, + :bash => Chef::Provider::Script, + :csh => Chef::Provider::Script, + :user => Chef::Provider::User::Useradd, + :group => Chef::Provider::Group::Gpasswd, + :http_request => Chef::Provider::HttpRequest, + :route => Chef::Provider::Route, + :ifconfig => Chef::Provider::Ifconfig, + :ruby_block => Chef::Provider::RubyBlock, + :erl_call => Chef::Provider::ErlCall, + :log => Chef::Provider::Log::ChefLog + } + } + end + + include Chef::Mixin::ParamsValidate + + def find(name, version) + provider_map = platforms[:default].clone + + name_sym = name + if name.kind_of?(String) + name.downcase! + name.gsub!(/\s/, "_") + name_sym = name.to_sym + end + + if platforms.has_key?(name_sym) + platform_versions = platforms[name_sym].select {|k, v| k != :default } + if platforms[name_sym].has_key?(:default) + provider_map.merge!(platforms[name_sym][:default]) + end + platform_versions.each do |platform_version, provider| + begin + version_constraint = Chef::VersionConstraint::Platform.new(platform_version) + if version_constraint.include?(version) + Chef::Log.debug("Platform #{name.to_s} version #{version} found") + provider_map.merge!(provider) + end + rescue Chef::Exceptions::InvalidPlatformVersion + Chef::Log.debug("Chef::Version::Comparable does not know how to parse the platform version: #{version}") + end + end + else + Chef::Log.debug("Platform #{name} not found, using all defaults. (Unsupported platform?)") + end + provider_map + end + + def find_platform_and_version(node) + platform = nil + version = nil + + if node[:platform] + platform = node[:platform] + elsif node.attribute?("os") + platform = node[:os] + end + + raise ArgumentError, "Cannot find a platform for #{node}" unless platform + + if node[:platform_version] + version = node[:platform_version] + elsif node[:os_version] + version = node[:os_version] + elsif node[:os_release] + version = node[:os_release] + end + + raise ArgumentError, "Cannot find a version for #{node}" unless version + + return platform, version + end + + def provider_for_resource(resource, action=:nothing) + node = resource.run_context && resource.run_context.node + raise ArgumentError, "Cannot find the provider for a resource with no run context set" unless node + provider = find_provider_for_node(node, resource).new(resource, resource.run_context) + provider.action = action + provider + end + + def provider_for_node(node, resource_type) + raise NotImplementedError, "#{self.class.name} no longer supports #provider_for_node" + find_provider_for_node(node, resource_type).new(node, resource_type) + end + + def find_provider_for_node(node, resource_type) + platform, version = find_platform_and_version(node) + find_provider(platform, version, resource_type) + end + + def set(args) + validate( + args, + { + :platform => { + :kind_of => Symbol, + :required => false, + }, + :version => { + :kind_of => String, + :required => false, + }, + :resource => { + :kind_of => Symbol, + }, + :provider => { + :kind_of => [ String, Symbol, Class ], + } + } + ) + if args.has_key?(:platform) + if args.has_key?(:version) + if platforms.has_key?(args[:platform]) + if platforms[args[:platform]].has_key?(args[:version]) + platforms[args[:platform]][args[:version]][args[:resource].to_sym] = args[:provider] + else + platforms[args[:platform]][args[:version]] = { + args[:resource].to_sym => args[:provider] + } + end + else + platforms[args[:platform]] = { + args[:version] => { + args[:resource].to_sym => args[:provider] + } + } + end + else + if platforms.has_key?(args[:platform]) + if platforms[args[:platform]].has_key?(:default) + platforms[args[:platform]][:default][args[:resource].to_sym] = args[:provider] + else + platforms[args[:platform]] = { :default => { args[:resource].to_sym => args[:provider] } } + end + else + platforms[args[:platform]] = { + :default => { + args[:resource].to_sym => args[:provider] + } + } + end + end + else + if platforms.has_key?(:default) + platforms[:default][args[:resource].to_sym] = args[:provider] + else + platforms[:default] = { + args[:resource].to_sym => args[:provider] + } + end + end + end + + def find_provider(platform, version, resource_type) + provider_klass = explicit_provider(platform, version, resource_type) || + platform_provider(platform, version, resource_type) || + resource_matching_provider(platform, version, resource_type) + + raise ArgumentError, "Cannot find a provider for #{resource_type} on #{platform} version #{version}" if provider_klass.nil? + + provider_klass + end + + private + + def explicit_provider(platform, version, resource_type) + resource_type.kind_of?(Chef::Resource) ? resource_type.provider : nil + end + + def platform_provider(platform, version, resource_type) + pmap = Chef::Platform.find(platform, version) + rtkey = resource_type.kind_of?(Chef::Resource) ? resource_type.resource_name.to_sym : resource_type + pmap.has_key?(rtkey) ? pmap[rtkey] : nil + end + + def resource_matching_provider(platform, version, resource_type) + if resource_type.kind_of?(Chef::Resource) + begin + Chef::Provider.const_get(resource_type.class.to_s.split('::').last) + rescue NameError + nil + end + else + nil + end + end + + end + end +end diff --git a/lib/chef/platform/query_helpers.rb b/lib/chef/platform/query_helpers.rb new file mode 100644 index 0000000000..028a220a5d --- /dev/null +++ b/lib/chef/platform/query_helpers.rb @@ -0,0 +1,42 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 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. +# + +class Chef + class Platform + + class << self + def windows? + if RUBY_PLATFORM =~ /mswin|mingw|windows/ + true + else + false + end + end + + def windows_server_2003? + return false unless windows? + + require 'ruby-wmi' + + host = WMI::Win32_OperatingSystem.find(:first) + (host.version && host.version.start_with?("5.2")) + end + end + + end +end diff --git a/lib/chef/resource/file.rb b/lib/chef/resource/file.rb index 0b92f3332d..2aea4a9431 100644 --- a/lib/chef/resource/file.rb +++ b/lib/chef/resource/file.rb @@ -18,7 +18,7 @@ # require 'chef/resource' -require 'chef/platform' +require 'chef/platform/query_helpers' require 'chef/provider/file' require 'chef/mixin/securable' diff --git a/lib/chef/rest.rb b/lib/chef/rest.rb index 85d6c5eafe..92b7c38b39 100644 --- a/lib/chef/rest.rb +++ b/lib/chef/rest.rb @@ -31,7 +31,7 @@ require 'chef/monkey_patches/string' require 'chef/monkey_patches/net_http' require 'chef/config' require 'chef/exceptions' -require 'chef/platform' +require 'chef/platform/query_helpers' class Chef diff --git a/lib/chef/runner.rb b/lib/chef/runner.rb index daa928e7a3..6125fe59e1 100644 --- a/lib/chef/runner.rb +++ b/lib/chef/runner.rb @@ -22,7 +22,6 @@ require 'chef/exceptions' require 'chef/mixin/params_validate' require 'chef/node' require 'chef/resource_collection' -require 'chef/platform' class Chef # == Chef::Runner |