diff options
author | Seth Chisamore <schisamo@opscode.com> | 2012-10-30 10:39:35 -0400 |
---|---|---|
committer | Seth Chisamore <schisamo@opscode.com> | 2012-10-30 10:39:35 -0400 |
commit | 24dc69a9a97e82a6e4207de68d6dcc664178249b (patch) | |
tree | 19bb289c9f88b4bbab066bc56b95d6d222fd5c35 /lib/chef/provider/package.rb | |
parent | 9348c1c9c80ee757354d624b7dc1b78ebc7605c4 (diff) | |
download | chef-24dc69a9a97e82a6e4207de68d6dcc664178249b.tar.gz |
[OC-3564] move core Chef to the repo root \o/ \m/
The opscode/chef repository now only contains the core Chef library code
used by chef-client, knife and chef-solo!
Diffstat (limited to 'lib/chef/provider/package.rb')
-rw-r--r-- | lib/chef/provider/package.rb | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb new file mode 100644 index 0000000000..a28a6f93fb --- /dev/null +++ b/lib/chef/provider/package.rb @@ -0,0 +1,229 @@ +# +# 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/mixin/command' +require 'chef/log' +require 'chef/file_cache' +require 'chef/platform' + +class Chef + class Provider + class Package < Chef::Provider + + include Chef::Mixin::Command + + attr_accessor :candidate_version + def initialize(new_resource, run_context) + super + @candidate_version = nil + end + + def whyrun_supported? + true + end + + def load_current_resource + end + + def define_resource_requirements + requirements.assert(:install) do |a| + a.assertion { ((@new_resource.version != nil) && !(target_version_already_installed?)) \ + || !(@current_resource.version.nil? && candidate_version.nil?) } + a.failure_message(Chef::Exceptions::Package, "No version specified, and no candidate version available for #{@new_resource.package_name}") + a.whyrun("Assuming a repository that offers #{@new_resource.package_name} would have been configured") + end + + requirements.assert(:upgrade) do |a| + # Can't upgrade what we don't have + a.assertion { !(@current_resource.version.nil? && candidate_version.nil?) } + a.failure_message(Chef::Exceptions::Package, "No candidate version available for #{@new_resource.package_name}") + a.whyrun("Assuming a repository that offers #{@new_resource.package_name} would have been configured") + end + end + + def action_install + # If we specified a version, and it's not the current version, move to the specified version + if !@new_resource.version.nil? && !(target_version_already_installed?) + install_version = @new_resource.version + # If it's not installed at all, install it + elsif @current_resource.version.nil? + install_version = candidate_version + else + Chef::Log.debug("#{@new_resource} is already installed - nothing to do") + return + end + + # We need to make sure we handle the preseed file + if @new_resource.response_file + if preseed_file = get_preseed_file(@new_resource.package_name, install_version) + converge_by("preseed package #{@new_resource.package_name}") do + preseed_package(preseed_file) + end + end + end + description = install_version ? "version #{install_version} of" : "" + converge_by("install #{description} package #{@new_resource.package_name}") do + @new_resource.version(install_version) + install_package(@new_resource.package_name, install_version) + end + end + + def action_upgrade + if candidate_version.nil? + Chef::Log.debug("#{@new_resource} no candidate version - nothing to do") + elsif @current_resource.version == candidate_version + Chef::Log.debug("#{@new_resource} is at the latest version - nothing to do") + else + @new_resource.version(candidate_version) + orig_version = @current_resource.version || "uninstalled" + converge_by("upgrade package #{@new_resource.package_name} from #{orig_version} to #{candidate_version}") do + status = upgrade_package(@new_resource.package_name, candidate_version) + Chef::Log.info("#{@new_resource} upgraded from #{orig_version} to #{candidate_version}") + end + end + end + + def action_remove + if removing_package? + description = @new_resource.version ? "version #{@new_resource.version} of " : "" + converge_by("remove #{description} package #{@current_resource.package_name}") do + remove_package(@current_resource.package_name, @new_resource.version) + Chef::Log.info("#{@new_resource} removed") + end + else + Chef::Log.debug("#{@new_resource} package does not exist - nothing to do") + end + end + + def removing_package? + if @current_resource.version.nil? + false # nothing to remove + elsif @new_resource.version.nil? + true # remove any version of a package + elsif @new_resource.version == @current_resource.version + true # remove the version we have + else + false # we don't have the version we want to remove + end + end + + def action_purge + if removing_package? + description = @new_resource.version ? "version #{@new_resource.version} of" : "" + converge_by("purge #{description} package #{@current_resource.package_name}") do + purge_package(@current_resource.package_name, @new_resource.version) + Chef::Log.info("#{@new_resource} purged") + end + end + end + + def action_reconfig + if @current_resource.version == nil then + Chef::Log.debug("#{@new_resource} is NOT installed - nothing to do") + return + end + + unless @new_resource.response_file then + Chef::Log.debug("#{@new_resource} no response_file provided - nothing to do") + return + end + + if preseed_file = get_preseed_file(@new_resource.package_name, @current_resource.version) + converge_by("reconfigure package #{@new_resource.package_name}") do + preseed_package(preseed_file) + status = reconfig_package(@new_resource.package_name, @current_resource.version) + Chef::Log.info("#{@new_resource} reconfigured") + end + else + Chef::Log.debug("#{@new_resource} preseeding has not changed - nothing to do") + end + end + + def install_package(name, version) + raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :install" + end + + def upgrade_package(name, version) + raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :upgrade" + end + + def remove_package(name, version) + raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :remove" + end + + def purge_package(name, version) + raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :purge" + end + + def preseed_package(file) + raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support pre-seeding package install/upgrade instructions" + end + + def reconfig_package(name, version) + raise( Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reconfig" ) + end + + def get_preseed_file(name, version) + resource = preseed_resource(name, version) + resource.run_action(:create) + Chef::Log.debug("#{@new_resource} fetched preseed file to #{resource.path}") + + if resource.updated_by_last_action? + resource.path + else + false + end + end + + def preseed_resource(name, version) + # A directory in our cache to store this cookbook's preseed files in + file_cache_dir = Chef::FileCache.create_cache_path("preseed/#{@new_resource.cookbook_name}") + # The full path where the preseed file will be stored + cache_seed_to = "#{file_cache_dir}/#{name}-#{version}.seed" + + Chef::Log.debug("#{@new_resource} fetching preseed file to #{cache_seed_to}") + + begin + remote_file = Chef::Resource::Template.new(cache_seed_to, run_context) + remote_file.cookbook_name = @new_resource.cookbook_name + remote_file.source(@new_resource.response_file) + remote_file.backup(false) + provider = Chef::Platform.provider_for_resource(remote_file, :create) + provider.template_location + rescue + Chef::Log.debug("#{@new_resource} fetching preseed file via Template resource failed, fallback to CookbookFile resource") + remote_file = Chef::Resource::CookbookFile.new(cache_seed_to, run_context) + remote_file.cookbook_name = @new_resource.cookbook_name + remote_file.source(@new_resource.response_file) + remote_file.backup(false) + end + + remote_file + end + + def expand_options(options) + options ? " #{options}" : "" + end + + def target_version_already_installed? + @new_resource.version == @current_resource.version + end + + end + end +end |