summaryrefslogtreecommitdiff
path: root/lib/chef/provider/package.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef/provider/package.rb')
-rw-r--r--lib/chef/provider/package.rb58
1 files changed, 40 insertions, 18 deletions
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb
index 6cbc8c7b24..e71bee2b0d 100644
--- a/lib/chef/provider/package.rb
+++ b/lib/chef/provider/package.rb
@@ -28,14 +28,33 @@ class Chef
class Package < Chef::Provider
extend Chef::Mixin::SubclassDirective
- # subclasses declare this if they want all their arguments as arrays of packages and names
+ # subclasses declare this if they want all their arguments as arrays of packages and names.
+ # any new packages using this should also use allow_nils below.
+ #
subclass_directive :use_multipackage_api
- # subclasses declare this if they want sources (filenames) pulled from their package names
+
+ # subclasses declare this if they want sources (filenames) pulled from their package names.
+ # this is for package providers that take a path into the filesystem (rpm, dpkg).
+ #
subclass_directive :use_package_name_for_source
+
# keeps package_names_for_targets and versions_for_targets indexed the same as package_name at
- # the cost of having the subclass needing to deal with nils
+ # the cost of having the subclass needing to deal with nils. all providers are encouraged to
+ # migrate to using this as it simplifies dealing with package aliases in subclasses.
+ #
subclass_directive :allow_nils
+ # subclasses that implement complex pattern matching using constraints, particularly the yum and
+ # dnf classes, should filter the installed version against the desired version constraint and
+ # return nil if it does not match. this means that 'nil' does not mean that no version of the
+ # package is installed, but that the installed version does not satisfy the desired constraints.
+ # (the package plus the constraints are not installed)
+ #
+ # [ this may arguably be useful for all package providers and it greatly simplifies the logic
+ # in the superclass that gets executed, so maybe this should always be used now? ]
+ #
+ subclass_directive :installed_version_satisfies_version_constraints
+
#
# Hook that subclasses use to populate the candidate_version(s)
#
@@ -414,19 +433,19 @@ class Chef
each_package do |package_name, new_version, current_version, candidate_version|
case action
when :upgrade
- if version_equals?(current_version, new_version)
- # this is an odd use case
- logger.trace("#{new_resource} #{package_name} #{new_version} is already installed -- you are equality pinning with an :upgrade action, this may be deprecated in the future")
- target_version_array.push(nil)
- elsif version_equals?(current_version, candidate_version)
- logger.trace("#{new_resource} #{package_name} #{candidate_version} is already installed")
+ if current_version.nil?
+ logger.trace("#{new_resource} has no existing installed version. Installing install #{candidate_version}")
+ target_version_array.push(candidate_version)
+ elsif version_equals?(current_version, new_version)
+ # this is a short-circuit to avoid needing to (expensively) query the candidate_version which must come later
+ logger.trace("#{new_resource} #{package_name} #{new_version} is already installed")
target_version_array.push(nil)
elsif candidate_version.nil?
logger.trace("#{new_resource} #{package_name} has no candidate_version to upgrade to")
target_version_array.push(nil)
- elsif current_version.nil?
- logger.trace("#{new_resource} has no existing installed version. Installing install #{candidate_version}")
- target_version_array.push(candidate_version)
+ elsif version_equals?(current_version, candidate_version)
+ logger.trace("#{new_resource} #{package_name} #{candidate_version} is already installed")
+ target_version_array.push(nil)
elsif !allow_downgrade && version_compare(current_version, candidate_version) == 1
logger.trace("#{new_resource} #{package_name} has installed version #{current_version}, which is newer than available version #{candidate_version}. Skipping...)")
target_version_array.push(nil)
@@ -436,16 +455,13 @@ class Chef
end
when :install
- if new_version
+ if new_version && !installed_version_satisfies_version_constraints?
if version_requirement_satisfied?(current_version, new_version)
logger.trace("#{new_resource} #{package_name} #{current_version} satisfies #{new_version} requirement")
target_version_array.push(nil)
elsif current_version && !allow_downgrade && version_compare(current_version, new_version) == 1
logger.warn("#{new_resource} #{package_name} has installed version #{current_version}, which is newer than available version #{new_version}. Skipping...)")
target_version_array.push(nil)
- elsif version_equals?(current_version, candidate_version)
- logger.trace("#{new_resource} #{package_name} #{candidate_version} is already installed")
- target_version_array.push(nil)
else
logger.trace("#{new_resource} #{package_name} #{current_version} needs updating to #{new_version}")
target_version_array.push(new_version)
@@ -511,8 +527,14 @@ class Chef
each_package do |package_name, new_version, current_version, candidate_version|
next if new_version.nil? || current_version.nil?
- if !version_requirement_satisfied?(current_version, new_version) && candidate_version.nil?
- missing.push(package_name)
+ if installed_version_satisfies_version_constraints?
+ if !current_version && candidate_version.nil?
+ missing.push(package_name)
+ end
+ else
+ if !version_requirement_satisfied?(current_version, new_version) && candidate_version.nil?
+ missing.push(package_name)
+ end
end
end
missing