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
|
#!/usr/local/bin/ruby -w
# $Id$
# the interpreter
#
# this builds our virtual pinball machine, into which we'll place our host-specific
# information and out of which we'll receive our host-specific configuration
require 'puppet'
require 'puppet/parser/parser'
require 'puppet/parser/scope'
module Puppet
module Parser
#---------------------------------------------------------------
class Interpreter
attr_accessor :ast, :topscope
# just shorten the constant path a bit, using what amounts to an alias
AST = Puppet::Parser::AST
#------------------------------------------------------------
def clear
TransObject.clear
end
#------------------------------------------------------------
#------------------------------------------------------------
#def callfunc(function,*args)
# #Puppet.debug("Calling %s on %s" % [function,@client])
# @client.callfunc(function,*args)
# #Puppet.debug("Finished %s" % function)
#end
#------------------------------------------------------------
#------------------------------------------------------------
# create our interpreter
def initialize(hash)
unless hash.include?(:ast)
raise ArgumentError.new("Must pass tree and client to Interpreter")
end
@ast = hash[:ast]
#@client = hash[:client]
@scope = Puppet::Parser::Scope.new() # no parent scope
@topscope = @scope
@scope.interp = self
if hash.include?(:facts)
facts = hash[:facts]
unless facts.is_a?(Hash)
raise ArgumentError.new("Facts must be a hash")
end
facts.each { |fact,value|
@scope.setvar(fact,value)
}
end
end
#------------------------------------------------------------
#------------------------------------------------------------
# evaluate our whole tree
def run
# evaluate returns a value, but at the top level we only
# care about its side effects
# i think
unless @ast.is_a?(AST) or @ast.is_a?(AST::ASTArray)
Puppet.err "Received top-level non-ast '%s' of type %s" %
[@ast,@ast.class]
raise TypeError.new("Received non-ast '%s' of type %s" %
[@ast,@ast.class])
end
begin
@ast.evaluate(@scope)
rescue Puppet::DevError, Puppet::Error, Puppet::ParseError => except
#Puppet.err "File %s, line %s: %s" %
# [except.file, except.line, except.message]
if Puppet[:debug]
puts except.stack
end
#exit(1)
raise
rescue => except
error = Puppet::DevError.new("%s: %s" %
[except.class, except.message])
error.stack = caller
if Puppet[:debug]
puts error.stack
end
raise error
end
# okay, at this point we have a tree of scopes, and we want to
# unzip along that tree, building our structure of objects
# to pass to the client
# this will be heirarchical, and will (at this point) contain
# only TransObjects and TransSettings
@topscope.name = "top"
@topscope.type = "puppet"
begin
topbucket = @topscope.to_trans
rescue => detail
Puppet.warning detail
raise
end
# add our settings to the front of the array
# at least, for now
#@topscope.typesets.each { |setting|
# topbucket.unshift setting
#}
# guarantee that settings are at the very top
#topbucket.push settingbucket
#topbucket.push @scope.to_trans
#retlist = TransObject.list
#Puppet.debug "retobject length is %s" % retlist.length
#TransObject.clear
return topbucket
end
#------------------------------------------------------------
#------------------------------------------------------------
def scope
return @scope
end
#------------------------------------------------------------
end
#---------------------------------------------------------------
end
end
|