class Chef::Provider::Package::Dpkg

Constants

DPKG_INSTALLED
DPKG_REMOVED
DPKG_VERSION

Public Instance Methods

check_resource_semantics!() click to toggle source

Override the superclass check. Multiple sources are required here.

# File lib/chef/provider/package/dpkg.rb, line 97
def check_resource_semantics!; end
define_resource_requirements() click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 37
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
install_package(name, version) click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 76
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
load_current_resource() click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 52
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
purge_package(name, version) click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 87
def purge_package(name, version)
  logger.info("#{new_resource} purging packages(s): #{name.join(' ')}")
  run_noninteractive("dpkg", "-P", *options, *name)
end
remove_package(name, version) click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 82
def remove_package(name, version)
  logger.info("#{new_resource} removing package(s): #{name.join(' ')}")
  run_noninteractive("dpkg", "-r", *options, *name)
end
upgrade_package(name, version) click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 92
def upgrade_package(name, version)
  install_package(name, version)
end

Private Instance Methods

current_package_name_array() click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 159
def current_package_name_array
  [ current_resource.package_name ].flatten
end
get_candidate_version() click to toggle source

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 205
def get_candidate_version
  package_name_array.map { |name| name_candidate_version[name] }
end
get_current_version_from(array) click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 138
def get_current_version_from(array)
  array.map do |name|
    read_current_version_of_package(name)
  end
end
get_package_name() click to toggle source

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 212
def get_package_name
  package_name_array.map { |name| name_package_name[name] }
end
installing?() click to toggle source

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 220
def installing?
  [:install, :upgrade].include?(action)
end
missing_sources() click to toggle source

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 155
def missing_sources
  resolved_source_array.select { |s| s.nil? || !::File.exist?(s) }
end
name_candidate_version() click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 188
def name_candidate_version
  @name_candidate_version ||=
    begin
      Hash[name_pkginfo.map { |k, v| [k, v ? v.split("\t")[1].strip : nil] }]
    end
end
name_package_name() click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 195
def name_package_name
  @name_package_name ||=
    begin
      Hash[name_pkginfo.map { |k, v| [k, v ? v.split("\t")[0] : nil] }]
    end
end
name_pkginfo() click to toggle source

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 176
def name_pkginfo
  @name_pkginfo ||=
    begin
      pkginfos = resolved_source_array.map do |src|
        logger.trace("#{new_resource} checking #{src} dpkg status")
        status = shell_out!("dpkg-deb", "-W", src)
        status.stdout
      end
      Hash[*package_name_array.zip(pkginfos).flatten]
    end
end
name_sources() click to toggle source

Helper to construct Hash of names-to-sources.

@return [Hash] Mapping of package names to sources

# File lib/chef/provider/package/dpkg.rb, line 166
def name_sources
  @name_sources =
    begin
      Hash[*package_name_array.zip(resolved_source_array).flatten]
    end
end
read_current_version_of_package(package_name) click to toggle source
# File lib/chef/provider/package/dpkg.rb, line 117
def read_current_version_of_package(package_name)
  logger.trace("#{new_resource} checking install state of #{package_name}")
  status = shell_out!("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
source_files_exist?() click to toggle source

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 148
def source_files_exist?
  resolved_source_array.all? { |s| s && ::File.exist?(s) }
end
version_compare(v1, v2) click to toggle source

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 107
def version_compare(v1, v2)
  if !shell_out("dpkg", "--compare-versions", v1.to_s, "gt", v2.to_s).error?
    1
  elsif !shell_out("dpkg", "--compare-versions", v1.to_s, "eq", v2.to_s).error?
    0
  else
    -1
  end
end