diff --git a/lib/puppet/provider/package/rpm.rb b/lib/puppet/provider/package/rpm.rb index 72dc260a4..ec6121743 100755 --- a/lib/puppet/provider/package/rpm.rb +++ b/lib/puppet/provider/package/rpm.rb @@ -1,132 +1,133 @@ require 'puppet/provider/package' # RPM packaging. Should work anywhere that has rpm installed. Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Provider::Package do desc "RPM packaging support; should work anywhere with a working `rpm` binary." has_feature :versionable # The query format by which we identify installed packages NEVRAFORMAT = "%{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION} %{RELEASE} %{ARCH}" NEVRA_FIELDS = [:name, :epoch, :version, :release, :arch] commands :rpm => "rpm" if command('rpm') confine :true => begin rpm('--version') rescue Puppet::ExecutionFailure false else true end end def self.instances packages = [] # rpm < 4.1 don't support --nosignature output = rpm "--version" sig = "--nosignature" if output =~ /RPM version (([123].*)|(4\.0.*))/ sig = "" end # list out all of the packages begin execpipe("#{command(:rpm)} -qa #{sig} --nodigest --qf '#{NEVRAFORMAT}\n'") { |process| # now turn each returned line into a package object process.each { |line| hash = nevra_to_hash(line) packages << new(hash) } } rescue Puppet::ExecutionFailure raise Puppet::Error, "Failed to list packages" end packages end # Find the fully versioned package name and the version alone. Returns # a hash with entries :instance => fully versioned package name, and # :ensure => version-release def query #NOTE: Prior to a fix for issue 1243, this method potentially returned a cached value #IF YOU CALL THIS METHOD, IT WILL CALL RPM #Use get(:property) to check if cached values are available cmd = ["-q", @resource[:name], "--nosignature", "--nodigest", "--qf", "#{NEVRAFORMAT}\n"] begin output = rpm(*cmd) rescue Puppet::ExecutionFailure - return nil + # rpm exits 1 if the package is not found. + return {:ensure => :purged, :status => 'missing', :name => @resource[:name], :error => 'ok'} end # FIXME: We could actually be getting back multiple packages # for multilib @property_hash.update(self.class.nevra_to_hash(output)) @property_hash.dup end # Here we just retrieve the version from the file specified in the source. def latest unless source = @resource[:source] @resource.fail "RPMs must specify a package source" end cmd = [command(:rpm), "-q", "--qf", "#{NEVRAFORMAT}\n", "-p", "#{@resource[:source]}"] h = self.class.nevra_to_hash(execfail(cmd, Puppet::Error)) h[:ensure] end def install source = nil unless source = @resource[:source] @resource.fail "RPMs must specify a package source" end # RPM gets pissy if you try to install an already # installed package if @resource.should(:ensure) == @property_hash[:ensure] or @resource.should(:ensure) == :latest && @property_hash[:ensure] == latest return end flag = "-i" flag = "-U" if @property_hash[:ensure] and @property_hash[:ensure] != :absent rpm flag, "--oldpackage", source end def uninstall query unless get(:arch) nvr = "#{get(:name)}-#{get(:version)}-#{get(:release)}" arch = ".#{get(:arch)}" # If they specified an arch in the manifest, erase that Otherwise, # erase the arch we got back from the query. If multiple arches are # installed and only the package name is specified (without the # arch), this will uninstall all of them on successive runs of the # client, one after the other if @resource[:name][-arch.size, arch.size] == arch nvr += arch else nvr += ".#{get(:arch)}" end rpm "-e", nvr end def update self.install end def self.nevra_to_hash(line) line.chomp! hash = {} NEVRA_FIELDS.zip(line.split) { |f, v| hash[f] = v } hash[:provider] = self.name hash[:ensure] = "#{hash[:version]}-#{hash[:release]}" hash end end