2
2
# Copyright (c) 2007. All rights reserved.
4
4
require 'puppet/node'
5
require 'puppet/node/catalog'
5
require 'puppet/resource/catalog'
6
6
require 'puppet/util/errors'
8
8
# Maintain a graph of scopes, along with a bunch of data
10
10
class Puppet::Parser::Compiler
11
11
include Puppet::Util
12
12
include Puppet::Util::Errors
13
attr_reader :parser, :node, :facts, :collections, :catalog, :node_scope
13
attr_reader :parser, :node, :facts, :collections, :catalog, :node_scope, :resources
15
15
# Add a collection to the global list.
16
16
def add_collection(coll)
32
32
# Store a resource in our resource table.
33
33
def add_resource(scope, resource)
34
@resources << resource
34
36
# Note that this will fail if the resource is not unique.
35
37
@catalog.add_resource(resource)
37
39
# And in the resource graph. At some point, this might supercede
38
40
# the global resource table, but the table is a lot faster
39
41
# so it makes sense to maintain for now.
40
@catalog.add_edge(scope.resource, resource)
42
if resource.type.to_s.downcase == "class" and main = @catalog.resource(:class, :main)
43
@catalog.add_edge(main, resource)
45
@catalog.add_edge(scope.resource, resource)
43
49
# Do we use nodes found in the code, vs. the external node sources?
45
parser.nodes.length > 0
48
54
# Store the fact that we've evaluated a class, and store a reference to
136
138
classes.each do |name|
137
139
# If we can find the class, then make a resource that will evaluate it.
138
if klass = scope.findclass(name)
140
if klass = scope.find_hostclass(name)
139
141
found << name and next if class_scope(klass)
141
143
resource = klass.evaluate(scope)
204
206
@resource_overrides[resource.ref]
207
# Return a list of all resources.
212
209
# The top scope is usually the top-level scope, but if we're using AST nodes,
213
210
# then it is instead the node's scope.
224
221
# Now see if we can find the node.
226
223
@node.names.each do |name|
227
break if astnode = @parser.nodes[name.to_s.downcase]
224
break if astnode = @parser.node(name.to_s.downcase)
230
unless (astnode ||= @parser.nodes["default"])
227
unless (astnode ||= @parser.node("default"))
231
228
raise Puppet::ParseError, "Could not find default node or by name with '%s'" % node.names.join(", ")
306
303
# Find and evaluate our main object, if possible.
307
304
def evaluate_main
308
@main = @parser.findclass("", "") || @parser.newclass("")
305
@main = @parser.find_hostclass("", "") || @parser.newclass("")
309
306
@topscope.source = @main
310
307
@main_resource = Puppet::Parser::Resource.new(:type => "class", :title => :main, :scope => @topscope, :source => @main)
311
308
@topscope.resource = @main_resource
310
@resources << @main_resource
313
311
@catalog.add_resource(@main_resource)
315
313
@main_resource.evaluate
366
364
# Make sure all of our resources and such have done any last work
369
@catalog.vertices.each do |resource|
367
resources.each do |resource|
370
368
# Add in any resource overrides.
371
369
if overrides = resource_overrides(resource)
372
370
overrides.each do |over|
412
410
@scope_graph = Puppet::SimpleGraph.new
414
412
# For maintaining the relationship between scopes and their resources.
415
@catalog = Puppet::Node::Catalog.new(@node.name)
413
@catalog = Puppet::Resource::Catalog.new(@node.name)
416
414
@catalog.version = @parser.version
416
# local resource array to maintain resource ordering
419
# Make sure any external node classes are in our class list
420
@catalog.add_class(*@node.classes)
419
423
# Set the node's parameters into the top-scope as variables.
421
425
node.parameters.each do |param, value|
422
426
@topscope.setvar(param, value)
426
# Store the catalog into the database.
428
unless Puppet.features.rails?
430
"storeconfigs is enabled but rails is unavailable"
433
unless ActiveRecord::Base.connected?
434
Puppet::Rails.connect
437
# We used to have hooks here for forking and saving, but I don't
438
# think it's worth retaining at this point.
439
store_to_active_record(@node, @catalog.vertices)
442
# Do the actual storage.
443
def store_to_active_record(node, resources)
445
# We store all of the objects, even the collectable ones
446
benchmark(:info, "Stored catalog for #{node.name}") do
447
Puppet::Rails::Host.transaction do
448
Puppet::Rails::Host.store(node, resources)
453
puts detail.backtrace
455
Puppet.err "Could not store configs: %s" % detail.to_s
429
# These might be nil.
430
catalog.client_version = node.parameters["clientversion"]
431
catalog.server_version = node.parameters["serverversion"]
459
434
# Return an array of all of the unevaluated resources. These will be definitions,
460
435
# which need to get evaluated into native resources.
461
436
def unevaluated_resources
462
ary = @catalog.vertices.reject { |resource| resource.builtin? or resource.evaluated? }
437
ary = resources.reject { |resource| resource.builtin? or resource.evaluated? }