1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Package do
desc "Provides packaging support for Gentoo's portage system."
has_feature :versionable
commands :emerge => "/usr/bin/emerge", :eix => "/usr/bin/eix", :update_eix => "/usr/bin/update-eix"
confine :operatingsystem => :gentoo
defaultfor :operatingsystem => :gentoo
def self.instances
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]*) (.*)/
result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
search_format = "{installedversionsshort}<category> <name> [<installedversionsshort>] [<best>] <homepage> <description>{}"
begin
if !FileUtils.uptodate?("/var/cache/eix", %w(/usr/bin/eix /usr/portage/metadata/timestamp))
update_eix
end
search_output = eix "--nocolor", "--format", search_format
packages = []
search_output.each do |search_result|
match = result_format.match( search_result )
if match
package = {}
result_fields.zip(match.captures) { |field, value|
package[field] = value unless !value or value.empty?
}
package[:provider] = :portage
package[:ensure] = package[:ensure].split.last
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 = "=%s-%s" % [name, should]
end
emerge name
end
# The common package name format.
def package_name
@resource[:category] ? "%s/%s" % [@resource[:category], @resource[:name]] : @resource[:name]
end
def uninstall
emerge "--unmerge", package_name
end
def update
self.install
end
def query
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]*) (.*)/
result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
search_field = package_name.count('/') > 0 ? "--category-name" : "--name"
search_value = package_name
search_format = "<category> <name> [<installedversionsshort>] [<best>] <homepage> <description>"
begin
if !FileUtils.uptodate?("/var/cache/eix", %w(/usr/bin/eix /usr/portage/metadata/timestamp))
update_eix
end
search_output = eix "--nocolor", "--format", search_format, "--exact", search_field, search_value
packages = []
search_output.each do |search_result|
match = result_format.match( search_result )
if( match )
package = {}
result_fields.zip( match.captures ) { |field, value| package[field] = value unless !value or value.empty? }
if package[:ensure]
package[:ensure] = package[:ensure].split.last
else
package[:ensure] = :absent
end
packages << package
end
end
case packages.size
when 0
not_found_value = "%s/%s" % [@resource[:category] ? @resource[:category] : "<unspecified category>", @resource[:name]]
raise Puppet::Error.new("No package found with the specified name [#{not_found_value}]")
when 1
return packages[0]
else
raise Puppet::Error.new("More than one package with the specified name [#{search_value}], please use the category parameter to disambiguate")
end
rescue Puppet::ExecutionFailure => detail
raise Puppet::Error.new(detail)
end
end
def latest
return self.query[:version_available]
end
end
|