diff options
author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-10-10 20:54:15 +0000 |
---|---|---|
committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-10-10 20:54:15 +0000 |
commit | 194dab3c7af4d8e993ec8549a30773d68508a9b6 (patch) | |
tree | a2839d7fcaec754637fffa065b3bed387e2fabec | |
parent | 55d7bbdcbefd550cee46a628da2292be540401ad (diff) | |
download | puppet-194dab3c7af4d8e993ec8549a30773d68508a9b6.tar.gz puppet-194dab3c7af4d8e993ec8549a30773d68508a9b6.tar.xz puppet-194dab3c7af4d8e993ec8549a30773d68508a9b6.zip |
Adding some semantic tagging. It is not exactly full-featured yet, and it is not used at all, but it was sufficient for some proof-of-concept stuff in preparation for the conference
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@716 980ebf18-57e1-0310-9a29-db15c13687c0
-rwxr-xr-x | bin/puppetd | 9 | ||||
-rw-r--r-- | lib/puppet/client.rb | 14 | ||||
-rw-r--r-- | lib/puppet/parser/ast.rb | 26 | ||||
-rw-r--r-- | lib/puppet/parser/grammar.ra | 2 | ||||
-rw-r--r-- | lib/puppet/parser/parser.rb | 6 | ||||
-rw-r--r-- | lib/puppet/parser/scope.rb | 104 | ||||
-rw-r--r-- | lib/puppet/server/master.rb | 5 | ||||
-rw-r--r-- | lib/puppet/server/servlet.rb | 19 | ||||
-rw-r--r-- | lib/puppet/transportable.rb | 6 | ||||
-rw-r--r-- | test/tagging/tc_tagging.rb | 2 |
10 files changed, 155 insertions, 38 deletions
diff --git a/bin/puppetd b/bin/puppetd index c7ab08304..aba1ebe79 100755 --- a/bin/puppetd +++ b/bin/puppetd @@ -208,7 +208,12 @@ end client.setcerts # and then retrieve and apply our configuration -client.getconfig -client.apply +begin + client.getconfig + client.apply +rescue => detail + Puppet.err detail.to_s + exit(13) +end # $Id$ diff --git a/lib/puppet/client.rb b/lib/puppet/client.rb index 53a61920f..ac2ec420c 100644 --- a/lib/puppet/client.rb +++ b/lib/puppet/client.rb @@ -61,10 +61,14 @@ module Puppet msg = "Could not connect to %s on port %s" % [@host, @port] #Puppet.err msg raise NetworkClientError, msg - #rescue => detail - # Puppet.err "Could not call %s.%s: %s" % - # [namespace, method, detail.inspect] - # raise NetworkClientError.new(detail.to_s) + rescue SocketError => detail + Puppet.err "Could not find server %s" % @puppetserver + exit(12) + rescue => detail + Puppet.err "Could not call %s.%s: %s" % + [namespace, method, detail.inspect] + #raise NetworkClientError.new(detail.to_s) + raise end } } @@ -96,6 +100,8 @@ module Puppet hash[:Server] ||= "localhost" hash[:Port] ||= Puppet[:masterport] + @puppetserver = hash[:Server] + super( hash[:Server], hash[:Path], diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb index 2848fd1fd..fa21f8a9e 100644 --- a/lib/puppet/parser/ast.rb +++ b/lib/puppet/parser/ast.rb @@ -1436,7 +1436,14 @@ module Puppet def evaluate(scope, facts = {}) scope = scope.newscope - scope.type = "node" + + # nodes are never instantiated like a normal object, + # but we need the type to be the name users would use for + # instantiation, otherwise tags don't work out + + # The name has already been evaluated, so it's a normal + # string. + scope.type = @name scope.name = @name # Mark this scope as a nodescope, so that classes will be @@ -1469,15 +1476,24 @@ module Puppet # We also can't just evaluate the node itself, because # it would create a node scope within this scope, # and that would cause mass havoc. - hash = nil + node = nil + + # The 'node' method just returns a hash of the node + # code and name. It's used here, and in 'evalnode'. unless hash = scope.node(@parentclass) raise Puppet::ParseError, "Could not find parent node %s" % @parentclass end + node = hash[:node] + # Tag the scope with the parent's name/type. + name = node.name + Puppet.info "Tagging with parent node %s" % name + scope.tag(name) + begin - code = hash[:node].code + code = node.code code.safeevaluate(scope) rescue Puppet::ParseError => except except.line = self.line @@ -1489,6 +1505,10 @@ module Puppet error.file = self.file raise error end + + if node.parentclass + node.evalparent(scope) + end end end diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra index 5fe801e15..96f043365 100644 --- a/lib/puppet/parser/grammar.ra +++ b/lib/puppet/parser/grammar.ra @@ -450,7 +450,7 @@ import: IMPORT QTEXT { parser.files = self.files Puppet.debug("importing '%s'" % file) begin - parser.file = file + parser.file = File.join(dir, file) rescue Puppet::ImportError Puppet.warning( "Importing %s would result in an import loop" % diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb index 733de138c..fd570a81c 100644 --- a/lib/puppet/parser/parser.rb +++ b/lib/puppet/parser/parser.rb @@ -32,7 +32,7 @@ module Puppet class Parser < Racc::Parser -module_eval <<'..end grammar.ra modeval..idb211ea7fd3', 'grammar.ra', 638 +module_eval <<'..end grammar.ra modeval..id0af758a138', 'grammar.ra', 638 attr_reader :file attr_accessor :files @@ -145,7 +145,7 @@ end def string=(string) @lexer.string = string end -..end grammar.ra modeval..idb211ea7fd3 +..end grammar.ra modeval..id0af758a138 ##### racc 1.4.4 generates ### @@ -1122,7 +1122,7 @@ module_eval <<'.,.,', 'grammar.ra', 469 parser.files = self.files Puppet.debug("importing '%s'" % file) begin - parser.file = file + parser.file = File.join(dir, file) rescue Puppet::ImportError Puppet.warning( "Importing %s would result in an import loop" % diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb index e9ad983a1..73c2e8f96 100644 --- a/lib/puppet/parser/scope.rb +++ b/lib/puppet/parser/scope.rb @@ -27,6 +27,40 @@ module Puppet @@declarative = val end + # Add a single object's tags to the global list of tags for + # that object. + def addtags(obj) + unless defined? @tagtable + raise Puppet::DevError, "Told to add tags, but no tag table" + end + list = @tagtable[obj.type][obj.name] + + obj.tags.each { |tag| + unless list.include?(tag) + if tag.nil? or tag == "" + Puppet.warning "Got tag %s from %s(%s)" % + [tag.inspect, obj.type, obj.name] + else + list << tag + end + end + } + end + + # Log the existing tags. At some point this should be in a better + # place, but eh. + def logtags + @tagtable.sort { |a, b| + a[0] <=> b[0] + }.each { |type, names| + names.sort { |a, b| + a[0] <=> b[0] + }.each { |name, tags| + Puppet.info "%s(%s): '%s'" % [type, name, tags.join("' '")] + } + } + end + # Create a new child scope. def child=(scope) @children.push(scope) @@ -129,11 +163,16 @@ module Puppet # And now return the whole thing #return self.to_trans - return self.to_trans + objects = self.to_trans + + # I should do something to add the node as an object with tags + # but that will possibly end up with far too many tags. + self.logtags + return objects end - # Retrieve a specific node. This is basically only used from within - # 'findnode'. + # Retrieve a specific node. This is used in ast.rb to find a + # parent node and in findnode to retrieve and evaluate a node. def node(name) @nodetable[name] end @@ -175,6 +214,8 @@ module Puppet @parent = parent @nodescope = false + @tags = [] + if @parent.nil? # the level is mostly used for debugging @level = 1 @@ -191,6 +232,14 @@ module Puppet # We're the top scope, so record that fact for our children @topscope = self + + # And create a tag table, so we can collect all of the tags + # associated with any objects created in this scope tree + @tagtable = Hash.new { |types, type| + types[type] = Hash.new { |names, name| + names[name] = [] + } + } else @parent.child = self @level = @parent.level + 1 @@ -489,27 +538,37 @@ module Puppet end end + # Add a tag to our current list. This is only currently used + # when nodes evaluate their parents. + def tag(*ary) + ary.each { |tag| + if tag.nil? or tag == "" + Puppet.warning "got told to tag with %s" % tag.inspect + end + unless @tags.include?(tag) + @tags << tag.to_s + end + } + end + # Return the tags associated with this scope. It's basically # just our parents' tags, plus our type. def tags - unless defined? @tags - @tags = [] - if @parent - @tags += @parent.tags - end - - # Add our type to the tag list - @tags << @type - - # We could add the base (e.g., node or class) to the - # tags, but for now, we're not going to - - # We also don't add the name + tmp = [] + @tags + unless @type.nil? or @type == "" + tmp << @type.to_s end - - return @tags.collect { |tag| - tag.to_s - } + if @parent + @parent.tags.each { |tag| + if tag.nil? or tag == "" + Puppet.warning "parent returned tag %s" % tag.inspect + end + unless tmp.include?(tag) + tmp << tag + end + } + end + return tmp end # Convert our scope to a list of Transportable objects. @@ -548,6 +607,11 @@ module Puppet # Wait until the last minute to set tags, although this # probably should not matter child.tags = self.tags + + # Then make sure this child's tags are stored in the + # central table. This should maybe be in the evaluate + # methods, but, eh. + @topscope.addtags(child) results.push(child) else error = Puppet::DevError.new( diff --git a/lib/puppet/server/master.rb b/lib/puppet/server/master.rb index 03ff7c6ac..d5dc6bc22 100644 --- a/lib/puppet/server/master.rb +++ b/lib/puppet/server/master.rb @@ -77,6 +77,11 @@ class Server Puppet.debug("Running interpreter") begin retobjects = @interpreter.run(client, facts) + rescue Puppet::Error => detail + Puppet.err detail + raise XMLRPC::FaultException.new( + 1, detail.to_s + ) rescue => detail Puppet.err detail.to_s return "" diff --git a/lib/puppet/server/servlet.rb b/lib/puppet/server/servlet.rb index e35a1d518..ce962b4ea 100644 --- a/lib/puppet/server/servlet.rb +++ b/lib/puppet/server/servlet.rb @@ -116,9 +116,22 @@ class Server ) end - #if request.client_cert - # Puppet.info "client cert is %s" % request.client_cert - #end + # If they have a certificate (which will almost always be true) + # then we get the hostname from the cert, instead of via IP + # info + if cert = request.client_cert + name = cert.subject + #Puppet.info name.inspect + if name.to_s =~ /CN=(\w+)/ + Puppet.info "Overriding %s with cert name %s" % + [@client, $1] + @client = $1 + else + Puppet.warning "Could not match against %s(%s)" % + [name, name.class] + end + #Puppet.info "client cert is %s" % request.client_cert + end #if request.server_cert # Puppet.info "server cert is %s" % @request.server_cert #end diff --git a/lib/puppet/transportable.rb b/lib/puppet/transportable.rb index 1f44f560a..d86e775cd 100644 --- a/lib/puppet/transportable.rb +++ b/lib/puppet/transportable.rb @@ -23,7 +23,7 @@ module Puppet end def tags - return @tags + [self.type, self.name] + return @tags + [@type, @name] end def to_s @@ -42,6 +42,10 @@ module Puppet raise Puppet::Error.new("Could not find object type %s" % self.type) end + if defined? @tags and @tags + Puppet.warning "%s(%s) tags: %s" % [@type, @name, @tags.join(" ")] + end + return retobj end end diff --git a/test/tagging/tc_tagging.rb b/test/tagging/tc_tagging.rb index ab73ae866..a3bc9592b 100644 --- a/test/tagging/tc_tagging.rb +++ b/test/tagging/tc_tagging.rb @@ -25,7 +25,7 @@ class TestTagging < Test::Unit::TestCase } end - # Test deeper tags + # Test deeper tags, where a scope gets all of its parent scopes' tags def test_deepscopetags scope = nil assert_nothing_raised { |