Class: Chef::Provider::Package
- Inherits:
-
Chef::Provider
- Object
- Chef::Provider
- Chef::Provider::Package
- Extended by:
- Mixin::SubclassDirective
- 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/chocolatey.rb,
lib/chef/provider/package/freebsd/pkg.rb,
lib/chef/provider/package/windows/exe.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,
lib/chef/provider/package/yum/rpm_utils.rb,
lib/chef/provider/package/yum/yum_cache.rb,
lib/chef/provider/package/windows/registry_uninstall_entry.rb
Direct Known Subclasses
Aix, Apt, Chocolatey, 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, Chocolatey, 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
- #action_reconfig ⇒ Object
- #action_remove ⇒ Object
- #action_upgrade ⇒ Object
-
#as_array(thing) ⇒ Object
helper method used by subclasses.
- #check_resource_semantics! ⇒ Object
- #define_resource_requirements ⇒ Object
-
#expand_options(options) ⇒ Object
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
- #multipackage_api_adapter(name, version) ⇒ 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, target_version) ⇒ Boolean
Check the current_version against either the candidate_version or the new_version.
- #upgrade_package(name, version) ⇒ Object
-
#version_requirement_satisfied?(current_version, new_version) ⇒ Boolean
Check the current_version against the new_resource.version, possibly using fuzzy matching criteria.
- #whyrun_supported? ⇒ Boolean
Methods included from Mixin::SubclassDirective
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, #converge_if_changed, #events, include_resource_dsl, include_resource_dsl_module, #node, #process_resource_requirements, provides, provides?, #requirements, #resource_collection, #resource_updated?, #run_action, #set_updated_status, supports?, use_inline_resources, #whyrun_mode?
Methods included from Mixin::Provides
#provided_as, #provides, #provides?
Methods included from Mixin::DescendantsTracker
#descendants, descendants, direct_descendants, #direct_descendants, find_descendants_by_name, #find_descendants_by_name, #inherited, store_inherited
Methods included from DeprecatedLWRPClass
#const_missing, #deprecated_constants, #register_deprecated_lwrp_class
Methods included from Mixin::LazyModuleInclude
#descendants, #include, #included
Methods included from Mixin::NotifyingBlock
#notifying_block, #subcontext_block
Methods included from DSL::DeclareResource
#build_resource, #declare_resource, #delete_resource, #delete_resource!, #edit_resource, #edit_resource!, #find_resource, #find_resource!, #with_run_context
Methods included from Mixin::PowershellOut
#powershell_out, #powershell_out!
Methods included from Mixin::WindowsArchitectureHelper
#assert_valid_windows_architecture!, #disable_wow64_file_redirection, #forced_32bit_override_required?, #is_i386_process_on_x86_64_windows?, #node_supports_windows_architecture?, #node_windows_architecture, #restore_wow64_file_redirection, #valid_windows_architecture?, #with_os_architecture, #wow64_architecture_override_required?, #wow64_directory
Methods included from DSL::PlatformIntrospection
#docker?, #platform?, #platform_family?, #value_for_platform, #value_for_platform_family
Constructor Details
#initialize(new_resource, run_context) ⇒ Package
Returns a new instance of Package.
45 46 47 48 |
# File 'lib/chef/provider/package.rb', line 45 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)
43 44 45 |
# File 'lib/chef/provider/package.rb', line 43 def candidate_version @candidate_version end |
Instance Method Details
#action_install ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/chef/provider/package.rb', line 84 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 converge_by(install_description) do multipackage_api_adapter(package_names_for_targets, versions_for_targets) do |name, version| install_package(name, version) end Chef::Log.info("#{@new_resource} installed #{package_names_for_targets} at #{versions_for_targets}") end end |
#action_purge ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/chef/provider/package.rb', line 184 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 multipackage_api_adapter(@current_resource.package_name, @new_resource.version) do |name, version| purge_package(name, version) end Chef::Log.info("#{@new_resource} purged") end end end |
#action_reconfig ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/chef/provider/package.rb', line 196 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) multipackage_api_adapter(@new_resource.package_name, @current_resource.version) do |name, version| reconfig_package(name, version) end 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
149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/chef/provider/package.rb', line 149 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 multipackage_api_adapter(@current_resource.package_name, @new_resource.version) do |name, version| remove_package(name, version) end 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
119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/chef/provider/package.rb', line 119 def action_upgrade if !target_version_array.any? Chef::Log.debug("#{@new_resource} no versions to upgrade - nothing to do") return end converge_by(upgrade_description) do multipackage_api_adapter(package_names_for_targets, versions_for_targets) do |name, version| upgrade_package(name, version) end 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
339 340 341 |
# File 'lib/chef/provider/package.rb', line 339 def as_array(thing) [ thing ].flatten end |
#check_resource_semantics! ⇒ Object
54 55 56 57 58 59 60 |
# File 'lib/chef/provider/package.rb', line 54 def check_resource_semantics! # FIXME: this is not universally true and subclasses are needing to override this and no-ops it. It should be turned into # another "subclass_directive" and the apt and yum providers should declare that they need this behavior. if new_resource.package_name.is_a?(Array) && new_resource.source != nil raise Chef::Exceptions::InvalidResourceSpecification, "You may not specify both multipackage and source" end end |
#define_resource_requirements ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/chef/provider/package.rb', line 65 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
used by subclasses. deprecated. use #a_to_s instead.
256 257 258 |
# File 'lib/chef/provider/package.rb', line 256 def () ? " #{}" : "" end |
#get_preseed_file(name, version) ⇒ Object
@todo: extract apt/dpkg specific preseeding to a helper class
298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/chef/provider/package.rb', line 298 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
163 164 165 166 167 168 169 |
# File 'lib/chef/provider/package.rb', line 163 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
231 232 233 |
# File 'lib/chef/provider/package.rb', line 231 def install_package(name, version) raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :install" end |
#load_current_resource ⇒ Object
62 63 |
# File 'lib/chef/provider/package.rb', line 62 def load_current_resource end |
#multipackage_api_adapter(name, version) ⇒ Object
use composition rather than inheritance
223 224 225 226 227 228 229 |
# File 'lib/chef/provider/package.rb', line 223 def multipackage_api_adapter(name, version) if use_multipackage_api? yield [name].flatten, [version].flatten else yield name, version end end |
#preseed_package(file) ⇒ Object
247 248 249 |
# File 'lib/chef/provider/package.rb', line 247 def preseed_package(file) raise Chef::Exceptions::UnsupportedAction, "#{self} 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
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/chef/provider/package.rb', line 311 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
243 244 245 |
# File 'lib/chef/provider/package.rb', line 243 def purge_package(name, version) raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :purge" end |
#reconfig_package(name, version) ⇒ Object
251 252 253 |
# File 'lib/chef/provider/package.rb', line 251 def reconfig_package(name, version) raise( Chef::Exceptions::UnsupportedAction, "#{self} does not support :reconfig" ) end |
#remove_package(name, version) ⇒ Object
239 240 241 |
# File 'lib/chef/provider/package.rb', line 239 def remove_package(name, version) raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :remove" end |
#removing_package? ⇒ Boolean
171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/chef/provider/package.rb', line 171 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, target_version) ⇒ Boolean
Check the current_version against either the candidate_version or the new_version
For some reason the windows provider subclasses this (to implement passing Arrays to versions for some reason other than multipackage stuff, which is mildly terrifying).
This MUST have ‘equality’ semantics – the exact thing matches the exact thing.
The current_version should probably be dropped out of the method signature, it should always be the first argument.
The name is not just bad, but i find it completely misleading, consider:
target_version_already_installed?(current_version, new_version)
target_version_already_installed?(current_version, candidate_version)
which of those is the ‘target_version’? i’d say the new_version and i’m confused when i see it called with the candidate_version.
‘current_version_equals?(version)` would be a better name
279 280 281 282 |
# File 'lib/chef/provider/package.rb', line 279 def target_version_already_installed?(current_version, target_version) return false unless current_version && target_version current_version == target_version end |
#upgrade_package(name, version) ⇒ Object
235 236 237 |
# File 'lib/chef/provider/package.rb', line 235 def upgrade_package(name, version) raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :upgrade" end |
#version_requirement_satisfied?(current_version, new_version) ⇒ Boolean
Check the current_version against the new_resource.version, possibly using fuzzy matching criteria.
Subclasses MAY override this to provide fuzzy matching on the resource (‘>=’ and ‘~>’ stuff)
This should only ever be offered the same arguments (so they should most likely be removed from the method signature).
‘new_version_satisfied?()` might be a better name
293 294 295 |
# File 'lib/chef/provider/package.rb', line 293 def version_requirement_satisfied?(current_version, new_version) target_version_already_installed?(current_version, new_version) end |
#whyrun_supported? ⇒ Boolean
50 51 52 |
# File 'lib/chef/provider/package.rb', line 50 def whyrun_supported? true end |