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.

Methods

Included Modules

Puppet::Util Puppet::Util::Errors

Attributes

catalog  [R] 
collections  [R] 
facts  [R] 
node  [R] 
node_scope  [R] 
parser  [R] 

Public Class methods

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.

[Source]

     # 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

Public Instance methods

Add a collection to the global list.

[Source]

    # File lib/puppet/parser/compiler.rb, line 16
16:     def add_collection(coll)
17:         @collections << coll
18:     end

Store a resource override.

[Source]

    # 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.

[Source]

    # 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?

[Source]

    # 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.

[Source]

    # 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.

[Source]

    # 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.

[Source]

    # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # File lib/puppet/parser/compiler.rb, line 203
203:     def resource_overrides(resource)
204:         @resource_overrides[resource.ref]
205:     end

Return a list of all resources.

[Source]

     # File lib/puppet/parser/compiler.rb, line 208
208:     def resources
209:         @catalog.vertices
210:     end

The top scope is usually the top-level scope, but if we‘re using AST nodes, then it is instead the node‘s scope.

[Source]

     # File lib/puppet/parser/compiler.rb, line 214
214:     def topscope
215:         node_scope || @topscope
216:     end

[Validate]