summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/provider')
-rwxr-xr-xlib/puppet/provider/package/rpm.rb75
-rwxr-xr-xlib/puppet/provider/package/yum.rb58
-rw-r--r--lib/puppet/provider/package/yumhelper.py37
3 files changed, 113 insertions, 57 deletions
diff --git a/lib/puppet/provider/package/rpm.rb b/lib/puppet/provider/package/rpm.rb
index a31e4edf6..6e0ba5070 100755
--- a/lib/puppet/provider/package/rpm.rb
+++ b/lib/puppet/provider/package/rpm.rb
@@ -5,15 +5,14 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr
binary."
# The query format by which we identify installed packages
- NVRFORMAT = "%{NAME}-%{VERSION}-%{RELEASE}"
-
- VERSIONSTRING = "%{VERSION}-%{RELEASE}"
+ 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('-ql', 'rpm')
+ rpm('--version')
rescue Puppet::ExecutionFailure
false
else
@@ -26,23 +25,11 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr
# list out all of the packages
begin
- execpipe("#{command(:rpm)} -qa --nosignature --nodigest --qf '%{NAME} #{VERSIONSTRING}\n'") { |process|
- # our regex for matching dpkg output
- regex = %r{^(\S+)\s+(\S+)}
- fields = [:name, :ensure]
-
+ execpipe("#{command(:rpm)} -qa --nosignature --nodigest --qf '#{NEVRAFORMAT}\n'") { |process|
# now turn each returned line into a package object
process.each { |line|
- if match = regex.match(line)
- hash = {}
- fields.zip(match.captures) { |field,value|
- hash[field] = value
- }
- hash[:provider] = self.name
- packages << new(hash)
- else
- raise "failed to match rpm line %s" % line
- end
+ hash = nevra_to_hash(line)
+ packages << new(hash)
}
}
rescue Puppet::ExecutionFailure
@@ -56,30 +43,21 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr
# a hash with entries :instance => fully versioned package name, and
# :ensure => version-release
def query
- cmd = ["-q", @resource[:name], "--nosignature", "--nodigest", "--qf", "#{NVRFORMAT} #{VERSIONSTRING}\n"]
-
- begin
- output = rpm(*cmd)
- rescue Puppet::ExecutionFailure
- return nil
+ 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
- regex = %r{^(\S+)\s+(\S+)}
- fields = [:instance, :ensure]
- attrs = {}
- if match = regex.match(output)
- fields.zip(match.captures) { |field,value|
- attrs[field] = value
- }
- else
- raise Puppet::DevError,
- "Failed to match rpm output '%s'" %
- output
- end
-
- @nvr = attrs[:instance]
-
- return attrs
+ return @property_hash.dup
end
# Here we just retrieve the version from the file specified in the source.
@@ -88,9 +66,9 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr
@resource.fail "RPMs must specify a package source"
end
- cmd = [command(:rpm), "-q", "--qf", "#{VERSIONSTRING}", "-p", "#{@resource[:source]}"]
- version = execfail(cmd, Puppet::Error)
- return version
+ cmd = [command(:rpm), "-q", "--qf", "#{NEVRAFORMAT}\n", "-p", "#{@resource[:source]}"]
+ h = nevra_to_hash(execfail(cmd, Puppet::Error))
+ return h[:ensure]
end
def install
@@ -125,6 +103,15 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr
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
# $Id$
diff --git a/lib/puppet/provider/package/yum.rb b/lib/puppet/provider/package/yum.rb
index 13863ee55..a9427061c 100755
--- a/lib/puppet/provider/package/yum.rb
+++ b/lib/puppet/provider/package/yum.rb
@@ -3,11 +3,17 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
has_feature :versionable
- commands :yum => "yum", :rpm => "rpm"
+ commands :yum => "yum", :rpm => "rpm", :python => "python"
+
+ YUMHELPER = File::join(File::dirname(__FILE__), "yumhelper.py")
+
+ class << self
+ attr_reader :updates
+ end
if command('rpm')
confine :true => begin
- rpm('-ql', 'rpm')
+ rpm('--version')
rescue Puppet::ExecutionFailure
false
else
@@ -17,8 +23,26 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
defaultfor :operatingsystem => [:fedora, :centos, :redhat]
- def install
+ def self.prefetch(packages)
+ @updates = {}
+ if Process.euid != 0
+ raise Puppet::Error, "The yum provider can only be used as root"
+ end
+ super
+ python(YUMHELPER).each_line do |l|
+ l.chomp!
+ next if l.empty?
+ if l[0,4] == "_pkg"
+ hash = nevra_to_hash(l[5..-1])
+ [hash[:name], "#{hash[:name]}.#{hash[:arch]}"].each do |n|
+ @updates[n] ||= []
+ @updates[n] << hash
+ end
+ end
+ end
+ end
+ def install
should = @resource.should(:ensure)
self.debug "Ensuring => #{should}"
wanted = @resource[:name]
@@ -27,6 +51,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
case should
when true, false, Symbol
# pass
+ should = nil
else
# Add the package version
wanted += "-%s" % should
@@ -34,26 +59,33 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
output = yum "-d", "0", "-e", "0", "-y", :install, wanted
- unless self.query
- raise Puppet::Error.new(
- "Could not find package %s" % self.name
- )
+ is = self.query
+ unless is
+ raise Puppet::Error, "Could not find package %s" % self.name
+ end
+
+ # FIXME: Should we raise an exception even if should == :latest
+ # and yum updated us to a version other than @param_hash[:ensure] ?
+ if should && should != is[:ensure]
+ raise Puppet::Error, "Failed to update to version #{should}, got version #{is[:ensure]} instead"
end
end
# What's the latest package version available?
def latest
- output = yum "-d", "0", "-e", "0", :list, :available, @resource[:name]
-
- if output =~ /^#{Regexp.escape(@resource[:name])}\S+\s+(\S+)\s/
- return $1
+ upd = self.class.updates[@resource[:name]]
+ unless upd.nil?
+ # FIXME: there could be more than one update for a package
+ # because of multiarch
+ upd = upd[0]
+ return "#{upd[:version]}-#{upd[:release]}"
else
# Yum didn't find updates, pretend the current
# version is the latest
- unless properties[:ensure] != :absent
+ if properties[:ensure] == :absent
raise Puppet::DevError, "Tried to get latest on a missing package"
end
- return @property_hash[:ensure]
+ return properties[:ensure]
end
end
diff --git a/lib/puppet/provider/package/yumhelper.py b/lib/puppet/provider/package/yumhelper.py
new file mode 100644
index 000000000..1142401b9
--- /dev/null
+++ b/lib/puppet/provider/package/yumhelper.py
@@ -0,0 +1,37 @@
+# Python helper script to query for the packages that have
+# pending updates. Called by the yum package provider
+#
+# (C) 2007 Red Hat Inc.
+# David Lutterkort <dlutter @redhat.com>
+
+import yum
+import sys
+
+OVERRIDE_OPTS = {
+ 'debuglevel': 0,
+ 'errorlevel': 0,
+ 'logfile': '/dev/null'
+}
+
+def pkg_lists():
+ my = yum.YumBase()
+ my.doConfigSetup()
+
+ for k in OVERRIDE_OPTS.keys():
+ if hasattr(my.conf, k):
+ setattr(my.conf, k, OVERRIDE_OPTS[k])
+ else:
+ my.conf.setConfigOption(k, OVERRIDE_OPTS[k])
+
+ my.doTsSetup()
+ my.doRpmDBSetup()
+ return my.doPackageLists('updates')
+
+try:
+ ypl = pkg_lists()
+except IOError, e:
+ print "_err IOError %d %s" % (e.errno, e)
+ sys.exit(1)
+
+for pkg in ypl.updates:
+ print "_pkg %s %s %s %s %s" % (pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch)