commit 572c8385d69d2edf934e002eba672a31049bc806 Author: Ben Roberts Date: Sat May 14 11:25:23 2011 +0100 Initial commit containing first attempt at entropy package provider diff --git a/lib/facter/has_entropy.rb b/lib/facter/has_entropy.rb new file mode 100644 index 0000000..d8073b3 --- /dev/null +++ b/lib/facter/has_entropy.rb @@ -0,0 +1,7 @@ +Facter.add(:has_entropy) do + confine :kernel => :linux + setcode do + FileTest.exists?("/usr/bin/equo") + end +end + diff --git a/lib/puppet/provider/package/entropy.rb b/lib/puppet/provider/package/entropy.rb new file mode 100644 index 0000000..9ee1efd --- /dev/null +++ b/lib/puppet/provider/package/entropy.rb @@ -0,0 +1,119 @@ +require 'puppet/provider/package' +require 'fileutils' + +Puppet::Type.type(:package).provide :entropy, :parent => Puppet::Provider::Package do + desc "Provides packaging support for Sabayon's entropy system." + + has_feature :versionable + + commands :equo => "/usr/bin/equo" + + #confine :operatingsystem => [ :gentoo, :sabayon ] + + defaultfor :has_entropy => true + + def self.instances + result_format = /^(\S+)\/(\S+)-([\.\d]+(?:_(?:alpha|beta|pre|rc|p)\d+)?(?:-r\d+)?)$/ + result_fields = [:category, :name, :version_available] + + begin + search_output = equo "query", "installed", "--nocolor", "--quiet" + + packages = [] + search_output.each do |search_result| + match = result_format.match(search_result) + + if match + package = {} + result_fields.zip(match.captures) do |field, value| + package[field] = value unless !value or value.empty? + end + package[:provider] = :entropy + + print package.to_yaml,"\n" if package[:name]=='htop' || package[:name]=='openssh' + + packages << new(package) + end + end + + return packages + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error.new(detail) + end + end + + def install + should = @resource.should(:ensure) + name = package_name + unless should == :present or should == :latest + # We must install a specific version + name = "=#{name}-#{should}" + end + equo "install", name + end + + # The common package name format. + def package_name + @resource[:category] ? "#{@resource[:category]}/#{@resource[:name]}" : @resource[:name] + end + + def uninstall + equo "remove", package_name + end + + def update + self.install + end + + def query + result_format = /@@\s*Package:\s*(\S+)\/(\S+)-[\.\d]+(?:_(?:alpha|beta|pre|rc|p)\d+)?(?:-r?\d+)?\s*branch:\s*\d+,\s*\[\S+\]\s*\n>>\s+Available:\s+version:\s+(\S+)\s+.*?\n>>\s+Installed:\s+version:\s+(Not installed|\S+)\s+/im + result_fields = [:category, :name, :version_available, :ensure] + + match = package_name.match(/^(?:(.*)\/)?(.*)$/) + search = {} + search[:category] = match.captures[0] + search[:name] = match.captures[1] + + begin + search_output = equo "search", "--nocolor", package_name + + packages = [] + search_output.scan(result_format) { |match| + + match_fields = Hash[result_fields.zip(match)] + + # skip packages that don't match exactly (equo search uses fuzzy matching) + if search[:name] == match_fields[:name] && ( ! search[:category] || search[:category].empty? || search[:category] == match_fields[:category]) + + package = {} + match_fields.each do |field, value| + package[field] = value unless !value or value.empty? + end + package[:ensure] = :absent if package[:ensure] == 'Not installed' + packages << package + end + } + + case packages.size + when 0 + not_found_value = "#{@resource[:category] ? @resource[:category] : ""}/#{@resource[:name]}" + raise Puppet::Error.new("No package found with the specified name [#{not_found_value}]") + else + packages.each do |candidate| + if (! search[:category] || search[:category].empty?) && search[:name] == candidate[:name] + return candidate + elsif search[:category] == candidate[:category] && search[:name] == candidate[:name] + return candidate + end + Puppet::Error.new("No exact matches for package '#{package_name}' in entropy db") + end + end + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error.new(detail) + end + end + + def latest + self.query[:version_available] + end +end