summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2007-09-01 09:51:03 -0500
committerLuke Kanies <luke@madstop.com>2007-09-01 09:51:03 -0500
commit25f6d7c521cb0189cf691fb1c4bce4b675568300 (patch)
tree582dd091cbaf62135ce7e81902bb582f154c363f /lib/puppet
parent62806bb8749d001354078f176fad8a0a54316efb (diff)
downloadpuppet-25f6d7c521cb0189cf691fb1c4bce4b675568300.tar.gz
puppet-25f6d7c521cb0189cf691fb1c4bce4b675568300.tar.xz
puppet-25f6d7c521cb0189cf691fb1c4bce4b675568300.zip
Deleting old documentation that somehow made it back into the tree in the switch to git, and refactoring the evaluate_classes method on the compile object so I can use resources as intermediaries, thus making classes do late-binding evaluation.
Diffstat (limited to 'lib/puppet')
-rw-r--r--lib/puppet/metatype/metaparams.rb4
-rwxr-xr-xlib/puppet/network/handler/facts.rb2
-rw-r--r--lib/puppet/network/handler/master.rb2
-rw-r--r--lib/puppet/parser/ast/definition.rb226
-rw-r--r--lib/puppet/parser/ast/hostclass.rb4
-rw-r--r--lib/puppet/parser/compile.rb16
-rw-r--r--lib/puppet/parser/functions.rb2
-rw-r--r--lib/puppet/parser/parser_support.rb2
8 files changed, 243 insertions, 15 deletions
diff --git a/lib/puppet/metatype/metaparams.rb b/lib/puppet/metatype/metaparams.rb
index 9825efc61..0e31bb41c 100644
--- a/lib/puppet/metatype/metaparams.rb
+++ b/lib/puppet/metatype/metaparams.rb
@@ -273,8 +273,8 @@ class Puppet::Type
# Either of the two retrieval attempts could have returned
# nil.
unless object
- self.fail "Could not retrieve dependency '%s[%s]'" %
- [tname.to_s.capitalize, name]
+ self.fail "Could not retrieve dependency '%s[%s]' of %s" %
+ [tname.to_s.capitalize, self.ref, name]
end
# Are we requiring them, or vice versa? See the method docs
diff --git a/lib/puppet/network/handler/facts.rb b/lib/puppet/network/handler/facts.rb
index e0b93f942..4767e8be4 100755
--- a/lib/puppet/network/handler/facts.rb
+++ b/lib/puppet/network/handler/facts.rb
@@ -66,5 +66,3 @@ class Puppet::Network::Handler
end
end
end
-
-# $Id$
diff --git a/lib/puppet/network/handler/master.rb b/lib/puppet/network/handler/master.rb
index e5bfa8122..ace383e9f 100644
--- a/lib/puppet/network/handler/master.rb
+++ b/lib/puppet/network/handler/master.rb
@@ -141,5 +141,3 @@ class Puppet::Network::Handler
end
end
end
-
-# $Id$
diff --git a/lib/puppet/parser/ast/definition.rb b/lib/puppet/parser/ast/definition.rb
new file mode 100644
index 000000000..c44f0f903
--- /dev/null
+++ b/lib/puppet/parser/ast/definition.rb
@@ -0,0 +1,226 @@
+require 'puppet/parser/ast/branch'
+
+class Puppet::Parser::AST
+ # Evaluate the stored parse tree for a given component. This will
+ # receive the arguments passed to the component and also the type and
+ # name of the component.
+ class Definition < AST::Branch
+ include Puppet::Util
+ include Puppet::Util::Warnings
+ include Puppet::Util::MethodHelper
+ class << self
+ attr_accessor :name
+ end
+
+ # The class name
+ @name = :definition
+
+ attr_accessor :classname, :arguments, :code, :scope, :keyword
+ attr_accessor :exported, :namespace, :parser, :virtual
+
+ # These are retrieved when looking up the superclass
+ attr_accessor :name
+
+ attr_reader :parentclass
+
+ def child_of?(klass)
+ false
+ end
+
+ def evaluate_resource(hash)
+ origscope = hash[:scope]
+ title = hash[:title]
+ args = symbolize_options(hash[:arguments] || {})
+
+ name = args[:name] || title
+
+ exported = hash[:exported]
+ virtual = hash[:virtual]
+
+ pscope = origscope
+ scope = subscope(pscope, title)
+
+ if virtual or origscope.virtual?
+ scope.virtual = true
+ end
+
+ if exported or origscope.exported?
+ scope.exported = true
+ end
+
+ # Additionally, add a tag for whatever kind of class
+ # we are
+ if @classname != "" and ! @classname.nil?
+ @classname.split(/::/).each { |tag| scope.tag(tag) }
+ end
+
+ [name, title].each do |str|
+ unless str.nil? or str =~ /[^\w]/ or str == ""
+ scope.tag(str)
+ end
+ end
+
+ # define all of the arguments in our local scope
+ if self.arguments
+ # Verify that all required arguments are either present or
+ # have been provided with defaults.
+ self.arguments.each { |arg, default|
+ arg = symbolize(arg)
+ unless args.include?(arg)
+ if defined? default and ! default.nil?
+ default = default.safeevaluate :scope => scope
+ args[arg] = default
+ #Puppet.debug "Got default %s for %s in %s" %
+ # [default.inspect, arg.inspect, @name.inspect]
+ else
+ parsefail "Must pass %s to %s of type %s" %
+ [arg,title,@classname]
+ end
+ end
+ }
+ end
+
+ # Set each of the provided arguments as variables in the
+ # component's scope.
+ args.each { |arg,value|
+ unless validattr?(arg)
+ parsefail "%s does not accept attribute %s" % [@classname, arg]
+ end
+
+ exceptwrap do
+ scope.setvar(arg.to_s,args[arg])
+ end
+ }
+
+ unless args.include? :title
+ scope.setvar("title",title)
+ end
+
+ unless args.include? :name
+ scope.setvar("name",name)
+ end
+
+ if self.code
+ return self.code.safeevaluate(:scope => scope)
+ else
+ return nil
+ end
+ end
+
+ def initialize(hash = {})
+ @arguments = nil
+ @parentclass = nil
+ super
+
+ # Convert the arguments to a hash for ease of later use.
+ if @arguments
+ unless @arguments.is_a? Array
+ @arguments = [@arguments]
+ end
+ oldargs = @arguments
+ @arguments = {}
+ oldargs.each do |arg, val|
+ @arguments[arg] = val
+ end
+ else
+ @arguments = {}
+ end
+
+ # Deal with metaparams in the argument list.
+ @arguments.each do |arg, defvalue|
+ next unless Puppet::Type.metaparamclass(arg)
+ if defvalue
+ warnonce "%s is a metaparam; this value will inherit to all contained elements" % arg
+ else
+ raise Puppet::ParseError,
+ "%s is a metaparameter; please choose another name" %
+ name
+ end
+ end
+ end
+
+ def find_parentclass
+ @parser.findclass(namespace, parentclass)
+ end
+
+ # Set our parent class, with a little check to avoid some potential
+ # weirdness.
+ def parentclass=(name)
+ if name == self.classname
+ parsefail "Parent classes must have dissimilar names"
+ end
+
+ @parentclass = name
+ end
+
+ # Hunt down our class object.
+ def parentobj
+ if @parentclass
+ # Cache our result, since it should never change.
+ unless defined?(@parentobj)
+ unless tmp = find_parentclass
+ parsefail "Could not find %s %s" % [self.class.name, @parentclass]
+ end
+
+ if tmp == self
+ parsefail "Parent classes must have dissimilar names"
+ end
+
+ @parentobj = tmp
+ end
+ @parentobj
+ else
+ nil
+ end
+ end
+
+ # Create a new subscope in which to evaluate our code.
+ def subscope(scope, name = nil)
+ args = {
+ :type => self.classname,
+ :keyword => self.keyword,
+ :namespace => self.namespace
+ }
+
+ args[:name] = name if name
+ scope = scope.newscope(args)
+ scope.source = self
+
+ return scope
+ end
+
+ def to_s
+ classname
+ end
+
+ # Check whether a given argument is valid. Searches up through
+ # any parent classes that might exist.
+ def validattr?(param)
+ param = param.to_s
+
+ if @arguments.include?(param)
+ # It's a valid arg for us
+ return true
+ elsif param == "name"
+ return true
+# elsif defined? @parentclass and @parentclass
+# # Else, check any existing parent
+# if parent = @scope.lookuptype(@parentclass) and parent != []
+# return parent.validarg?(param)
+# elsif builtin = Puppet::Type.type(@parentclass)
+# return builtin.validattr?(param)
+# else
+# raise Puppet::Error, "Could not find parent class %s" %
+# @parentclass
+# end
+ elsif Puppet::Type.metaparam?(param)
+ return true
+ else
+ # Or just return false
+ return false
+ end
+ end
+ end
+end
+
+# $Id$
diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb
index 9b60c692f..f3b0602b1 100644
--- a/lib/puppet/parser/ast/hostclass.rb
+++ b/lib/puppet/parser/ast/hostclass.rb
@@ -1,10 +1,10 @@
-require 'puppet/parser/ast/component'
+require 'puppet/parser/ast/definition'
class Puppet::Parser::AST
# The code associated with a class. This is different from components
# in that each class is a singleton -- only one will exist for a given
# node.
- class HostClass < AST::Component
+ class HostClass < AST::Definition
@name = :class
# Are we a child of the passed class? Do a recursive search up our
diff --git a/lib/puppet/parser/compile.rb b/lib/puppet/parser/compile.rb
index 710f90273..7159947bf 100644
--- a/lib/puppet/parser/compile.rb
+++ b/lib/puppet/parser/compile.rb
@@ -70,7 +70,7 @@ class Puppet::Parser::Compile
evaluate_ast_node()
- evaluate_classes()
+ evaluate_node_classes()
evaluate_generators()
@@ -109,10 +109,16 @@ class Puppet::Parser::Compile
@environment
end
- # Evaluate each class in turn. If there are any classes we can't find,
- # just tag the configuration and move on.
- def evaluate_classes(classes = nil)
- classes ||= node.classes
+ # Evaluate all of the classes specified by the node.
+ def evaluate_node_classes
+ evaluate_classes(@node.classes, @parser.findclass("", ""))
+ end
+
+ # Evaluate each specified class in turn. If there are any classes we can't
+ # find, just tag the configuration 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.
+ def evaluate_classes(classes, source)
found = []
classes.each do |name|
if klass = @parser.findclass("", name)
diff --git a/lib/puppet/parser/functions.rb b/lib/puppet/parser/functions.rb
index 895b4f083..05d694310 100644
--- a/lib/puppet/parser/functions.rb
+++ b/lib/puppet/parser/functions.rb
@@ -110,7 +110,7 @@ module Functions
# Include the specified classes
newfunction(:include, :doc => "Evaluate one or more classes.") do |vals|
vals = [vals] unless vals.is_a?(Array)
- klasses = compile.evaluate_classes(vals)
+ klasses = compile.evaluate_classes(vals, self)
missing = vals.find_all do |klass|
! klasses.include?(klass)
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index 660fa8169..be1d73047 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -336,7 +336,7 @@ class Puppet::Parser::Parser
args[param] = options[param] if options[param]
end
- @astset.definitions[name] = ast AST::Component, args
+ @astset.definitions[name] = ast AST::Definition, args
end
# Create a new node. Nodes are special, because they're stored in a global