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
120
121
122
123
124
125
126
127
128
129
130
|
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
NVRFORMAT = "%{NAME}-%{VERSION}-%{RELEASE}"
VERSIONSTRING = "%{VERSION}-%{RELEASE}"
commands :rpm => "rpm"
if command('rpm')
confine :true => begin
rpm('-ql', 'rpm')
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 '%{NAME} #{VERSIONSTRING}\n'") { |process|
# our regex for matching dpkg output
regex = %r{^(\S+)\s+(\S+)}
fields = [:name, :ensure]
# 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
}
}
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
cmd = ["-q", @resource[:name], "--nosignature", "--nodigest", "--qf", "#{NVRFORMAT} #{VERSIONSTRING}\n"]
begin
output = rpm(*cmd)
rescue Puppet::ExecutionFailure
return nil
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
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", "#{VERSIONSTRING}", "-p", "#{@resource[:source]}"]
version = execfail(cmd, Puppet::Error)
return version
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
rpm "-e", nvr
end
def update
self.install
end
def nvr
query unless @nvr
@nvr
end
end
# $Id$
|