summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-10-10 20:54:15 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-10-10 20:54:15 +0000
commit194dab3c7af4d8e993ec8549a30773d68508a9b6 (patch)
treea2839d7fcaec754637fffa065b3bed387e2fabec
parent55d7bbdcbefd550cee46a628da2292be540401ad (diff)
downloadpuppet-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-xbin/puppetd9
-rw-r--r--lib/puppet/client.rb14
-rw-r--r--lib/puppet/parser/ast.rb26
-rw-r--r--lib/puppet/parser/grammar.ra2
-rw-r--r--lib/puppet/parser/parser.rb6
-rw-r--r--lib/puppet/parser/scope.rb104
-rw-r--r--lib/puppet/server/master.rb5
-rw-r--r--lib/puppet/server/servlet.rb19
-rw-r--r--lib/puppet/transportable.rb6
-rw-r--r--test/tagging/tc_tagging.rb2
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 {