summaryrefslogtreecommitdiffstats
path: root/lib/puppet/util
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2007-08-24 18:31:00 -0500
committerLuke Kanies <luke@madstop.com>2007-08-24 18:31:00 -0500
commitc6e201cdd4ca5ee11a04cac77bf32faf40640b6d (patch)
tree7bcd93a091a327563d5641fb3c78aab548fed2fc /lib/puppet/util
parent520aaafbb87805a79283386e37deb4b3093a1144 (diff)
downloadpuppet-c6e201cdd4ca5ee11a04cac77bf32faf40640b6d.tar.gz
puppet-c6e201cdd4ca5ee11a04cac77bf32faf40640b6d.tar.xz
puppet-c6e201cdd4ca5ee11a04cac77bf32faf40640b6d.zip
I have added basic support for a search path, altho not yet with any ability to manipulate it. All config tests pass in both the old tests and the new ones, so it is time to add the hooks for manipulating the search path.
Diffstat (limited to 'lib/puppet/util')
-rw-r--r--lib/puppet/util/autoload.rb2
-rw-r--r--lib/puppet/util/config.rb278
2 files changed, 149 insertions, 131 deletions
diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb
index be9e14671..65cd3affb 100644
--- a/lib/puppet/util/autoload.rb
+++ b/lib/puppet/util/autoload.rb
@@ -150,5 +150,3 @@ class Puppet::Util::Autoload
[module_lib_dirs, Puppet[:libdir], $:].flatten
end
end
-
-# $Id$
diff --git a/lib/puppet/util/config.rb b/lib/puppet/util/config.rb
index 9ec777e99..27004cf41 100644
--- a/lib/puppet/util/config.rb
+++ b/lib/puppet/util/config.rb
@@ -16,39 +16,29 @@ class Puppet::Util::Config
# Retrieve a config value
def [](param)
- param = symbolize(param)
-
- # Yay, recursion.
- self.reparse() unless param == :filetimeout
-
- # Cache the returned values; this method was taking close to
- # 10% of the compile time.
- unless @returned[param]
- if @config.include?(param)
- if @config[param]
- @returned[param] = @config[param].value
- end
- else
- raise ArgumentError, "Undefined configuration parameter '%s'" % param
- end
- end
-
- return @returned[param]
+ value(param)
end
# Set a config value. This doesn't set the defaults, it sets the value itself.
def []=(param, value)
@@sync.synchronize do # yay, thread-safe
param = symbolize(param)
- unless @config.include?(param)
+ unless element = @config[param]
raise ArgumentError,
"Attempt to assign a value to unknown configuration parameter %s" % param.inspect
end
- unless @order.include?(param)
- @order << param
+ if element.respond_to?(:munge)
+ value = element.munge(value)
end
- @config[param].value = value
- @returned.clear
+ if element.respond_to?(:handle)
+ element.handle(value)
+ end
+ # Reset the name, so it's looked up again.
+ if param == :name
+ @name = nil
+ end
+ @values[:memory][param] = value
+ @values[:cache].clear
end
return value
@@ -57,7 +47,7 @@ class Puppet::Util::Config
# A simplified equality operator.
def ==(other)
self.each { |myname, myobj|
- unless other[myname] == myobj.value
+ unless other[myname] == value(myname)
return false
end
}
@@ -112,21 +102,42 @@ class Puppet::Util::Config
obj.clear
end
}
- @returned.clear
+ @values.each do |name, values|
+ next if name == :cli and exceptcli
+ @values.delete(name)
+ end
# Don't clear the 'used' in this case, since it's a config file reparse,
# and we want to retain this info.
unless exceptcli
@used = []
end
+
+ @name = nil
end
# This is mostly just used for testing.
def clearused
- @returned.clear
+ @values[:cache].clear
@used = []
end
+ # Do variable interpolation on the value.
+ def convert(value)
+ return value unless value
+ return value unless value.is_a? String
+ newval = value.gsub(/\$(\w+)|\$\{(\w+)\}/) do |value|
+ varname = $2 || $1
+ if pval = self.value(varname)
+ pval
+ else
+ raise Puppet::DevError, "Could not find value for %s" % parent
+ end
+ end
+
+ return newval
+ end
+
# Return a value's description.
def description(name)
if obj = @config[symbolize(name)]
@@ -137,29 +148,21 @@ class Puppet::Util::Config
end
def each
- @order.each { |name|
- if @config.include?(name)
- yield name, @config[name]
- else
- raise Puppet::DevError, "%s is in the order but does not exist" % name
- end
+ @config.each { |name, object|
+ yield name, object
}
end
# Iterate over each section name.
def eachsection
yielded = []
- @order.each { |name|
- if @config.include?(name)
- section = @config[name].section
- unless yielded.include? section
- yield section
- yielded << section
- end
- else
- raise Puppet::DevError, "%s is in the order but does not exist" % name
+ @config.each do |name, object|
+ section = object.section
+ unless yielded.include? section
+ yield section
+ yielded << section
end
- }
+ end
end
# Return an object by name.
@@ -178,16 +181,13 @@ class Puppet::Util::Config
str = newstr
bool = false
end
+ str = str.intern
if self.valid?(str)
if self.boolean?(str)
- self[str] = bool
+ @values[:cli][str] = bool
else
- self[str] = value
+ @values[:cli][str] = value
end
-
- # Mark that this was set on the cli, so it's not overridden if the
- # config gets reread.
- @config[str.intern].setbycli = true
else
raise ArgumentError, "Invalid argument %s" % opt
end
@@ -206,12 +206,17 @@ class Puppet::Util::Config
# Create a new config object
def initialize
- @order = []
@config = {}
@shortnames = {}
@created = []
- @returned = {}
+ @searchpath = nil
+
+ # Keep track of set values.
+ @values = Hash.new { |hash, key| hash[key] = {} }
+
+ # A central concept of a name.
+ @name = nil
end
# Return a given object's file metadata.
@@ -245,6 +250,23 @@ class Puppet::Util::Config
end
end
+ # Figure out our name.
+ def name
+ unless @name
+ unless @config[:name]
+ return nil
+ end
+ searchpath.each do |source|
+ next if source == :name
+ break if @name = @values[source][:name]
+ end
+ unless @name
+ @name = convert(@config[:name].default).intern
+ end
+ end
+ @name
+ end
+
# Return all of the parameters associated with a given section.
def params(section = nil)
if section
@@ -261,16 +283,18 @@ class Puppet::Util::Config
# Parse the configuration file.
def parse(file)
- configmap = parse_file(file)
+ clear(true)
- # We know we want the 'main' section
- if main = configmap[:main]
- set_parameter_hash(main)
+ parse_file(file).each do |area, values|
+ @values[area] = values
end
- # Otherwise, we only want our named section
- if @config.include?(:name) and named = configmap[symbolize(self[:name])]
- set_parameter_hash(named)
+ # We have to do it in the reverse of the search path,
+ # because multiple sections could set the same value.
+ searchpath.reverse.each do |source|
+ if meta = @values[source][:_meta]
+ set_metadata(meta)
+ end
end
end
@@ -335,7 +359,8 @@ class Puppet::Util::Config
# If the parameter is valid, then set it.
if section == Puppet[:name] and @config.include?(var)
- @config[var].value = value
+ #@config[var].value = value
+ @values[:main][var] = value
end
next
end
@@ -383,11 +408,12 @@ class Puppet::Util::Config
hash[:parent] = self
element = klass.new(hash)
- @order << element.name
-
return element
end
+ # This has to be private, because it doesn't add the elements to @config
+ private :newelement
+
# Iterate across all of the objects in a given section.
def persection(section)
section = symbolize(section)
@@ -419,6 +445,17 @@ class Puppet::Util::Config
end
end
+ # The order in which to search for values.
+ def searchpath(environment = nil)
+ # Start with a stupid list.
+ [:cache, :cli, :memory, :name, :main]
+# unless @searchpath
+# @searchpath = [:cache, :memory, :cli, :name, :main].collect do |source|
+# end
+# end
+# @searchpath
+ end
+
# Get a list of objects per section
def sectionlist
sectionlist = []
@@ -439,7 +476,7 @@ class Puppet::Util::Config
done ||= Hash.new { |hash, key| hash[key] = {} }
objects = []
persection(section) do |obj|
- if @config[:mkusers] and @config[:mkusers].value
+ if @config[:mkusers] and value(:mkusers)
[:owner, :group].each do |attr|
type = nil
if attr == :owner
@@ -487,7 +524,7 @@ class Puppet::Util::Config
end
if obj.respond_to? :to_transportable
- next if obj.value =~ /^\/dev/
+ next if value(obj.name) =~ /^\/dev/
transobjects = obj.to_transportable
transobjects = [transobjects] unless transobjects.is_a? Array
transobjects.each do |trans|
@@ -683,13 +720,41 @@ Generated on #{Time.now}.
@config.has_key?(param)
end
- def value(param)
+ def value(param, environment = nil)
param = symbolize(param)
- if obj = @config[param]
- obj.value
- else
- nil
+
+ # Short circuit to nil for undefined parameters.
+ return nil unless @config.include?(param)
+
+ # Yay, recursion.
+ self.reparse() unless param == :filetimeout
+
+ # See if we can find it within our searchable list of values
+ searchpath(environment).each do |source|
+ # Modify the source as necessary.
+ source = case source
+ when :name:
+ self.name
+ else
+ source
+ end
+
+ # Look for the value.
+ if @values[source].include?(param)
+ val = @values[source][param]
+ # Cache the value, because we do so many parameter lookups.
+ unless source == :cache
+ val = convert(val)
+ @values[:cache][param] = val
+ end
+ return val
+ end
end
+
+ # No normal source, so get the default and cache it
+ val = convert(@config[param].default)
+ @values[:cache][param] = val
+ return val
end
# Open a file with the appropriate user, group, and mode
@@ -718,7 +783,7 @@ Generated on #{Time.now}.
args << mode
- File.open(obj.value, *args) do |file|
+ File.open(value(obj.name), *args) do |file|
yield file
end
end
@@ -897,12 +962,13 @@ Generated on #{Time.now}.
self[param] = value
end
end
+ end
- if meta = params[:_meta]
- meta.each do |var, values|
- values.each do |param, value|
- @config[var].send(param.to_s + "=", value)
- end
+ # Set file metadata.
+ def set_metadata(meta)
+ meta.each do |var, values|
+ values.each do |param, value|
+ @config[var].send(param.to_s + "=", value)
end
end
end
@@ -917,22 +983,6 @@ Generated on #{Time.now}.
@value = nil
end
- # Do variable interpolation on the value.
- def convert(value)
- return value unless value
- return value unless value.is_a? String
- newval = value.gsub(/\$(\w+)|\$\{(\w+)\}/) do |value|
- varname = $2 || $1
- if pval = @parent[varname]
- pval
- else
- raise Puppet::DevError, "Could not find value for %s" % parent
- end
- end
-
- return newval
- end
-
def desc=(value)
@desc = value.gsub(/^\s*/, '')
end
@@ -1007,13 +1057,13 @@ Generated on #{Time.now}.
str += "# The default value is '%s'.\n" % @default
end
- line = "%s = %s" % [@name, self.value]
-
# If the value has not been overridden, then print it out commented
# and unconverted, so it's clear that that's the default and how it
# works.
- if defined? @value and ! @value.nil?
- line = "%s = %s" % [@name, self.value]
+ value = @parent.value(self.name)
+
+ if value != @default
+ line = "%s = %s" % [@name, value]
else
line = "# %s = %s" % [@name, @default]
end
@@ -1025,37 +1075,7 @@ Generated on #{Time.now}.
# Retrieves the value, or if it's not set, retrieves the default.
def value
- retval = nil
- if defined? @value and ! @value.nil?
- retval = @value
- elsif defined? @default
- retval = @default
- else
- return nil
- end
-
- if retval.is_a? String
- return convert(retval)
- else
- return retval
- end
- end
-
- # Set the value.
- def value=(value)
- if respond_to?(:validate)
- validate(value)
- end
-
- if respond_to?(:munge)
- @value = munge(value)
- else
- @value = value
- end
-
- if respond_to?(:handle)
- handle(@value)
- end
+ @parent.value(self.name)
end
end
@@ -1066,7 +1086,7 @@ Generated on #{Time.now}.
def group
if defined? @group
- return convert(@group)
+ return @parent.convert(@group)
else
return nil
end
@@ -1074,7 +1094,7 @@ Generated on #{Time.now}.
def owner
if defined? @owner
- return convert(@owner)
+ return @parent.convert(@owner)
else
return nil
end
@@ -1092,7 +1112,7 @@ Generated on #{Time.now}.
# Return the appropriate type.
def type
- value = self.value
+ value = @parent.value(self.name)
if @name.to_s =~ /dir/
return :directory
elsif value.to_s =~ /\/$/
@@ -1111,7 +1131,7 @@ Generated on #{Time.now}.
def to_transportable
type = self.type
return nil unless type
- path = self.value.split(File::SEPARATOR)
+ path = @parent.value(self.name).split(File::SEPARATOR)
path.shift # remove the leading nil
objects = []
@@ -1124,7 +1144,7 @@ Generated on #{Time.now}.
end
[:mode].each { |var|
if value = self.send(var)
- # Don't both converting the mode, since the file type
+ # Don't bother converting the mode, since the file type
# can handle it any old way.
obj[var] = value
end