Skip to content

Commit c35d07b

Browse files
author
luke
committed
Significantly reworked the type => provider interface with respect to
listing existing provider instances. The class method on both class heirarchies has been renamed to 'instances', to start. Providers are now expected to return provider instances, instead of creating resources, and the resource's 'instances' method is expected to find the matching resource, if any, and set the resource's provider appropriately. This *significantly* reduces the reliance on effectively global state (resource references in the resource classes). This global state will go away soon. Along with this change, the 'prefetch' class method on providers now accepts the list of resources for prefetching. This again reduces reliance on global state, and makes the execution path much easier to follow. git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2551 980ebf18-57e1-0310-9a29-db15c13687c0
1 parent a7b057d commit c35d07b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+416
-310
lines changed

CHANGELOG

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
Significantly reworked the type => provider interface with respect to
2+
listing existing provider instances. The class method on both
3+
class heirarchies has been renamed to 'instances', to start. Providers
4+
are now expected to return provider instances, instead of creating
5+
resources, and the resource's 'instances' method is expected to
6+
find the matching resource, if any, and set the resource's
7+
provider appropriately. This *significantly* reduces the reliance on
8+
effectively global state (resource references in the resource classes).
9+
This global state will go away soon.
10+
11+
Along with this change, the 'prefetch' class method on providers now
12+
accepts the list of resources for prefetching. This again reduces
13+
reliance on global state, and makes the execution path much easier
14+
to follow.
15+
116
Fixed #532 -- reparsing config files now longer throws an exception.
217

318
Added some warnings and logs to the service type so

lib/puppet/metatype/instances.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,24 @@ def self.hash2trans(hash)
248248
return trans
249249
end
250250

251+
# Retrieve all known instances. Either requires providers or must be overridden.
252+
def self.instances
253+
unless defined?(@providers) and ! @providers.empty?
254+
raise Puppet::DevError, "%s has no providers and has not overridden 'instances'" % self.name
255+
end
256+
257+
# Put the default provider first, then the rest of the suitable providers.
258+
sources = []
259+
[defaultprovider, suitableprovider].flatten.uniq.collect do |provider|
260+
next if sources.include?(provider.source)
261+
262+
sources << provider.source
263+
provider.instances.collect do |instance|
264+
create(:name => instance.name, :provider => instance, :check => :all)
265+
end
266+
end.flatten.compact
267+
end
268+
251269
# Create the path for logging and such.
252270
def pathbuilder
253271
if defined? @parent and @parent

lib/puppet/metatype/providers.rb

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -86,26 +86,6 @@ def self.hash2obj(hash)
8686
return obj
8787
end
8888

89-
# Create a list method that just calls our providers.
90-
def self.mkprovider_list
91-
unless respond_to?(:list)
92-
meta_def(:list) do
93-
suitableprovider.find_all { |p| p.respond_to?(:list) }.collect { |prov|
94-
prov.list.each { |h| h[:provider] = prov.name }
95-
}.flatten.collect do |hash|
96-
if hash.is_a?(Hash)
97-
hash2obj(hash)
98-
elsif hash.is_a?(self)
99-
hash
100-
else
101-
raise Puppet::DevError, "Provider %s returned object of type %s in list" %
102-
[prov.name, hash.class]
103-
end
104-
end
105-
end
106-
end
107-
end
108-
10989
# Retrieve a provider by name.
11090
def self.provider(name)
11191
name = Puppet::Util.symbolize(name)
@@ -172,7 +152,6 @@ def self.provide(name, options = {}, &block)
172152
def self.providify
173153
return if @paramhash.has_key? :provider
174154

175-
mkprovider_list()
176155
newparam(:provider) do
177156
desc "The specific backend for #{self.name.to_s} to use. You will
178157
seldom need to specify this -- Puppet will usually discover the
@@ -197,17 +176,21 @@ def self.doc
197176
@resource.class.defaultprovider.name
198177
}
199178

200-
validate do |value|
201-
value = value[0] if value.is_a? Array
202-
if provider = @resource.class.provider(value)
179+
validate do |provider_class|
180+
provider_class = provider_class[0] if provider_class.is_a? Array
181+
if provider_class.is_a?(Puppet::Provider)
182+
provider_class = provider_class.class.name
183+
end
184+
185+
if provider = @resource.class.provider(provider_class)
203186
unless provider.suitable?
204187
raise ArgumentError,
205188
"Provider '%s' is not functional on this platform" %
206-
[value]
189+
[provider_class]
207190
end
208191
else
209192
raise ArgumentError, "Invalid %s provider '%s'" %
210-
[@resource.class.name, value]
193+
[@resource.class.name, provider_class]
211194
end
212195
end
213196

