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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
#!/usr/local/bin/ruby -w
# $Id$
require 'puppet'
module Puppet
#------------------------------------------------------------
class TransObject < Hash
attr_accessor :type, :name
@@ohash = {}
@@oarray = []
def TransObject.add(object)
@@oarray.push object
# this is just so we can check, at parse time, whether a required
# object has already been mentioned when it is listed as required
# because we're ordered, as long as an object gets made before its
# dependent objects will get synced later
@@ohash[object.longname] = object
end
def TransObject.clear
@@oarray.clear
end
def TransObject.list
return @@oarray
end
def initialize(name,type)
self[:name] = name
@type = type
@name = name
self.class.add(self)
end
def longname
return [self.type,self[:name]].join('--')
end
#def name
# return self[:name]
#end
def to_s
return "%s(%s) => %s" % [@type,self[:name],super]
end
def to_type
retobj = nil
if type = Puppet::Type.type(self.type)
retobj = type.new(self)
else
raise Puppet::Error.new("Could not find object type %s" % self.type)
end
return retobj
end
end
#------------------------------------------------------------
#------------------------------------------------------------
# just a linear container for objects
class TransBucket < Array
attr_accessor :name, :type
def push(*args)
args.each { |arg|
case arg
when Puppet::TransBucket, Puppet::TransObject, Puppet::TransSetting
# nada
else
raise "TransBuckets cannot handle objects of type %s" %
arg.class
end
}
super
end
def to_type
# this container will contain the equivalent of all objects at
# this level
#container = Puppet::Component.new(:name => @name, :type => @type)
unless defined? @name
raise "TransBuckets must have names"
end
unless defined? @type
Puppet.debug "TransBucket '%s' has no type" % @name
end
hash = {
:name => @name,
:type => @type
}
if defined? @parameters
@parameters.each { |param,value|
Puppet.debug "Defining %s on %s of type %s" %
[param,@name,@type]
hash[param] = value
}
else
Puppet.debug "%s has no parameters" % @name
end
container = Puppet::Component.new(hash)
nametable = {}
self.each { |child|
# the fact that we descend here means that we are
# always going to execute depth-first
# which is _probably_ a good thing, but one never knows...
if child.is_a?(Puppet::TransBucket)
# just perform the same operation on any children
container.push(child.to_type)
elsif child.is_a?(Puppet::TransObject)
# do a simple little naming hack to see if the object already
# exists in our scope
# this assumes that type/name combinations are globally
# unique
# XXX this still might be wrong, because it doesn't search
# up scopes
# either that, or it's redundant
name = [child[:name],child.type].join("--")
if nametable.include?(name)
object = nametable[name]
child.each { |var,value|
# don't rename; this shouldn't be possible anyway
next if var == :name
Puppet.debug "Adding %s to %s" % [var,name]
# override any existing values
object[var] = value
}
object.parent = self
else # the object does not exist yet in our scope
# now we have the object instantiated, in our scope
begin
object = child.to_type
rescue Puppet::Error => except
Puppet.err "Failed to create %s %s: %s" %
[child.type,child.name,except.message]
if Puppet[:debug]
puts child.inspect
puts except.stack
end
next
rescue => except
Puppet.err "Failed to create %s %s: %s" %
[child.type,child.name,except.message]
if Puppet[:debug]
puts child.inspect
puts caller
end
next
end
nametable[name] = object
# this sets the order of the object
container.push object
end
else
raise "TransBucket#to_type cannot handle objects of type %s" %
child.class
end
}
# at this point, no objects at are level are still Transportable
# objects
return container
end
def param(param,value)
unless defined? @parameters
@parameters = {}
end
@parameters[param] = value
end
end
#------------------------------------------------------------
end
|