diff options
-rwxr-xr-x | bin/puppetmasterd | 7 | ||||
-rw-r--r-- | lib/puppet/parser/interpreter.rb | 30 | ||||
-rw-r--r-- | lib/puppet/parser/scope.rb | 66 | ||||
-rw-r--r-- | lib/puppet/server/master.rb | 4 | ||||
-rw-r--r-- | test/client/tc_client.rb | 2 | ||||
-rwxr-xr-x | test/language/tc_interpreter.rb | 2 | ||||
-rwxr-xr-x | test/language/tc_scope.rb | 20 | ||||
-rw-r--r-- | test/puppettest.rb | 2 | ||||
-rw-r--r-- | test/server/tc_master.rb | 4 | ||||
-rw-r--r-- | test/server/tc_server.rb | 1 |
10 files changed, 100 insertions, 38 deletions
diff --git a/bin/puppetmasterd b/bin/puppetmasterd index 45bd07f1a..055892004 100755 --- a/bin/puppetmasterd +++ b/bin/puppetmasterd @@ -52,6 +52,10 @@ # noca:: # Do not function as a certificate authority. # +# nonodes:: +# Do not use individual node designations; each node will receive the result +# of evaluating the entire configuration. +# # parseonly:: # Just parse the central manifest to verify it is syntactically correct. # @@ -93,6 +97,7 @@ result = GetoptLong.new( [ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ], [ "--manifest", "-m", GetoptLong::REQUIRED_ARGUMENT ], [ "--noca", GetoptLong::NO_ARGUMENT ], + [ "--nonodes", GetoptLong::NO_ARGUMENT ], [ "--parseonly", GetoptLong::NO_ARGUMENT ], [ "--port", "-p", GetoptLong::REQUIRED_ARGUMENT ], [ "--ssldir", "-s", GetoptLong::REQUIRED_ARGUMENT ], @@ -143,6 +148,8 @@ begin master[:File] = arg when "--noca" haveca = false + when "--nonodes" + master[:UseNodes] = false when "--parseonly" parseonly = true when "--port" diff --git a/lib/puppet/parser/interpreter.rb b/lib/puppet/parser/interpreter.rb index 9335d81aa..2b036018f 100644 --- a/lib/puppet/parser/interpreter.rb +++ b/lib/puppet/parser/interpreter.rb @@ -10,21 +10,23 @@ require 'puppet/parser/scope' module Puppet module Parser class Interpreter - attr_accessor :ast, :topscope + attr_accessor :ast # just shorten the constant path a bit, using what amounts to an alias AST = Puppet::Parser::AST # create our interpreter def initialize(hash) unless hash.include?(:Manifest) - raise Puppet::DevError, "Interpreter was not passed a file" + raise Puppet::DevError, "Interpreter was not passed a manifest" end @file = hash[:Manifest] if hash.include?(:UseNodes) + Puppet.warning "Usenodes is %s" % hash[:UseNodes] @usenodes = hash[:UseNodes] else + Puppet.warning "Usenodes is missing" @usenodes = true end @@ -38,6 +40,9 @@ module Puppet def run(client, facts) parsefiles() + # Really, we should stick multiple names in here + # but for now just make a simple array + names = [client] begin if @usenodes unless client @@ -46,13 +51,13 @@ module Puppet end # We've already evaluated the AST, in this case - @scope.evalnode(client, facts) + @scope.evalnode(names, facts) else - scope = Puppet::Parser::Scope.new() # no parent scope - scope.interp = self - scope.evaluate(@ast, facts) + @scope = Puppet::Parser::Scope.new() # no parent scope + @scope.interp = self + @scope.evaluate(@ast, facts) end - @ast.evaluate(@scope) + #@ast.evaluate(@scope) rescue Puppet::DevError, Puppet::Error, Puppet::ParseError => except #Puppet.err "File %s, line %s: %s" % # [except.file, except.line, except.message] @@ -79,10 +84,10 @@ module Puppet # 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" + @scope.name = "top" + @scope.type = "puppet" begin - topbucket = @topscope.to_trans + topbucket = @scope.to_trans rescue => detail Puppet.warning detail raise @@ -114,11 +119,10 @@ module Puppet # this doesn't actually do anything, because we have to evaluate the # entire configuration each time we get a connect. def evaluate - @scope = Puppet::Parser::Scope.new() # no parent scope - @topscope = @scope - @scope.interp = self if @usenodes + @scope = Puppet::Parser::Scope.new() # no parent scope + @scope.interp = self Puppet.debug "Nodes defined" @ast.safeevaluate(@scope) else diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb index 56bf620dd..d813ea804 100644 --- a/lib/puppet/parser/scope.rb +++ b/lib/puppet/parser/scope.rb @@ -79,7 +79,7 @@ module Puppet # Yield each child scope in turn def each - @children.each { |child| + @children.reject { |child| yield child } end @@ -90,7 +90,8 @@ module Puppet def evalnode(names, facts) scope = code = nil names.each { |node| - scope, code = self.findnode(node) + scope = self.findnode(node) + code = scope.node(node) if scope and code break end @@ -124,14 +125,27 @@ module Puppet # Find a given node's definition; searches downward recursively. def findnode(node) if @nodetable.include?(node) - return [self, @nodetable[node]] + return self else - self.find { |child| - child.findnode(node) + scope = nil + self.reject { |child| + ! child.is_a?(Scope) + }.each { |child| + if scope = child.findnode(node) + break + end } + + return scope end end + # Retrieve a specific node. This is basically only used from within + # 'findnode'. + def node(name) + @nodetable[name] + end + # Evaluate normally, with no node definitions def evaluate(objects, facts = {}) facts.each { |var, value| @@ -245,15 +259,6 @@ module Puppet end end - # Look up hosts from the global table. - def lookuphost(name) - if @@hosttable.include?(name) - return @@hosttable[name] - else - return nil - end - end - # Collect all of the defaults set at any higher scopes. # This is a different type of lookup because it's additive -- # it collects all of the defaults, with defaults in closer scopes @@ -390,12 +395,41 @@ module Puppet } end + # Check whether a node is already defined. + # FIXME Should this system replace the 'UseNodes' flags and such? + def nodedefined?(name) + if defined? @nodemarkers + return @nodemarkers[name] + else + if @parent + return @parent.nodedefined?(name) + else + return false + end + end + end + + # Mark that a node is defined. We don't want to allow more than one + # node definition per name, because, well, that would make things not + # work any more. + def marknode(name) + if @parent + @parent.marknode(name) + else + unless defined? @nodemarkers + @nodemarkers = {} + end + @nodemarkers[name] = true + end + end + # Store a host in the global table. def setnode(name,code) - if @nodetable.include?(name) - raise Puppet::Error, "Host %s is already defined" % name + if self.nodedefined?(name) + raise Puppet::ParseError, "Host %s is already defined" % name else @nodetable[name] = code + self.marknode(name) end #self.nodescope = true diff --git a/lib/puppet/server/master.rb b/lib/puppet/server/master.rb index bf6998bac..08706bea7 100644 --- a/lib/puppet/server/master.rb +++ b/lib/puppet/server/master.rb @@ -38,7 +38,9 @@ class Server args = {:Manifest => @file} - if @local + if hash.include?(:UseNodes) + args[:UseNodes] = hash[:UseNodes] + elsif @local args[:UseNodes] = false end diff --git a/test/client/tc_client.rb b/test/client/tc_client.rb index feaa24184..27d135d4d 100644 --- a/test/client/tc_client.rb +++ b/test/client/tc_client.rb @@ -61,7 +61,7 @@ class TestClient < ServerTest # here we create two servers; we - def test_zzfailureWithUntrustedCerts + def test_failureWithUntrustedCerts Puppet[:autosign] = true # create a pair of clients with no certs diff --git a/test/language/tc_interpreter.rb b/test/language/tc_interpreter.rb index 6135bcb3f..8767dd8a3 100755 --- a/test/language/tc_interpreter.rb +++ b/test/language/tc_interpreter.rb @@ -22,7 +22,7 @@ class TestInterpreter < TestPuppet f.puts "file { \"/etc\": owner => root }" } assert_nothing_raised { - Puppet::Parser::Interpreter.new(:file => file) + Puppet::Parser::Interpreter.new(:Manifest => file) } end end diff --git a/test/language/tc_scope.rb b/test/language/tc_scope.rb index 161dee9c6..192b74b61 100755 --- a/test/language/tc_scope.rb +++ b/test/language/tc_scope.rb @@ -262,13 +262,20 @@ class TestScope < TestPuppet def test_zhostlookup top = Puppet::Parser::Scope.new(nil) - child1 = Puppet::Parser::Scope.new(top) - child2 = Puppet::Parser::Scope.new(top) - sub1 = Puppet::Parser::Scope.new(child1) + # Create a deep scope tree, so that we know we're doing a deeply recursive + # search. + mid1 = Puppet::Parser::Scope.new(top) + mid2 = Puppet::Parser::Scope.new(mid1) + mid3 = Puppet::Parser::Scope.new(mid2) + child1 = Puppet::Parser::Scope.new(mid3) + mida = Puppet::Parser::Scope.new(top) + midb = Puppet::Parser::Scope.new(mida) + midc = Puppet::Parser::Scope.new(midb) + child2 = Puppet::Parser::Scope.new(midc) # verify we can set a host assert_nothing_raised("Could not create host") { - child1.sethost("testing", AST::Node.new( + child1.setnode("testing", AST::Node.new( :name => "testing", :code => :notused ) @@ -277,7 +284,7 @@ class TestScope < TestPuppet # Verify we cannot redefine it assert_raise(Puppet::ParseError, "Duplicate host creation succeeded") { - child2.sethost("testing", AST::Node.new( + child2.setnode("testing", AST::Node.new( :name => "testing", :code => :notused ) @@ -287,7 +294,8 @@ class TestScope < TestPuppet # Now verify we can find the host again host = nil assert_nothing_raised("Host lookup failed") { - host = top.lookuphost("testing") + scope = top.findnode("testing") + host = scope.node("testing") } assert(host, "Could not find host") diff --git a/test/puppettest.rb b/test/puppettest.rb index 23d940d08..f18675549 100644 --- a/test/puppettest.rb +++ b/test/puppettest.rb @@ -181,6 +181,7 @@ class ServerTest < TestPuppet :CA => {}, # so that certs autogenerate :Master => { :File => mktestmanifest(), + :UseNodes => false }, } end @@ -229,6 +230,7 @@ class ExeTest < ServerTest args += " --manifest %s" % manifest args += " --ssldir %s" % Puppet[:ssldir] args += " --port %s" % @@port + args += " --nonodes" args += " --autosign" cmd = "puppetmasterd %s" % args diff --git a/test/server/tc_master.rb b/test/server/tc_master.rb index 29a10662b..4fb8df8b2 100644 --- a/test/server/tc_master.rb +++ b/test/server/tc_master.rb @@ -25,6 +25,7 @@ class TestMaster < ServerTest def test_files count = 0 textfiles { |file| + Puppet.err :mark Puppet.debug("parsing %s" % file) client = nil master = nil @@ -34,6 +35,7 @@ class TestMaster < ServerTest # this is the default server setup master = Puppet::Server::Master.new( :File => file, + :UseNodes => false, :Local => true ) } @@ -78,6 +80,7 @@ class TestMaster < ServerTest # this is the default server setup master = Puppet::Server::Master.new( :File => file, + :UseNodes => false, :Local => true ) } @@ -108,6 +111,7 @@ class TestMaster < ServerTest # this is the default server setup master = Puppet::Server::Master.new( :File => manifest, + :UseNodes => false, :Local => true, :FileTimeout => 0.5 ) diff --git a/test/server/tc_server.rb b/test/server/tc_server.rb index b0afc6398..d7056eef4 100644 --- a/test/server/tc_server.rb +++ b/test/server/tc_server.rb @@ -87,6 +87,7 @@ class TestServer < ServerTest :Handlers => { :CA => {}, # so that certs autogenerate :Master => { + :UseNodes => false, :File => file }, :Status => nil |