summaryrefslogtreecommitdiff
path: root/lib/chef/provider
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2015-02-16 19:12:06 -0800
committerLamont Granquist <lamont@scriptkiddie.org>2015-02-17 13:58:08 -0800
commite40a02ecbb9c806ca7782741492dc7be2423d884 (patch)
tree045c6b84f8cccc4bcccad0dd261108a034600b3f /lib/chef/provider
parent9b99bf076324659d70055226713495c67dbeaa8d (diff)
downloadchef-e40a02ecbb9c806ca7782741492dc7be2423d884.tar.gz
fix virtual package logic in check_package_state
since check_package_state calls itself to check virtual packages the array building it does was getting indexed incorrectly as the virtual packages were getting inserted into arrays that were supposed to be indexed by the package arguments the user gave. there was also a bug which broke idempotency with virtual packages and would cause virtual packages to get reinstalled every time (installed_version not geting correctly inherited from the virtual package). WIP2 remove debug fix specs
Diffstat (limited to 'lib/chef/provider')
-rw-r--r--lib/chef/provider/package/apt.rb166
1 files changed, 78 insertions, 88 deletions
diff --git a/lib/chef/provider/package/apt.rb b/lib/chef/provider/package/apt.rb
index 584d1cf75a..e426b51992 100644
--- a/lib/chef/provider/package/apt.rb
+++ b/lib/chef/provider/package/apt.rb
@@ -38,7 +38,7 @@ class Chef
def load_current_resource
@current_resource = Chef::Resource::Package.new(@new_resource.name)
@current_resource.package_name(@new_resource.package_name)
- check_package_state(@new_resource.package_name)
+ check_all_packages_state(@new_resource.package_name)
@current_resource
end
@@ -56,89 +56,91 @@ class Chef
"-o APT::Default-Release=#{@new_resource.default_release}" if @new_resource.respond_to?(:default_release) && @new_resource.default_release
end
- def check_package_state(package)
- final_installed_version = []
- final_candidate_version = []
- final_installed = []
- final_virtual = []
-
- [package].flatten.each do |pkg|
- installed = virtual = false
- installed_version = candidate_version = nil
- shell_out!("apt-cache#{expand_options(default_release_options)} policy #{pkg}", {:timeout=>900}).stdout.each_line do |line|
- case line
- when /^\s{2}Installed: (.+)$/
- installed_version = $1
- if installed_version == '(none)'
- Chef::Log.debug("#{@new_resource} current version is nil")
- installed_version = nil
- else
- Chef::Log.debug("#{@new_resource} current version is #{installed_version}")
- installed = true
- end
- when /^\s{2}Candidate: (.+)$/
- candidate_version = $1
- if candidate_version == '(none)'
- # This may not be an appropriate assumption, but it shouldn't break anything that already worked -- btm
- virtual = true
- showpkg = shell_out!("apt-cache showpkg #{pkg}", {:timeout => 900}).stdout
- providers = Hash.new
- showpkg.rpartition(/Reverse Provides: ?#{$/}/)[2].each_line do |line|
- provider, version = line.split
- providers[provider] = version
- end
- # Check if the package providing this virtual package is installed
- num_providers = providers.length
- raise Chef::Exceptions::Package, "#{@new_resource.package_name} has no candidate in the apt-cache" if num_providers == 0
- # apt will only install a virtual package if there is a single providing package
- raise Chef::Exceptions::Package, "#{@new_resource.package_name} is a virtual package provided by #{num_providers} packages, you must explicitly select one to install" if num_providers > 1
- # Check if the package providing this virtual package is installed
- Chef::Log.info("#{@new_resource} is a virtual package, actually acting on package[#{providers.keys.first}]")
- installed = check_package_state(providers.keys.first)
- else
- Chef::Log.debug("#{@new_resource} candidate version is #{$1}")
+ def check_package_state(pkg)
+ is_virtual_package = false
+ installed = false
+ installed_version = nil
+ candidate_version = nil
+
+ shell_out!("apt-cache#{expand_options(default_release_options)} policy #{pkg}", {:timeout=>900}).stdout.each_line do |line|
+ case line
+ when /^\s{2}Installed: (.+)$/
+ installed_version = $1
+ if installed_version == '(none)'
+ Chef::Log.debug("#{@new_resource} current version is nil")
+ installed_version = nil
+ else
+ Chef::Log.debug("#{@new_resource} current version is #{installed_version}")
+ installed = true
+ end
+ when /^\s{2}Candidate: (.+)$/
+ candidate_version = $1
+ if candidate_version == '(none)'
+ # This may not be an appropriate assumption, but it shouldn't break anything that already worked -- btm
+ is_virtual_package = true
+ showpkg = shell_out!("apt-cache showpkg #{pkg}", {:timeout => 900}).stdout
+ providers = Hash.new
+ showpkg.rpartition(/Reverse Provides: ?#{$/}/)[2].each_line do |line|
+ provider, version = line.split
+ providers[provider] = version
end
+ # Check if the package providing this virtual package is installed
+ num_providers = providers.length
+ raise Chef::Exceptions::Package, "#{@new_resource.package_name} has no candidate in the apt-cache" if num_providers == 0
+ # apt will only install a virtual package if there is a single providing package
+ raise Chef::Exceptions::Package, "#{@new_resource.package_name} is a virtual package provided by #{num_providers} packages, you must explicitly select one to install" if num_providers > 1
+ # Check if the package providing this virtual package is installed
+ Chef::Log.info("#{@new_resource} is a virtual package, actually acting on package[#{providers.keys.first}]")
+ ret = check_package_state(providers.keys.first)
+ installed = ret[:installed]
+ installed_version = ret[:installed_version]
+ else
+ Chef::Log.debug("#{@new_resource} candidate version is #{$1}")
end
end
- if package.is_a?(Array)
- final_installed_version << installed_version
- final_candidate_version << candidate_version
- final_installed << installed
- final_virtual << virtual
- else
- final_installed_version = installed_version
- final_candidate_version = candidate_version
- final_installed = installed
- final_virtual = virtual
- end
end
- @candidate_version = final_candidate_version
- @current_resource.version(final_installed_version)
+
+ return {
+ installed_version: installed_version,
+ installed: installed,
+ candidate_version: candidate_version,
+ is_virtual_package: is_virtual_package,
+ }
+ end
+
+ def check_all_packages_state(package)
+ installed_version = {}
+ candidate_version = {}
+ installed = {}
[package].flatten.each do |pkg|
- @is_virtual_package[pkg] = final_virtual
+ ret = check_package_state(pkg)
+ is_virtual_package[pkg] = ret[:is_virtual_package]
+ installed[pkg] = ret[:installed]
+ installed_version[pkg] = ret[:installed_version]
+ candidate_version[pkg] = ret[:candidate_version]
end
- return final_installed.is_a?(Array) ? final_installed.any? : final_installed
+ if package.is_a?(Array)
+ @candidate_version = []
+ final_installed_version = []
+ [package].flatten.each do |pkg|
+ @candidate_version << candidate_version[pkg]
+ final_installed_version << installed_version[pkg]
+ end
+ @current_resource.version(final_installed_version)
+ else
+ @candidate_version = candidate_version[package]
+ @current_resource.version(installed_version[package])
+ end
end
def install_package(name, version)
- if name.is_a?(Array)
- index = 0
- package_name = name.zip(version).map do |x, y|
- namestr = nil
- if is_virtual_package[name]
- namestr = x
- else
- namestr = "#{x}=#{y}"
- end
- index += 1
- namestr
- end.join(' ')
- else
- package_name = "#{name}=#{version}"
- package_name = name if is_virtual_package[name]
- end
+ name_array = [ name ].flatten
+ version_array = [ version ].flatten
+ package_name = name_array.zip(version_array).map do |n, v|
+ is_virtual_package[n] ? n : "#{n}=#{v}"
+ end.join(' ')
run_noninteractive("apt-get -q -y#{expand_options(default_release_options)}#{expand_options(@new_resource.options)} install #{package_name}")
end
@@ -147,20 +149,12 @@ class Chef
end
def remove_package(name, version)
- if name.is_a?(Array)
- package_name = name.join(' ')
- else
- package_name = name
- end
+ package_name = [ name ].flatten.join(' ')
run_noninteractive("apt-get -q -y#{expand_options(@new_resource.options)} remove #{package_name}")
end
def purge_package(name, version)
- if name.is_a?(Array)
- package_name = name.join(' ')
- else
- package_name = "#{name}"
- end
+ package_name = [ name ].flatten.join(' ')
run_noninteractive("apt-get -q -y#{expand_options(@new_resource.options)} purge #{package_name}")
end
@@ -170,11 +164,7 @@ class Chef
end
def reconfig_package(name, version)
- if name.is_a?(Array)
- package_name = name.join(' ')
- else
- package_name = "#{name}"
- end
+ package_name = [ name ].flatten.join(' ')
Chef::Log.info("#{@new_resource} reconfiguring")
run_noninteractive("dpkg-reconfigure #{package_name}")
end