diff --git a/lib/puppet/provider/package/rpm.rb b/lib/puppet/provider/package/rpm.rb index 4af299283..98ca1efa6 100755 --- a/lib/puppet/provider/package/rpm.rb +++ b/lib/puppet/provider/package/rpm.rb @@ -1,116 +1,124 @@ 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." # 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 = [] # list out all of the packages begin execpipe("#{command(:rpm)} -qa --nosignature --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 return 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 unless @property_hash[:epoch] cmd = ["-q", @resource[:name], "--nosignature", "--nodigest", "--qf", "#{NEVRAFORMAT}\n"] begin output = rpm(*cmd) rescue Puppet::ExecutionFailure return nil end # FIXME: We could actually be getting back multiple packages # for multilib @property_hash.update(self.class.nevra_to_hash(output)) end return @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 = nevra_to_hash(execfail(cmd, Puppet::Error)) return 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" if @property_hash[:ensure] and @property_hash[:ensure] != :absent flag = "-U" end 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 nvr - query unless @nvr - @nvr - 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]}" return hash end end