diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/util/autoload.rb | 2 | ||||
-rw-r--r-- | lib/puppet/util/config.rb | 278 |
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 |