class Chef::Provider::Package::Dpkg
Constants
- DPKG_INSTALLED
- DPKG_REMOVED
- DPKG_VERSION
Public Instance Methods
Override the superclass check. Multiple sources are required here.
# File lib/chef/provider/package/dpkg.rb, line 105 def check_resource_semantics!; end
# File lib/chef/provider/package/dpkg.rb, line 35 def define_resource_requirements super requirements.assert(:install, :upgrade) do |a| a.assertion { !resolved_source_array.compact.empty? } a.failure_message Chef::Exceptions::Package, "#{new_resource} the source property is required for action :install or :upgrade" end requirements.assert(:install, :upgrade) do |a| a.assertion { source_files_exist? } a.failure_message Chef::Exceptions::Package, "#{new_resource} source file(s) do not exist: #{missing_sources}" a.whyrun "Assuming they would have been previously created." end end
# File lib/chef/provider/package/dpkg.rb, line 74 def install_package(name, version) sources = name.map { |n| name_sources[n] } logger.info("#{new_resource} installing package(s): #{name.join(' ')}") run_noninteractive("dpkg", "-i", *options, *sources) end
# File lib/chef/provider/package/dpkg.rb, line 50 def load_current_resource @current_resource = Chef::Resource::Package.new(new_resource.name) current_resource.package_name(new_resource.package_name) if source_files_exist? @candidate_version = get_candidate_version current_resource.package_name(get_package_name) # if the source file exists then our package_name is right current_resource.version(get_current_version_from(current_package_name_array)) elsif !installing? # we can't do this if we're installing with no source, because our package_name # is probably not right. # # if we're removing or purging we don't use source, and our package_name must # be right so we can do this. # # we don't error here on the dpkg command since we'll handle the exception or # the why-run message in define_resource_requirements. current_resource.version(get_current_version_from(current_package_name_array)) end current_resource end
# File lib/chef/provider/package/dpkg.rb, line 94 def preseed_package(preseed_file) logger.info("#{new_resource} pre-seeding package installation instructions") run_noninteractive("debconf-set-selections", *preseed_file) end
# File lib/chef/provider/package/dpkg.rb, line 85 def purge_package(name, version) logger.info("#{new_resource} purging packages(s): #{name.join(' ')}") run_noninteractive("dpkg", "-P", *options, *name) end
# File lib/chef/provider/package/dpkg.rb, line 99 def reconfig_package(name, version) logger.info("#{new_resource} reconfiguring") run_noninteractive("dpkg-reconfigure", *name) end
# File lib/chef/provider/package/dpkg.rb, line 80 def remove_package(name, version) logger.info("#{new_resource} removing package(s): #{name.join(' ')}") run_noninteractive("dpkg", "-r", *options, *name) end
# File lib/chef/provider/package/dpkg.rb, line 90 def upgrade_package(name, version) install_package(name, version) end
Private Instance Methods
# File lib/chef/provider/package/dpkg.rb, line 173 def current_package_name_array [ current_resource.package_name ].flatten end
Return candidate version array from pkg-deb -W against the source file(s).
@return [Array] Array of candidate versions read from the source files
# File lib/chef/provider/package/dpkg.rb, line 219 def get_candidate_version package_name_array.map { |name| name_candidate_version[name] } end
# File lib/chef/provider/package/dpkg.rb, line 146 def get_current_version_from(array) array.map do |name| read_current_version_of_package(name) end end
Return package names from the candidate source file(s).
@return [Array] Array of actual package names read from the source files
# File lib/chef/provider/package/dpkg.rb, line 226 def get_package_name package_name_array.map { |name| name_package_name[name] } end
Since upgrade just calls install, this is a helper to determine if our action means that we'll be calling install_package.
@return [Boolean] true if we're doing :install or :upgrade
# File lib/chef/provider/package/dpkg.rb, line 234 def installing? [:install, :upgrade].include?(action) end
Helper to return all the nanes of the missing sources for error messages.
@return [Array<String>] Array of missing sources
# File lib/chef/provider/package/dpkg.rb, line 169 def missing_sources resolved_source_array.select { |s| s.nil? || !::File.exist?(s) } end
# File lib/chef/provider/package/dpkg.rb, line 202 def name_candidate_version @name_candidate_version ||= begin Hash[name_pkginfo.map { |k, v| [k, v ? v.split("\t")[1].strip : nil] }] end end
# File lib/chef/provider/package/dpkg.rb, line 209 def name_package_name @name_package_name ||= begin Hash[name_pkginfo.map { |k, v| [k, v ? v.split("\t")[0] : nil] }] end end
Helper to construct Hash of names-to-package-information.
@return [Hash] Mapping of package names to package information
# File lib/chef/provider/package/dpkg.rb, line 190 def name_pkginfo @name_pkginfo ||= begin pkginfos = resolved_source_array.map do |src| logger.trace("#{new_resource} checking #{src} dpkg status") status = shell_out_compact_timeout!("dpkg-deb", "-W", src) status.stdout end Hash[*package_name_array.zip(pkginfos).flatten] end end
Helper to construct Hash of names-to-sources.
@return [Hash] Mapping of package names to sources
# File lib/chef/provider/package/dpkg.rb, line 180 def name_sources @name_sources = begin Hash[*package_name_array.zip(resolved_source_array).flatten] end end
# File lib/chef/provider/package/dpkg.rb, line 125 def read_current_version_of_package(package_name) logger.trace("#{new_resource} checking install state of #{package_name}") status = shell_out_compact_timeout!("dpkg", "-s", package_name, returns: [0, 1]) package_installed = false status.stdout.each_line do |line| case line when DPKG_REMOVED # if we are 'purging' then we consider 'removed' to be 'installed' package_installed = true if action == :purge when DPKG_INSTALLED package_installed = true when DPKG_VERSION if package_installed logger.trace("#{new_resource} current version is #{$1}") return $1 end end end nil end
Runs command via shell_out_with_timeout with magic environment to disable interactive prompts.
# File lib/chef/provider/package/dpkg.rb, line 154 def run_noninteractive(*command) shell_out_compact_timeout!(*command, env: { "DEBIAN_FRONTEND" => "noninteractive" }) end
Returns true if all sources exist. Returns false if any do not, or if no sources were specified.
@return [Boolean] True if all sources exist
# File lib/chef/provider/package/dpkg.rb, line 162 def source_files_exist? resolved_source_array.all? { |s| s && ::File.exist?(s) } end
compare 2 versions to each other to see which is newer. this differs from the standard package method because we need to be able to parse debian version strings which contain tildes which Gem cannot properly parse
@return [Integer] 1 if v1 > v2. 0 if they're equal. -1 if v1 < v2
# File lib/chef/provider/package/dpkg.rb, line 115 def version_compare(v1, v2) if !shell_out_compact_timeout("dpkg", "--compare-versions", v1.to_s, "gt", v2.to_s).error? 1 elsif !shell_out_compact_timeout("dpkg", "--compare-versions", v1.to_s, "eq", v2.to_s).error? 0 else -1 end end