class Chef::Provider::Package::Dnf
Public Instance Methods
# File lib/chef/provider/package/dnf.rb, line 84 def candidate_version package_name_array.each_with_index.map do |pkg, i| available_version(i).version_with_arch end end
Chef::Provider::Package#define_resource_requirements
# File lib/chef/provider/package/dnf.rb, line 74 def define_resource_requirements requirements.assert(:install, :upgrade, :remove, :purge) do |a| a.assertion { !new_resource.source || ::File.exist?(new_resource.source) } a.failure_message Chef::Exceptions::Package, "Package #{new_resource.package_name} not found: #{new_resource.source}" a.whyrun "assuming #{new_resource.source} would have previously been created" end super end
# File lib/chef/provider/package/dnf.rb, line 90 def get_current_versions package_name_array.each_with_index.map do |pkg, i| installed_version(i).version_with_arch end end
# File lib/chef/provider/package/dnf.rb, line 96 def install_package(names, versions) if new_resource.source dnf(options, "-y", "install", new_resource.source) else resolved_names = names.each_with_index.map { |name, i| available_version(i).to_s unless name.nil? } dnf(options, "-y", "install", resolved_names) end flushcache end
# File lib/chef/provider/package/dnf.rb, line 64 def load_current_resource flushcache if new_resource.flush_cache[:before] @current_resource = Chef::Resource::DnfPackage.new(new_resource.name) current_resource.package_name(new_resource.package_name) current_resource.version(get_current_versions) current_resource end
Most of the magic in this class happens in the python helper script. The ruby side of this provider knows only enough to translate Chef-style new_resource name+package+version into a request to the python side. The python side is then responsible for knowing everything about RPMs and what is installed and what is available. The ruby side of this class should remain a lightweight translation layer to translate Chef
requests into RPC requests to python. This class knows nothing about how to compare RPM versions, and does not maintain any cached state of installed/available versions and should be kept that way.
# File lib/chef/provider/package/dnf.rb, line 60 def python_helper @python_helper ||= PythonHelper.instance end
# File lib/chef/provider/package/dnf.rb, line 109 def remove_package(names, versions) resolved_names = names.each_with_index.map { |name, i| installed_version(i).to_s unless name.nil? } dnf(options, "-y", "remove", resolved_names) flushcache end
dnf upgrade does not work on uninstalled packaged, while install will upgrade
Private Instance Methods
@return Array<Version>
# File lib/chef/provider/package/dnf.rb, line 139 def available_version(index) @available_version ||= [] @available_version[index] ||= if new_resource.source resolve_source_to_version_obj else python_helper.query(:whatavailable, package_name_array[index], safe_version_array[index], safe_arch_array[index]) end @available_version[index] end
# File lib/chef/provider/package/dnf.rb, line 169 def dnf(*args) shell_out!("dnf", *args) end
cache flushing is accomplished by simply restarting the python helper. this produces a roughly 15% hit to the runtime of installing/removing/upgrading packages. correctly using multipackage array installs (and the multipackage cookbook) can produce 600% improvements in runtime.
# File lib/chef/provider/package/dnf.rb, line 165 def flushcache python_helper.restart end
@return [Array<Version>]
# File lib/chef/provider/package/dnf.rb, line 152 def installed_version(index) @installed_version ||= [] @installed_version[index] ||= if new_resource.source python_helper.query(:whatinstalled, available_version(index).name, safe_version_array[index], safe_arch_array[index]) else python_helper.query(:whatinstalled, package_name_array[index], safe_version_array[index], safe_arch_array[index]) end @installed_version[index] end
# File lib/chef/provider/package/dnf.rb, line 123 def resolve_source_to_version_obj shell_out!("rpm -qp --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n' #{new_resource.source}").stdout.each_line do |line| # this is another case of committing the sin of doing some lightweight mangling of RPM versions in ruby -- but the output of the rpm command # does not match what the dnf library accepts. case line when /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/ return Version.new($1, "#{$2 == '(none)' ? '0' : $2}:#{$3}-#{$4}", $5) end end end
# File lib/chef/provider/package/dnf.rb, line 183 def safe_arch_array if new_resource.arch.is_a?(Array) new_resource.arch elsif new_resource.arch.nil? package_name_array.map { nil } else [ new_resource.arch ] end end
# File lib/chef/provider/package/dnf.rb, line 173 def safe_version_array if new_resource.version.is_a?(Array) new_resource.version elsif new_resource.version.nil? package_name_array.map { nil } else [ new_resource.version ] end end
# File lib/chef/provider/package/dnf.rb, line 134 def version_compare(v1, v2) python_helper.compare_versions(v1, v2) end