1
Puppet::Type.type(:package).provide :portage do
1
require 'puppet/provider/package'
3
Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Package do
2
4
desc "Provides packaging support for Gentoo's portage system."
4
commands :emerge => "/usr/bin/emerge", :eix => "/usr/bin/eix"
6
has_feature :versionable
8
commands :emerge => "/usr/bin/emerge", :eix => "/usr/bin/eix", :update_eix => "/usr/bin/update-eix"
6
10
defaultfor :operatingsystem => :gentoo
9
search_format = /(\S+) (\S+) \[(.*)\] \[(\S*)\] ([\S]*) (.*)/
10
result_fields = [:category, :name, :ensure, :version_available,
11
:vendor, :description]
12
command = "#{command(:eix)} --format \"{installedversions}<category> <name> [<installedversions>] [<best>] <homepage> <description>{}\""
13
result_format = /(\S+) (\S+) \[(?:([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\([^\)]+\))?(?:\[([^\]]+)\])?[ ]*)*\] \[(?:(?:\{M\})?(?:\([~*]+\))?([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\(([^\)]+)\))?(?:![mf])*(?:\[([^\]]+)\])?)?\] ([\S]*) (.*)/
14
result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
16
search_format = "{installedversionsshort}<category> <name> [<installedversionsshort>] [<best>] <homepage> <description>{}"
15
search_output = execute( command )
19
if !FileUtils.uptodate?("/var/cache/eix", %w(/usr/bin/eix /usr/portage/metadata/timestamp))
22
search_output = eix "--nocolor", "--format", search_format
18
25
search_output.each do |search_result|
19
match = search_format.match( search_result )
26
match = result_format.match( search_result )
23
result_fields.zip( match.captures ) { |field, value| package[field] = value unless value.empty? }
30
result_fields.zip(match.captures) { |field, value|
31
package[field] = value unless !value or value.empty?
24
33
package[:provider] = :portage
25
34
package[:ensure] = package[:ensure].split.last
27
packages.push( Puppet.type(:package).installedpkg(package) )
36
packages << new(package)
32
41
rescue Puppet::ExecutionFailure => detail
33
raise Puppet::PackageError.new(detail)
42
raise Puppet::Error.new(detail)
38
if @model.should( :ensure ) == :present || @model.should( :ensure ) == :latest
39
package_name = "#{@model[:category]}/#{@model[:name]}"
47
should = @resource.should(:ensure)
49
unless should == :present or should == :latest
41
50
# We must install a specific version
42
package_name = "=#{@model[:category]}/#{@model[:name]}-#{@model.should( :ensure )}"
51
name = "=%s-%s" % [name, should]
44
command = "#{command(:emerge)} #{package_name}"
46
output = execute( command )
56
# The common package name format.
58
@resource[:category] ? "%s/%s" % [@resource[:category], @resource[:name]] : @resource[:name]
50
package_name = "#{@model[:category]}/#{@model[:name]}"
51
command ="#{command(:emerge)} --unmerge #{package_name}"
53
output = execute( command )
54
rescue Puppet::ExecutionFailure => detail
55
raise Puppet::PackageError.new(detail)
62
emerge "--unmerge", package_name
64
search_format = /(\S+) (\S+) \[(.*)\] \[(\S*)\] ([\S]*) (.*)/
65
result_fields = [:category, :name, :ensure, :version_available, :vendor, :description]
70
result_format = /(\S+) (\S+) \[(?:([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\([^\)]+\))?(?:\[([^\]]+)\])?[ ]*)*\] \[(?:(?:\{M\})?(?:\([~*]+\))?([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\(([^\)]+)\))?(?:![mf])*(?:\[([^\]]+)\])?)?\] ([\S]*) (.*)/
71
result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
67
search_field = @model[:name].include?( '/' ) ? "--category-name" : "--name"
68
command = "#{command(:eix)} --format \"<category> <name> [<installedversions>] [<best>] <homepage> <description>\" --exact #{search_field} #{@model[:name]}"
73
search_field = @resource[:category] ? "--category-name" : "--name"
74
search_value = package_name
75
search_format = "<category> <name> [<installedversionsshort>] [<best>] <homepage> <description>"
71
search_output = execute( command )
78
if !FileUtils.uptodate?("/var/cache/eix", %w(/usr/bin/eix /usr/portage/metadata/timestamp))
81
search_output = eix "--nocolor", "--format", search_format, "--exact", search_field, search_value
74
84
search_output.each do |search_result|
75
match = search_format.match( search_result )
85
match = result_format.match( search_result )
79
result_fields.zip( match.captures ) { |field, value| package[field] = value unless value.empty? }
89
result_fields.zip( match.captures ) { |field, value| package[field] = value unless !value or value.empty? }
80
90
if package[:ensure]
81
91
package[:ensure] = package[:ensure].split.last
91
raise Puppet::PackageError.new( "No package found with the specified name [#{@model[:name]}]" )
101
not_found_value = "%s/%s" % [@resource[:category] ? @resource[:category] : "<unspecified category>", @resource[:name]]
102
raise Puppet::Error.new("No package found with the specified name [#{not_found_value}]")
93
104
return packages[0]
95
raise Puppet::PackageError.new( "More than one package with the specified name [#{@model[:name]}], please use category/name to disambiguate" )
106
raise Puppet::Error.new("More than one package with the specified name [#{search_value}], please use the category parameter to disambiguate")
97
108
rescue Puppet::ExecutionFailure => detail
98
raise Puppet::PackageError.new(detail)
109
raise Puppet::Error.new(detail)
103
114
return self.query[:version_available]
111
# $Id: portage.rb 1811 2006-10-18 14:39:33Z luke $