summaryrefslogtreecommitdiffstats
path: root/lib/puppet/config.rb
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-02-07 23:12:33 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-02-07 23:12:33 +0000
commitb98e65f1fd858a1d0af415554db49a121a76232c (patch)
tree728f94dd17f88902c6bdf21ff6b17486babb08af /lib/puppet/config.rb
parentf1ffc34c0927840beeb21e1e2d864ce14de5d15e (diff)
downloadpuppet-b98e65f1fd858a1d0af415554db49a121a76232c.tar.gz
puppet-b98e65f1fd858a1d0af415554db49a121a76232c.tar.xz
puppet-b98e65f1fd858a1d0af415554db49a121a76232c.zip
There is now full support for configuration files, and the entire system has been modified to expect their new behaviour. I have not yet run the test across all test hosts, though.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@873 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib/puppet/config.rb')
-rw-r--r--lib/puppet/config.rb222
1 files changed, 194 insertions, 28 deletions
diff --git a/lib/puppet/config.rb b/lib/puppet/config.rb
index 295bf2035..010473dbf 100644
--- a/lib/puppet/config.rb
+++ b/lib/puppet/config.rb
@@ -5,23 +5,22 @@ class Config
# Retrieve a config value
def [](param)
- param = param.intern unless param.is_a? Symbol
+ param = convert(param)
if @config.include?(param)
if @config[param]
val = @config[param].value
return val
end
else
- nil
+ raise ArgumentError, "Invalid argument %s" % param
end
end
# Set a config value. This doesn't set the defaults, it sets the value itself.
def []=(param, value)
- param = param.intern unless param.is_a? Symbol
+ param = convert(param)
unless @config.include?(param)
- raise Puppet::Error, "Unknown configuration parameter %s" % param
- #@config[param] = newelement(param, value)
+ raise Puppet::Error, "Unknown configuration parameter %s" % param.inspect
end
unless @order.include?(param)
@order << param
@@ -40,6 +39,47 @@ class Config
return true
end
+ # Generate the list of valid arguments, in a format that GetoptLong can
+ # understand, and add them to the passed option list.
+ def addargs(options)
+ require 'getoptlong'
+ # Add all of the config parameters as valid options.
+ self.each { |param, obj|
+ if self.boolean?(param)
+ options << ["--#{param}", GetoptLong::NO_ARGUMENT]
+ options << ["--no-#{param}", GetoptLong::NO_ARGUMENT]
+ else
+ options << ["--#{param}", GetoptLong::REQUIRED_ARGUMENT]
+ end
+ }
+
+ return options
+ end
+
+ # Turn the config into a transaction and apply it
+ def apply
+ trans = self.to_transportable
+ begin
+ comp = trans.to_type
+ trans = comp.evaluate
+ trans.evaluate
+ comp.remove
+ rescue => detail
+ puts detail.backtrace
+ Puppet.err "Could not configure myself: %s" % detail
+ end
+ end
+
+ # Is our parameter a boolean parameter?
+ def boolean?(param)
+ param = convert(param)
+ if @config.include?(param) and @config[param].kind_of? CBoolean
+ return true
+ else
+ return false
+ end
+ end
+
# Remove all set values.
def clear
@config.each { |name, obj|
@@ -47,6 +87,15 @@ class Config
}
end
+ def convert(param)
+ case param
+ when String: return param.intern
+ when Symbol: return param
+ else
+ raise ArgumentError, "Invalid param type %s" % param.class
+ end
+ end
+
def each
@order.each { |name|
if @config.include?(name)
@@ -75,10 +124,40 @@ class Config
# Return an object by name.
def element(param)
- param = param.intern unless param.is_a? Symbol
+ param = convert(param)
@config[param]
end
+ # Handle a command-line argument.
+ def handlearg(opt, value = nil)
+ if value == "true"
+ value = true
+ end
+ if value == "false"
+ value = false
+ end
+ str = opt.sub(/^--/,'')
+ bool = true
+ newstr = str.sub(/^no-/, '')
+ if newstr != str
+ str = newstr
+ bool = false
+ end
+ if self.valid?(str)
+ if self.boolean?(str)
+ self[str] = bool
+ else
+ self[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
+ end
+
# Create a new config object
def initialize
@order = []
@@ -87,6 +166,7 @@ class Config
# Return all of the parameters associated with a given section.
def params(section)
+ section = section.intern if section.is_a? String
@config.find_all { |name, obj|
obj.section == section
}.collect { |name, obj|
@@ -134,8 +214,13 @@ class Config
values[section][var.to_s] = value
next
end
- Puppet.info "%s: Setting %s to '%s'" % [section, var, value]
- self[var] = value
+
+ # Don't override set parameters, since the file is parsed
+ # after cli arguments are handled.
+ unless @config.include?(var) and @config[var].setbycli
+ Puppet.debug "%s: Setting %s to '%s'" % [section, var, value]
+ self[var] = value
+ end
@config[var].section = section
metas.each { |meta|
@@ -155,6 +240,7 @@ class Config
# what kind of element we're creating, but the value itself might be either
# a default or a value, so we can't actually assign it.
def newelement(param, desc, value)
+ param = convert(param)
mod = nil
case value
when true, false, "true", "false":
@@ -171,9 +257,12 @@ class Config
element.extend(mod)
end
+ @order << param
+
return element
end
+ # Iterate across all of the objects in a given section.
def persection(section)
self.each { |name, obj|
if obj.section == section
@@ -221,7 +310,13 @@ class Config
}
if obj.respond_to? :to_transportable
- objects << obj.to_transportable
+ unless done[:file].include? obj.value
+ trans = obj.to_transportable
+ # transportable could return nil
+ next unless trans
+ objects << trans
+ done[:file] << obj.value
+ end
end
}
@@ -241,6 +336,7 @@ class Config
section = section.intern unless section.is_a? Symbol
#hash.each { |param, value|
defs.each { |param, value, desc|
+ param = convert(param)
if @config.include?(param) and @config[param].default
raise Puppet::Error, "Default %s is already defined" % param
end
@@ -260,11 +356,27 @@ class Config
# Convert our list of objects into a configuration file.
def to_config
- str = ""
+ str = %{The configuration file for #{Puppet.name}. Note that this file
+is likely to have unused configuration parameters in it; any parameter that's
+valid anywhere in Puppet can be in any config file, even if it's not used.
+
+Every section can specify three special parameters: owner, group, and mode.
+These parameters affect the required permissions of any files specified after
+their specification. Puppet will sometimes use these parameters to check its
+own configured state, so they can be used to make Puppet a bit more self-managing.
+
+Note also that the section names are entirely for human-level organizational
+purposes; they don't provide separate namespaces. All parameters are in a
+single namespace.
+
+Generated on #{Time.now}.
+
+}.gsub(/^/, "# ")
+
eachsection do |section|
str += "[#{section}]\n"
persection(section) do |obj|
- str += obj.to_s + "\n"
+ str += obj.to_config + "\n"
end
end
@@ -276,6 +388,7 @@ class Config
done = {
:owner => [],
:group => [],
+ :file => []
}
topbucket = Puppet::TransBucket.new
@@ -299,12 +412,23 @@ class Config
# Convert to a parseable manifest
def to_manifest
transport = self.to_transportable
- return transport.to_manifest
+
+ manifest = transport.to_manifest + "\n"
+ eachsection { |section|
+ manifest += "include #{section}\n"
+ }
+
+ return manifest
+ end
+
+ def valid?(param)
+ param = convert(param)
+ @config.has_key?(param)
end
# The base element type.
class CElement
- attr_accessor :name, :section, :default, :parent, :desc
+ attr_accessor :name, :section, :default, :parent, :desc, :setbycli
# Unset any set value.
def clear
@@ -314,15 +438,43 @@ class Config
# Create the new element. Pretty much just sets the name.
def initialize(name, desc, value = nil)
@name = name
- @desc = desc
+ @desc = desc.gsub(/^\s*/, '')
if value
@value = value
end
end
- def to_s
- str = @desc.gsub(/^/, " # ") +
- "\n %s = %s" % [@name, self.value]
+ def set?
+ if defined? @value and ! @value.nil?
+ return true
+ else
+ return false
+ end
+ end
+
+ # Convert the object to a config statement.
+ def to_config
+ str = @desc.gsub(/^/, "# ") + "\n"
+
+ # Add in a statement about the default.
+ if defined? @default and @default
+ 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]
+ else
+ line = "# %s = %s" % [@name, @default]
+ end
+
+ str += line + "\n"
+
+ str.gsub(/^/, " ")
end
# Retrieves the value, or if it's not set, retrieves the default.
@@ -358,12 +510,11 @@ class Config
# A file.
module CFile
- attr_accessor :owner, :group, :mode, :type
+ attr_accessor :owner, :group, :mode
def convert(value)
- unless value
- return nil
- end
+ return value unless value
+ return value unless value.is_a? String
if value =~ /\$(\w+)/
parent = $1
if pval = @parent[parent]
@@ -380,20 +531,33 @@ class Config
# Set the type appropriately. Yep, a hack. This supports either naming
# the variable 'dir', or adding a slash at the end.
def munge(value)
- if value.to_s =~ /dir/
- @type = :directory
- elsif value =~ /\/$/
+ if value.to_s =~ /\/$/
@type = :directory
return value.sub(/\/$/, '')
- else
- @type = :file
end
return value
end
+ # Return the appropriate type.
+ def type
+ value = self.value
+ if @name.to_s =~ /dir/
+ return :directory
+ elsif value.to_s =~ /\/$/
+ return :directory
+ elsif value.is_a? String
+ return :file
+ else
+ return nil
+ end
+ end
+
+ # Convert the object to a TransObject instance.
def to_transportable
+ type = self.type
+ return nil unless type
obj = Puppet::TransObject.new(self.value, "file")
- obj[:ensure] = self.type
+ obj[:ensure] = type
[:owner, :group, :mode].each { |var|
if value = self.send(var)
obj[var] = value
@@ -407,6 +571,7 @@ class Config
# Make sure any provided variables look up to something.
def validate(value)
+ return true unless value.is_a? String
value.scan(/\$(\w+)/) { |name|
name = name[0]
unless @parent[name]
@@ -423,7 +588,8 @@ class Config
when true, "true": return true
when false, "false": return false
else
- raise Puppet::Error, "Invalid value %s for %s" % [value, @name]
+ raise Puppet::Error, "Invalid value '%s' for %s" %
+ [value.inspect, @name]
end
end
end