| Class | Puppet::Parser::Compiler |
| In: |
lib/puppet/parser/compiler.rb
|
| Parent: | Object |
Maintain a graph of scopes, along with a bunch of data about the individual catalog we‘re compiling.
| catalog | [R] | |
| collections | [R] | |
| facts | [R] | |
| node | [R] | |
| node_scope | [R] | |
| parser | [R] |
Set up our compile. We require a parser and a node object; the parser is so we can look up classes and AST nodes, and the node has all of the client‘s info, like facts and environment.
# File lib/puppet/parser/compiler.rb, line 164
164: def initialize(node, parser, options = {})
165: @node = node
166: @parser = parser
167:
168: options.each do |param, value|
169: begin
170: send(param.to_s + "=", value)
171: rescue NoMethodError
172: raise ArgumentError, "Compiler objects do not accept %s" % param
173: end
174: end
175:
176: initvars()
177: init_main()
178: end
Add a collection to the global list.
# File lib/puppet/parser/compiler.rb, line 16
16: def add_collection(coll)
17: @collections << coll
18: end
Store a resource override.
# File lib/puppet/parser/compiler.rb, line 21
21: def add_override(override)
22: # If possible, merge the override in immediately.
23: if resource = @catalog.resource(override.ref)
24: resource.merge(override)
25: else
26: # Otherwise, store the override for later; these
27: # get evaluated in Resource#finish.
28: @resource_overrides[override.ref] << override
29: end
30: end
Store a resource in our resource table.
# File lib/puppet/parser/compiler.rb, line 33
33: def add_resource(scope, resource)
34: # Note that this will fail if the resource is not unique.
35: @catalog.add_resource(resource)
36:
37: # And in the resource graph. At some point, this might supercede
38: # the global resource table, but the table is a lot faster
39: # so it makes sense to maintain for now.
40: @catalog.add_edge(scope.resource, resource)
41: end
Do we use nodes found in the code, vs. the external node sources?
# File lib/puppet/parser/compiler.rb, line 44
44: def ast_nodes?
45: parser.nodes.length > 0
46: end
Return the scope associated with a class. This is just here so that subclasses can set their parent scopes to be the scope of their parent class, and it‘s also used when looking up qualified variables.
# File lib/puppet/parser/compiler.rb, line 66
66: def class_scope(klass)
67: # They might pass in either the class or class name
68: if klass.respond_to?(:classname)
69: @class_scopes[klass.classname]
70: else
71: @class_scopes[klass]
72: end
73: end
Store the fact that we‘ve evaluated a class, and store a reference to the scope in which it was evaluated, so that we can look it up later.
# File lib/puppet/parser/compiler.rb, line 50
50: def class_set(name, scope)
51: if existing = @class_scopes[name]
52: if existing.nodescope? != scope.nodescope?
53: raise Puppet::ParseError, "Cannot have classes, nodes, or definitions with the same name"
54: else
55: raise Puppet::DevError, "Somehow evaluated %s %s twice" % [ existing.nodescope? ? "node" : "class", name]
56: end
57: end
58: @class_scopes[name] = scope
59: @catalog.add_class(name) unless name == ""
60: end
Return a list of all of the defined classes.
# File lib/puppet/parser/compiler.rb, line 76
76: def classlist
77: return @catalog.classes
78: end
Compiler our catalog. This mostly revolves around finding and evaluating classes. This is the main entry into our catalog.
# File lib/puppet/parser/compiler.rb, line 82
82: def compile
83: # Set the client's parameters into the top scope.
84: set_node_parameters()
85:
86: evaluate_main()
87:
88: evaluate_ast_node()
89:
90: evaluate_node_classes()
91:
92: evaluate_generators()
93:
94: finish()
95:
96: fail_on_unevaluated()
97:
98: if Puppet[:storeconfigs]
99: store()
100: end
101:
102: return @catalog
103: end
LAK:FIXME There are no tests for this.
# File lib/puppet/parser/compiler.rb, line 106
106: def delete_collection(coll)
107: @collections.delete(coll) if @collections.include?(coll)
108: end
Return the node‘s environment.
# File lib/puppet/parser/compiler.rb, line 111
111: def environment
112: unless defined? @environment
113: if node.environment and node.environment != ""
114: @environment = node.environment
115: else
116: @environment = nil
117: end
118: end
119: @environment
120: end
Evaluate each specified class in turn. If there are any classes we can‘t find, just tag the catalog and move on. This method really just creates resource objects that point back to the classes, and then the resources are themselves evaluated later in the process.
# File lib/puppet/parser/compiler.rb, line 131
131: def evaluate_classes(classes, scope, lazy_evaluate = true)
132: unless scope.source
133: raise Puppet::DevError, "No source for scope passed to evaluate_classes"
134: end
135: found = []
136: classes.each do |name|
137: # If we can find the class, then make a resource that will evaluate it.
138: if klass = scope.findclass(name)
139: found << name and next if class_scope(klass)
140:
141: resource = klass.evaluate(scope)
142:
143: # If they've disabled lazy evaluation (which the :include function does),
144: # then evaluate our resource immediately.
145: resource.evaluate unless lazy_evaluate
146: found << name
147: else
148: Puppet.info "Could not find class %s for %s" % [name, node.name]
149: @catalog.tag(name)
150: end
151: end
152: found
153: end
Evaluate all of the classes specified by the node.
# File lib/puppet/parser/compiler.rb, line 123
123: def evaluate_node_classes
124: evaluate_classes(@node.classes, topscope)
125: end
Return a resource by either its ref or its type and title.
# File lib/puppet/parser/compiler.rb, line 156
156: def findresource(*args)
157: @catalog.resource(*args)
158: end
Create a new scope, with either a specified parent scope or using the top scope. Adds an edge between the scope and its parent to the graph.
# File lib/puppet/parser/compiler.rb, line 183
183: def newscope(parent, options = {})
184: parent ||= topscope
185: options[:compiler] = self
186: options[:parser] ||= self.parser
187: scope = Puppet::Parser::Scope.new(options)
188: @scope_graph.add_edge(parent, scope)
189: scope
190: end
Find the parent of a given scope. Assumes scopes only ever have one in edge, which will always be true.
# File lib/puppet/parser/compiler.rb, line 194
194: def parent(scope)
195: if ary = @scope_graph.adjacent(scope, :direction => :in) and ary.length > 0
196: ary[0]
197: else
198: nil
199: end
200: end
Return any overrides for the given resource.
# File lib/puppet/parser/compiler.rb, line 203
203: def resource_overrides(resource)
204: @resource_overrides[resource.ref]
205: end