Class: Chef::Provider::Package
- Inherits:
-
Chef::Provider
- Object
- Chef::Provider
- Chef::Provider::Package
- Includes:
- Mixin::Command, Mixin::ShellOut
- Defined in:
- lib/chef/provider/package.rb,
lib/chef/provider/package/aix.rb,
lib/chef/provider/package/apt.rb,
lib/chef/provider/package/ips.rb,
lib/chef/provider/package/rpm.rb,
lib/chef/provider/package/yum.rb,
lib/chef/provider/package/dpkg.rb,
lib/chef/provider/package/pacman.rb,
lib/chef/provider/package/zypper.rb,
lib/chef/provider/package/openbsd.rb,
lib/chef/provider/package/paludis.rb,
lib/chef/provider/package/portage.rb,
lib/chef/provider/package/smartos.rb,
lib/chef/provider/package/solaris.rb,
lib/chef/provider/package/windows.rb,
lib/chef/provider/package/homebrew.rb,
lib/chef/provider/package/macports.rb,
lib/chef/provider/package/rubygems.rb,
lib/chef/provider/package/freebsd/pkg.rb,
lib/chef/provider/package/windows/msi.rb,
lib/chef/provider/package/easy_install.rb,
lib/chef/provider/package/freebsd/base.rb,
lib/chef/provider/package/freebsd/port.rb,
lib/chef/provider/package/freebsd/pkgng.rb
Direct Known Subclasses
Aix, Apt, Dpkg, EasyInstall, Freebsd::Base, Homebrew, Ips, Macports, Openbsd, Pacman, Paludis, Portage, Rpm, Rubygems, SmartOS, Solaris, Windows, Yum, Zypper
Defined Under Namespace
Modules: Freebsd Classes: Aix, Apt, Dpkg, EasyInstall, Homebrew, Ips, Macports, Openbsd, Pacman, Paludis, Portage, Rpm, Rubygems, SmartOS, Solaris, Windows, Yum, Zypper
Constant Summary
Constants included from Mixin::ShellOut
Mixin::ShellOut::DEPRECATED_OPTIONS
Instance Attribute Summary collapse
-
#candidate_version ⇒ Array, String
Hook that subclasses use to populate the candidate_version(s).
Attributes inherited from Chef::Provider
#action, #cookbook_name, #current_resource, #new_resource, #recipe_name, #run_context
Instance Method Summary collapse
- #action_install ⇒ Object
-
#action_purge ⇒ Object
@todo: ability to purge an array of packages.
-
#action_reconfig ⇒ Object
@todo: ability to reconfigure an array of packages.
-
#action_remove ⇒ Object
@todo: ability to remove an array of packages.
- #action_upgrade ⇒ Object
-
#as_array(thing) ⇒ Object
helper method used by subclasses.
- #define_resource_requirements ⇒ Object
-
#expand_options(options) ⇒ Object
this is heavily used by subclasses.
-
#get_preseed_file(name, version) ⇒ Object
@todo: extract apt/dpkg specific preseeding to a helper class.
- #have_any_matching_version? ⇒ Boolean
-
#initialize(new_resource, run_context) ⇒ Package
constructor
A new instance of Package.
- #install_package(name, version) ⇒ Object
- #load_current_resource ⇒ Object
- #preseed_package(file) ⇒ Object
-
#preseed_resource(name, version) ⇒ Object
@todo: extract apt/dpkg specific preseeding to a helper class.
- #purge_package(name, version) ⇒ Object
- #reconfig_package(name, version) ⇒ Object
- #remove_package(name, version) ⇒ Object
- #removing_package? ⇒ Boolean
-
#target_version_already_installed?(current_version, new_version) ⇒ Boolean
this is public and overridden by subclasses (rubygems package implements ‘>=’ and ‘~>’ operators).
- #upgrade_package(name, version) ⇒ Object
- #whyrun_supported? ⇒ Boolean
Methods included from Mixin::ShellOut
#run_command_compatible_options, #shell_out, #shell_out!, #shell_out_with_systems_locale, #shell_out_with_systems_locale!
Methods included from Mixin::Command
#chdir_or_tmpdir, #handle_command_failures, #output_of_command, #run_command, #run_command_and_return_stdout_stderr, #run_command_with_systems_locale
Methods included from Mixin::Command::Windows
Methods included from Mixin::Command::Unix
Methods inherited from Chef::Provider
#action_nothing, #cleanup_after_converge, #converge_by, #events, #node, node_map, #process_resource_requirements, provides, provides?, #requirements, #resource_collection, #resource_updated?, #run_action, #set_updated_status, supports?, #whyrun_mode?
Methods included from Mixin::DescendantsTracker
#descendants, descendants, direct_descendants, #direct_descendants, find_descendants_by_name, #find_descendants_by_name, #inherited, store_inherited
Constructor Details
#initialize(new_resource, run_context) ⇒ Package
Returns a new instance of Package.
37 38 39 40 |
# File 'lib/chef/provider/package.rb', line 37 def initialize(new_resource, run_context) super @candidate_version = nil end |
Instance Attribute Details
#candidate_version ⇒ Array, String
Hook that subclasses use to populate the candidate_version(s)
35 36 37 |
# File 'lib/chef/provider/package.rb', line 35 def candidate_version @candidate_version end |
Instance Method Details
#action_install ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/chef/provider/package.rb', line 68 def action_install unless target_version_array.any? Chef::Log.debug("#{@new_resource} is already installed - nothing to do") return end # @todo: move the preseed code out of the base class (and complete the fix for Array of preseeds? ugh...) if @new_resource.response_file if preseed_file = get_preseed_file(package_names_for_targets, versions_for_targets) converge_by("preseed package #{package_names_for_targets}") do preseed_package(preseed_file) end end end # XXX: mutating the new resource is generally bad @new_resource.version(versions_for_new_resource) converge_by(install_description) do install_package(package_names_for_targets, versions_for_targets) Chef::Log.info("#{@new_resource} installed #{package_names_for_targets} at #{versions_for_targets}") end end |
#action_purge ⇒ Object
@todo: ability to purge an array of packages
170 171 172 173 174 175 176 177 178 |
# File 'lib/chef/provider/package.rb', line 170 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 |
#action_reconfig ⇒ Object
@todo: ability to reconfigure an array of packages
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/chef/provider/package.rb', line 181 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) 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 |
#action_remove ⇒ Object
@todo: ability to remove an array of packages
136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/chef/provider/package.rb', line 136 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 |
#action_upgrade ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/chef/provider/package.rb', line 104 def action_upgrade if !target_version_array.any? Chef::Log.debug("#{@new_resource} no versions to upgrade - nothing to do") return end # XXX: mutating the new resource is generally bad @new_resource.version(versions_for_new_resource) converge_by(upgrade_description) do upgrade_package(package_names_for_targets, versions_for_targets) log_allow_downgrade = allow_downgrade ? '(allow_downgrade)' : '' Chef::Log.info("#{@new_resource} upgraded#{log_allow_downgrade} #{package_names_for_targets} to #{versions_for_targets}") end end |
#as_array(thing) ⇒ Object
helper method used by subclasses
280 281 282 |
# File 'lib/chef/provider/package.rb', line 280 def as_array(thing) [ thing ].flatten end |
#define_resource_requirements ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/chef/provider/package.rb', line 49 def define_resource_requirements # XXX: upgrade with a specific version doesn't make a whole lot of sense, but why don't we throw this anyway if it happens? # if not, shouldn't we raise to tell the user to use install instead of upgrade if they want to pin a version? requirements.assert(:install) do |a| a.assertion { candidates_exist_for_all_forced_changes? } a.(Chef::Exceptions::Package, "No version specified, and no candidate version available for #{forced_packages_missing_candidates.join(", ")}") a.whyrun("Assuming a repository that offers #{forced_packages_missing_candidates.join(", ")} would have been configured") end # XXX: Does it make sense to pass in a source with :upgrade? Probably # not, but as with the above comment, we don't yet enforce such a thing, # so we'll just leave things as-is for now. requirements.assert(:upgrade, :install) do |a| a.assertion { candidates_exist_for_all_uninstalled? || new_resource.source } a.(Chef::Exceptions::Package, "No candidate version available for #{packages_missing_candidates.join(", ")}") a.whyrun("Assuming a repository that offers #{packages_missing_candidates.join(", ")} would have been configured") end end |
#expand_options(options) ⇒ Object
this is heavily used by subclasses
229 230 231 |
# File 'lib/chef/provider/package.rb', line 229 def () ? " #{options}" : "" end |
#get_preseed_file(name, version) ⇒ Object
@todo: extract apt/dpkg specific preseeding to a helper class
239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/chef/provider/package.rb', line 239 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 |
#have_any_matching_version? ⇒ Boolean
148 149 150 151 152 153 154 |
# File 'lib/chef/provider/package.rb', line 148 def have_any_matching_version? f = [] new_version_array.each_with_index do |item, index| f << (item == current_version_array[index]) end f.any? end |
#install_package(name, version) ⇒ Object
use composition rather than inheritance
204 205 206 |
# File 'lib/chef/provider/package.rb', line 204 def install_package(name, version) raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :install" end |
#load_current_resource ⇒ Object
46 47 |
# File 'lib/chef/provider/package.rb', line 46 def load_current_resource end |
#preseed_package(file) ⇒ Object
220 221 222 |
# File 'lib/chef/provider/package.rb', line 220 def preseed_package(file) raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support pre-seeding package install/upgrade instructions" end |
#preseed_resource(name, version) ⇒ Object
@todo: extract apt/dpkg specific preseeding to a helper class
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/chef/provider/package.rb', line 252 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}") if template_available?(@new_resource.response_file) Chef::Log.debug("#{@new_resource} fetching preseed file via Template") remote_file = Chef::Resource::Template.new(cache_seed_to, run_context) remote_file.variables(@new_resource.response_file_variables) elsif cookbook_file_available?(@new_resource.response_file) Chef::Log.debug("#{@new_resource} fetching preseed file via cookbook_file") remote_file = Chef::Resource::CookbookFile.new(cache_seed_to, run_context) else = "No template or cookbook file found for response file #{@new_resource.response_file}" raise Chef::Exceptions::FileNotFound, end remote_file.cookbook_name = @new_resource.cookbook_name remote_file.source(@new_resource.response_file) remote_file.backup(false) remote_file end |
#purge_package(name, version) ⇒ Object
216 217 218 |
# File 'lib/chef/provider/package.rb', line 216 def purge_package(name, version) raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :purge" end |
#reconfig_package(name, version) ⇒ Object
224 225 226 |
# File 'lib/chef/provider/package.rb', line 224 def reconfig_package(name, version) raise( Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reconfig" ) end |
#remove_package(name, version) ⇒ Object
212 213 214 |
# File 'lib/chef/provider/package.rb', line 212 def remove_package(name, version) raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :remove" end |
#removing_package? ⇒ Boolean
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/chef/provider/package.rb', line 156 def removing_package? if !current_version_array.any? # ! any? means it's all nil's, which means nothing is installed false elsif !new_version_array.any? true # remove any version of all packages elsif have_any_matching_version? true # remove the version we have else false # we don't have the version we want to remove end end |
#target_version_already_installed?(current_version, new_version) ⇒ Boolean
this is public and overridden by subclasses (rubygems package implements ‘>=’ and ‘~>’ operators)
234 235 236 |
# File 'lib/chef/provider/package.rb', line 234 def target_version_already_installed?(current_version, new_version) new_version == current_version end |
#upgrade_package(name, version) ⇒ Object
208 209 210 |
# File 'lib/chef/provider/package.rb', line 208 def upgrade_package(name, version) raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :upgrade" end |
#whyrun_supported? ⇒ Boolean
42 43 44 |
# File 'lib/chef/provider/package.rb', line 42 def whyrun_supported? true end |