summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/puppet/parser/ast.rb38
-rw-r--r--lib/puppet/parser/scope.rb33
-rw-r--r--lib/puppet/transportable.rb6
-rw-r--r--test/puppettest.rb2
-rw-r--r--test/tagging/tc_tagging.rb79
-rw-r--r--test/types/tc_service.rb28
6 files changed, 161 insertions, 25 deletions
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index 602067436..2848fd1fd 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -1030,14 +1030,15 @@ module Puppet
end
end
- # Define a new component. This basically just stores the associated parse
- # tree by name in our current scope. Note that there is currently
- # a mismatch in how we look up components -- it usually uses scopes, but
- # sometimes uses '@@settypes'.
+ # Define a new component. This basically just stores the
+ # associated parse tree by name in our current scope. Note that
+ # there is currently a mismatch in how we look up components -- it
+ # usually uses scopes, but sometimes uses '@@settypes'.
# FIXME This class should verify that each of its direct children
- # has an abstractable name -- i.e., if a file does not include a variable
- # in its name, then the user is essentially guaranteed to encounter
- # an error if the component is instantiated more than once.
+ # has an abstractable name -- i.e., if a file does not include a
+ # variable in its name, then the user is essentially guaranteed to
+ # encounter an error if the component is instantiated more than
+ # once.
class CompDef < AST::Branch
attr_accessor :name, :args, :code
@@ -1277,20 +1278,37 @@ module Puppet
# receive the arguments passed to the component and also the type and
# name of the component.
class Component < AST::Branch
+ class << self
+ attr_accessor :name
+ end
+
+ # The class name
+ @name = :component
+
attr_accessor :name, :args, :code
def evaluate(scope,hash,objtype,objname)
scope = scope.newscope
+
+ # The type is the component or class name
scope.type = objtype
+
+ # The name is the name the user has chosen or that has
+ # been dynamically generated. This is almost never used
scope.name = objname
+ # Additionally, add a tag for whatever kind of class
+ # we are
+ scope.base = self.class.name
+
+
# define all of the arguments in our local scope
if self.args
# Verify that all required arguments are either present or
# have been provided with defaults.
- # FIXME This should probably also require each parent class's
- # arguments...
+ # FIXME This should probably also require each parent
+ # class's arguments...
self.args.each { |arg, default|
unless hash.include?(arg)
if defined? default and ! default.nil?
@@ -1343,6 +1361,7 @@ module Puppet
# in that each class is a singleton -- only one will exist for a given
# node.
class HostClass < AST::Component
+ @name = :class
attr_accessor :parentclass
def evaluate(scope,hash,objtype,objname)
@@ -1412,6 +1431,7 @@ module Puppet
# The specific code associated with a host.
class Node < AST::Component
+ @name = :node
attr_accessor :name, :args, :code, :parentclass
def evaluate(scope, facts = {})
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index 054a0e7b7..e9ad983a1 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -8,7 +8,7 @@ module Puppet
class Scope
include Enumerable
attr_accessor :parent, :level, :interp
- attr_accessor :name, :type
+ attr_accessor :name, :type, :topscope, :base
# This is probably not all that good of an idea, but...
# This way a parent can share its node table with all of its children.
@@ -176,6 +176,7 @@ module Puppet
@nodescope = false
if @parent.nil?
+ # the level is mostly used for debugging
@level = 1
@@declarative = declarative
@@ -187,10 +188,14 @@ module Puppet
# of nodes with the same name in different sites. For now
# the top-level scope is always the only site scope.
@sitescope = true
+
+ # We're the top scope, so record that fact for our children
+ @topscope = self
else
@parent.child = self
@level = @parent.level + 1
@interp = @parent.interp
+ @topscope = @parent.topscope
end
# Our child scopes
@@ -484,6 +489,29 @@ module Puppet
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
+ end
+
+ return @tags.collect { |tag|
+ tag.to_s
+ }
+ end
+
# Convert our scope to a list of Transportable objects.
def to_trans
#Puppet.debug "Translating scope %s at level %s" %
@@ -517,6 +545,9 @@ module Puppet
@children.delete(child)
end
elsif child.is_a?(TransObject)
+ # Wait until the last minute to set tags, although this
+ # probably should not matter
+ child.tags = self.tags
results.push(child)
else
error = Puppet::DevError.new(
diff --git a/lib/puppet/transportable.rb b/lib/puppet/transportable.rb
index f50060d67..1f44f560a 100644
--- a/lib/puppet/transportable.rb
+++ b/lib/puppet/transportable.rb
@@ -9,6 +9,8 @@ module Puppet
class TransObject < Hash
attr_accessor :type, :name, :file, :line
+ attr_writer :tags
+
def initialize(name,type)
self[:name] = name
@type = type
@@ -20,6 +22,10 @@ module Puppet
return [self.type,self[:name]].join('--')
end
+ def tags
+ return @tags + [self.type, self.name]
+ end
+
def to_s
return "%s(%s) => %s" % [@type,self[:name],super]
end
diff --git a/test/puppettest.rb b/test/puppettest.rb
index 1ffad0833..8a93dcb7e 100644
--- a/test/puppettest.rb
+++ b/test/puppettest.rb
@@ -503,7 +503,7 @@ module FileTesting
end
end
-module PuppetTestSuite
+class PuppetTestSuite
attr_accessor :subdir
def self.list
diff --git a/test/tagging/tc_tagging.rb b/test/tagging/tc_tagging.rb
new file mode 100644
index 000000000..ab73ae866
--- /dev/null
+++ b/test/tagging/tc_tagging.rb
@@ -0,0 +1,79 @@
+if __FILE__ == $0
+ $:.unshift '..'
+ $:.unshift '../../lib'
+ $puppetbase = "../.."
+end
+
+require 'puppet'
+require 'puppettest'
+require 'test/unit'
+
+class TestTagging < Test::Unit::TestCase
+ include TestPuppet
+
+ # Make sure the scopes are getting the right tags
+ def test_scopetags
+ scope = nil
+ assert_nothing_raised {
+ scope = Puppet::Parser::Scope.new()
+ scope.name = "yayness"
+ scope.type = "solaris"
+ }
+
+ assert_nothing_raised {
+ assert_equal(%w{solaris}, scope.tags, "Incorrect scope tags")
+ }
+ end
+
+ # Test deeper tags
+ def test_deepscopetags
+ scope = nil
+ assert_nothing_raised {
+ scope = Puppet::Parser::Scope.new()
+ scope.name = "yayness"
+ scope.type = "solaris"
+ scope = scope.newscope
+ scope.name = "booness"
+ scope.type = "apache"
+ }
+
+ assert_nothing_raised {
+ assert_equal(%w{solaris apache}, scope.tags, "Incorrect scope tags")
+ }
+ end
+
+ # Verify that the tags make their way to the objects
+ def test_objecttags
+ scope = nil
+ assert_nothing_raised {
+ scope = Puppet::Parser::Scope.new()
+ scope.name = "yayness"
+ scope.type = "solaris"
+ }
+
+ assert_nothing_raised {
+ scope.setobject(
+ "file",
+ "/etc/passwd",
+ {"owner" => "root"},
+ "/yay",
+ 1
+ )
+ }
+
+ objects = nil
+ assert_nothing_raised {
+ objects = scope.to_trans
+ }
+
+ # There's only one object, so shift it out
+ object = objects.shift
+
+ assert_nothing_raised {
+ assert_equal(%w{solaris file /etc/passwd}, object.tags,
+ "Incorrect tags")
+ }
+ end
+end
+
+# $Id$
diff --git a/test/types/tc_service.rb b/test/types/tc_service.rb
index b2a919478..8f50aa931 100644
--- a/test/types/tc_service.rb
+++ b/test/types/tc_service.rb
@@ -75,18 +75,18 @@ class TestService < Test::Unit::TestCase
assert(sleeper.insync?)
end
- case Puppet::Type::Service.svctype
- when Puppet::ServiceTypes::InitSvc
- def test_processStartWithPattern
- sleeper = mksleeper(:pattern => "bin/sleeper")
-
- cyclesleeper(sleeper)
- end
-
- def test_processStartWithStatus
- sleeper = mksleeper(:hasstatus => true)
- cyclesleeper(sleeper)
- end
- #when Puppet::ServiceTypes::SMFSvc
- end
+ #case Puppet::Type::Service.svctype
+ #when Puppet::ServiceTypes::InitSvc
+ # def test_processStartWithPattern
+ # sleeper = mksleeper(:pattern => "bin/sleeper")
+#
+# cyclesleeper(sleeper)
+# end
+#
+# def test_processStartWithStatus
+# sleeper = mksleeper(:hasstatus => true)
+# cyclesleeper(sleeper)
+# end
+# #when Puppet::ServiceTypes::SMFSvc
+# end
end