@@ -244,10 +227,13 @@ def self.suitableprovider
244227
end
245228

246229
def provider=(name)
247-
if klass = self.class.provider(name)
230+
if name.is_a?(Puppet::Provider)
231+
@provider = name
232+
@provider.resource = self
233+
elsif klass = self.class.provider(name)
248234
@provider = klass.new(self)
249235
else
250-
raise UnknownProviderError, "Could not find %s provider of %s" %
236+
raise ArgumentError, "Could not find %s provider of %s" %
251237
[name, self.class.name]
252238
end
253239
end

lib/puppet/network/handler/resource.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def list(type, ignore = [], base = nil, format = "yaml", client = nil, clientip
145145
bucket = Puppet::TransBucket.new
146146
bucket.type = typeklass.name
147147

148-
typeklass.list.each do |obj|
148+
typeklass.instances.each do |obj|
149149
next if ignore.include? obj.name
150150

151151
#object = Puppet::TransObject.new(obj.name, typeklass.name)

lib/puppet/provider.rb

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ def self.initvars
109109
end
110110
end
111111

112+
# The method for returning a list of provider instances. Note that it returns providers, preferably with values already
113+
# filled in, not resources.
114+
def self.instances
115+
raise Puppet::DevError, "Provider %s has not defined the 'instances' class method" % self.name
116+
end
117+
112118
# Create the methods for a given command.
113119
def self.make_command_methods(name)
114120
# Now define a method for that command
@@ -323,16 +329,34 @@ def command(name)
323329
self.class.command(name)
324330
end
325331

326-
def initialize(resource)
327-
@resource = resource
328-
329-
# LAK 2007-05-09: Keep the model stuff around for backward compatibility
330-
@model = resource
331-
@property_hash = {}
332+
def initialize(resource = nil)
333+
if resource.is_a?(Hash)
334+
@property_hash = resource.dup
335+
elsif resource
336+
@resource = resource if resource
337+
# LAK 2007-05-09: Keep the model stuff around for backward compatibility
338+
@model = resource
339+
@property_hash = {}
340+
else
341+
@property_hash = {}
342+
end
332343
end
333344

334345
def name
335-
@resource.name
346+
if n = @property_hash[:name]
347+
return n
348+
elsif self.resource
349+
resource.name
350+
else
351+
raise Puppet::DevError, "No resource and no name in property hash"
352+
end
353+
end
354+
355+
# Set passed params as the current values.
356+
def set(params)
357+
params.each do |param, value|
358+
@property_hash[symbolize(param)] = value
359+
end
336360
end
337361

338362
def to_s

lib/puppet/provider/nameservice/netinfo.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ def self.finish
4545
end
4646
end
4747

48+
def self.instances
49+
report(@resource_type.validproperties).collect do |hash|
50+
self.new(hash)
51+
end
52+
end
53+
4854
# Convert a NetInfo line into a hash of data.
4955
def self.line2hash(line, params)
5056
values = line.split(/\t/)
@@ -61,12 +67,6 @@ def self.line2hash(line, params)
6167
hash
6268
end
6369

64-
def self.list
65-
report(@resource_type.validproperties).collect do |hash|
66-
@resource_type.hash2obj(hash)
67-
end
68-
end
69-
7070
# What field the value is stored under.
7171
def self.netinfokey(name)
7272
name = symbolize(name)

lib/puppet/provider/package/apple.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,17 @@
1111

1212
defaultfor :operatingsystem => :darwin
1313

14-
def self.listbyname
14+
def self.instances
15+
instance_by_name.collect do |name|
16+
self.new(
17+
:name => name,
18+
:provider => :apple,
19+
:ensure => :installed
20+
)
21+
end
22+
end
23+
24+
def self.instance_by_name
1525
Dir.entries("/Library/Receipts").find_all { |f|
1626
f =~ /\.pkg$/
1727
}.collect { |f|
@@ -22,16 +32,6 @@ def self.listbyname
2232
}
2333
end
2434

25-
def self.list
26-
listbyname.collect do |name|
27-
Puppet.type(:package).installedpkg(
28-
:name => name,
29-
:provider => :apple,
30-
:ensure => :installed
31-
)
32-
end
33-
end
34-
3535
def query
3636
if FileTest.exists?("/Library/Receipts/#{@resource[:name]}.pkg")
3737
return {:name => @resource[:name], :ensure => :present}

lib/puppet/provider/package/blastwave.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ def self.extended(mod)
2323
end
2424
end
2525

26-
def self.list(hash = {})
26+
def self.instances(hash = {})
2727
blastlist(hash).collect do |bhash|
2828
bhash.delete(:avail)
29-
Puppet::Type.type(:package).installedpkg(bhash)
29+
new(bhash)
3030
end
3131
end
3232

lib/puppet/provider/package/darwinport.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ def self.eachpkgashash
3131
}
3232
end
3333

34-
def self.list
34+
def self.instances
3535
packages = []
3636

3737
eachpkgashash do |hash|
38-
pkg = Puppet.type(:package).installedpkg(hash)
39-
packages << pkg
38+
packages << new(hash)
4039
end
4140

4241
return packages

lib/puppet/provider/package/dpkg.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
commands :dpkg => "/usr/bin/dpkg"
77
commands :dpkgquery => "/usr/bin/dpkg-query"
88

9-
def self.list
9+
def self.instances
1010
packages = []
1111

1212
# list out all of the packages
@@ -29,7 +29,7 @@ def self.list
2929

3030
hash[:provider] = self.name
3131

32-
packages.push Puppet.type(:package).installedpkg(hash)
32+
packages << new(hash)
3333
else
3434
Puppet.warning "Failed to match dpkg-query line %s" %
3535
line.inspect

lib/puppet/provider/package/gem.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ def self.gemsplit(desc)
5656
end
5757
end
5858

59-
def self.list(justme = false)
59+
def self.instances(justme = false)
6060
gemlist(:local => true).collect do |hash|
61-
Puppet::Type.type(:package).installedpkg(hash)
61+
new(hash)
6262
end
6363
end
6464

lib/puppet/provider/package/openbsd.rb

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
defaultfor :operatingsystem => :openbsd
88
confine :operatingsystem => :openbsd
99

10-
def self.list
10+
def self.instances
1111
packages = []
1212

1313
begin
@@ -29,21 +29,14 @@ def self.list
2929

3030
hash[:provider] = self.name
3131

32-
pkg = Puppet.type(:package).installedpkg(hash)
33-
packages << pkg
32+
packages << new(hash)
3433
else
3534
# Print a warning on lines we can't match, but move
3635
# on, since it should be non-fatal
3736
warning("Failed to match line %s" % line)
3837
end
3938
}
4039
end
41-
# Mark as absent any packages we didn't find
42-
Puppet.type(:package).each do |pkg|
43-
unless packages.include? pkg
44-
pkg.is = [:ensure, :absent]
45-
end
46-
end
4740

4841
return packages
4942
rescue Puppet::ExecutionFailure

lib/puppet/provider/package/pkgdmg.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
commands :curl => "/usr/bin/curl"
2424

2525
# JJM We store a cookie for each installed .pkg.dmg in /var/db
26-
def self.listbyname
26+
def self.instance_by_name
2727
Dir.entries("/var/db").find_all { |f|
2828
f =~ /^\.puppet_pkgdmg_installed_/
2929
}.collect do |f|
@@ -33,9 +33,9 @@ def self.listbyname
3333
end
3434
end
3535

36-
def self.list
37-
listbyname.collect do |name|
38-
Puppet.type(:package).installedpkg(
36+
def self.instances
37+
instance_by_name.collect do |name|
38+
new(
3939
:name => name,
4040
:provider => :pkgdmg,
4141
:ensure => :installed

lib/puppet/provider/package/portage.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
defaultfor :operatingsystem => :gentoo
99

10-
def self.list
10+
def self.instances
1111
result_format = /(\S+) (\S+) \[(.*)\] \[[^0-9]*([^\s:]*)(:\S*)?\] ([\S]*) (.*)/
1212
result_fields = [:category, :name, :ensure, :version_available, :slot, :vendor, :description]
1313

@@ -28,7 +28,7 @@ def self.list
2828
package[:provider] = :portage
2929
package[:ensure] = package[:ensure].split.last
3030

31-
packages.push(Puppet.type(:package).installedpkg(package))
31+
packages << new(package)
3232
end
3333
end
3434

lib/puppet/provider/package/rpm.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
commands :rpm => "rpm"
1212

13-
def self.list
13+
def self.instances
1414
packages = []
1515

1616
# list out all of the packages
@@ -30,7 +30,7 @@ def self.list
3030
hash[field] = value
3131
}
3232
hash[:provider] = self.name
33-
packages.push Puppet.type(:package).installedpkg(hash)
33+
packages << new(hash)
3434
else
3535
raise "failed to match rpm line %s" % line
3636
end

0 commit comments

Comments
 (0)