summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2007-08-22 18:07:52 -0500
committerLuke Kanies <luke@madstop.com>2007-08-22 18:07:52 -0500
commitb9f529a063cabb183966da29739cd924836eb67b (patch)
treec0056176c2ff82d0fe90dfc6c97826f6d79917a6
parent0682d7e473cfd8f2fe6bee9eae0868b846fd0d50 (diff)
parent282ec893ef895e0d386126ba70494a3b086030b9 (diff)
Merging the multi_env branch with master. There are not actually any conflicts, so this commit might only be necessary because I did not pull sufficiently often.
-rw-r--r--CHANGELOG2
-rw-r--r--examples/code/modules/sample-module.pp10
-rw-r--r--examples/code/modules/sample-module/README.txt17
-rw-r--r--examples/code/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb36
-rw-r--r--examples/code/modules/sample-module/manifests/init.pp12
-rw-r--r--examples/code/modules/sample-module/templates/sample.erb5
-rw-r--r--lib/puppet/util/autoload.rb8
-rw-r--r--lib/puppet/util/config.rb59
-rw-r--r--lib/puppet/util/suidmanager.rb1
-rw-r--r--test/lib/spec/version.rb56
-rwxr-xr-xtest/util/config.rb113
11 files changed, 254 insertions, 65 deletions
diff --git a/CHANGELOG b/CHANGELOG
index f51e1f3c6..27aa0fa5e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,6 @@
0.23.2 (misspiggy)
+ Added shortname support to config.rb and refactored addargs
+
Fixed the problem in cron jobs where environment settings
tended to multiple. (#749)
diff --git a/examples/code/modules/sample-module.pp b/examples/code/modules/sample-module.pp
new file mode 100644
index 000000000..57079a0aa
--- /dev/null
+++ b/examples/code/modules/sample-module.pp
@@ -0,0 +1,10 @@
+# Jeff McCune <jeff.mccune@northstarlabs.net>
+# 2007-08-14
+#
+# Use:
+# puppet --verbose --debug --modulepath=`pwd` ./sample-module.pp
+#
+# sample-module demonstrates the use of a custom language function
+# included within the module bundle.
+
+include sample-module
diff --git a/examples/code/modules/sample-module/README.txt b/examples/code/modules/sample-module/README.txt
new file mode 100644
index 000000000..ee4b8201a
--- /dev/null
+++ b/examples/code/modules/sample-module/README.txt
@@ -0,0 +1,17 @@
+Jeff McCune <jeff.mccune@northstarlabs.net>
+2007-08-14
+
+This small, sample module demonstrates how to extend the puppet language
+with a new parser function.
+
+See:
+manifests/init.pp
+lib/puppet/parser/functions/hostname_to_dn.rb
+templates/sample.erb
+
+Note the consistent naming of files for Puppet::Util::Autoload
+
+Reference Documents:
+http://reductivelabs.com/trac/puppet/wiki/ModuleOrganisation
+http://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions
+http://reductivelabs.com/trac/puppet/wiki/FunctionReference
diff --git a/examples/code/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb b/examples/code/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb
new file mode 100644
index 000000000..9f732b5bc
--- /dev/null
+++ b/examples/code/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb
@@ -0,0 +1,36 @@
+# Copyright (C) David Schmitt <david@schmitt.edv-bus.at>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the Author nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+# Jeff McCune <jeff.mccune@northstarlabs.net>
+# 2007-08-14
+# See: http://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions
+
+module Puppet::Parser::Functions
+ newfunction(:hostname_to_dn, :type => :rvalue, :doc => "Given 'foo.bar.com', return 'dc=foo,dc=bar,dc=com'.") do |args|
+ args[0].split(/\./).map do |s| "dc=%s"%[s] end.join(",")
+ end
+end
diff --git a/examples/code/modules/sample-module/manifests/init.pp b/examples/code/modules/sample-module/manifests/init.pp
new file mode 100644
index 000000000..1af8dff1f
--- /dev/null
+++ b/examples/code/modules/sample-module/manifests/init.pp
@@ -0,0 +1,12 @@
+# Jeff McCune <jeff.mccune@northstarlabs.net>
+#
+# Demonstration of a custom parser function and erb template within
+# a module, working in concert.
+
+class sample-module {
+ $fqdn_to_dn = hostname_to_dn($domain)
+ $sample_template = template("sample-module/sample.erb")
+
+ notice("hostname_to_dn module function returned: [$fqdn_to_dn]")
+ info("sample.erb looks like:\n$sample_template")
+}
diff --git a/examples/code/modules/sample-module/templates/sample.erb b/examples/code/modules/sample-module/templates/sample.erb
new file mode 100644
index 000000000..b13561b45
--- /dev/null
+++ b/examples/code/modules/sample-module/templates/sample.erb
@@ -0,0 +1,5 @@
+
+## Jeff McCune <jeff.mccune@northstarlabs.net>
+fqdn: <%= fqdn %>
+basedn: <%= fqdn_to_dn %>
+## end sample.erb ##
diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb
index 42aa56c32..be9e14671 100644
--- a/lib/puppet/util/autoload.rb
+++ b/lib/puppet/util/autoload.rb
@@ -141,7 +141,13 @@ class Puppet::Util::Autoload
# The list of directories to search through for loadable plugins.
def searchpath
- [Puppet[:libdir], $:].flatten
+ # JJM: Search for optional lib directories in each module bundle.
+ module_lib_dirs = Puppet[:modulepath].split(":").collect do |d|
+ Dir.glob("%s/*/lib" % d).select do |f|
+ FileTest.directory?(f)
+ end
+ end.flatten
+ [module_lib_dirs, Puppet[:libdir], $:].flatten
end
end
diff --git a/lib/puppet/util/config.rb b/lib/puppet/util/config.rb
index 6d42f0ea6..932314215 100644
--- a/lib/puppet/util/config.rb
+++ b/lib/puppet/util/config.rb
@@ -1,6 +1,8 @@
require 'puppet'
require 'sync'
require 'puppet/transportable'
+require 'getoptlong'
+
# The class for handling configuration files.
class Puppet::Util::Config
@@ -67,19 +69,12 @@ class Puppet::Util::Config
# 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'
-
# Hackish, but acceptable. Copy the current ARGV for restarting.
Puppet.args = ARGV.dup
# 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
+ self.each { |name, element|
+ element.getopt_args.each { |args| options << args }
}
return options
@@ -195,10 +190,17 @@ class Puppet::Util::Config
@config.include?(name)
end
+ # check to see if a short name is already defined
+ def shortinclude?(short)
+ short = short.intern if name.is_a? String
+ @shortnames.include?(short)
+ end
+
# Create a new config object
def initialize
@order = []
@config = {}
+ @shortnames = {}
@created = []
@returned = {}
@@ -499,7 +501,14 @@ class Puppet::Util::Config
if @config.include?(name)
raise Puppet::Error, "Parameter %s is already defined" % name
end
- @config[name] = newelement(hash)
+ tryconfig = newelement(hash)
+ if short = tryconfig.short
+ if other = @shortnames[short]
+ raise ArgumentError, "Parameter %s is already using short name '%s'" % [other.name, short]
+ end
+ @shortnames[short] = tryconfig
+ end
+ @config[name] = tryconfig
}
end
@@ -858,7 +867,7 @@ Generated on #{Time.now}.
# The base element type.
class CElement
attr_accessor :name, :section, :default, :parent, :setbycli
- attr_reader :desc
+ attr_reader :desc, :short
# Unset any set value.
def clear
@@ -885,6 +894,15 @@ Generated on #{Time.now}.
@desc = value.gsub(/^\s*/, '')
end
+ # get the arguments in getopt format
+ def getopt_args
+ if short
+ [["--#{name}", "-#{short}", GetoptLong::REQUIRED_ARGUMENT]]
+ else
+ [["--#{name}", GetoptLong::REQUIRED_ARGUMENT]]
+ end
+ end
+
def hook=(block)
meta_def :handle, &block
end
@@ -929,6 +947,14 @@ Generated on #{Time.now}.
end
end
+ # short name for the celement
+ def short=(value)
+ if value.to_s.length != 1
+ raise ArgumentError, "Short names can only be one character."
+ end
+ @short = value.to_s
+ end
+
# Convert the object to a config statement.
def to_config
str = @desc.gsub(/^/, "# ") + "\n"
@@ -1101,6 +1127,17 @@ Generated on #{Time.now}.
# A simple boolean.
class CBoolean < CElement
+ # get the arguments in getopt format
+ def getopt_args
+ if short
+ [["--#{name}", "-#{short}", GetoptLong::NO_ARGUMENT],
+ ["--no-#{name}", GetoptLong::NO_ARGUMENT]]
+ else
+ [["--#{name}", GetoptLong::NO_ARGUMENT],
+ ["--no-#{name}", GetoptLong::NO_ARGUMENT]]
+ end
+ end
+
def munge(value)
case value
when true, "true": return true
diff --git a/lib/puppet/util/suidmanager.rb b/lib/puppet/util/suidmanager.rb
index e15656d77..c1ff66248 100644
--- a/lib/puppet/util/suidmanager.rb
+++ b/lib/puppet/util/suidmanager.rb
@@ -1,5 +1,6 @@
require 'facter'
require 'puppet/util/warnings'
+require 'forwardable'
module Puppet::Util::SUIDManager
include Puppet::Util::Warnings
diff --git a/test/lib/spec/version.rb b/test/lib/spec/version.rb
index a0c0fdbbe..e692a87ee 100644
--- a/test/lib/spec/version.rb
+++ b/test/lib/spec/version.rb
@@ -1,30 +1,30 @@
-module Spec
- module VERSION
- def self.build_tag
- tag = "REL_" + [MAJOR, MINOR, TINY].join('_')
- if defined?(RELEASE_CANDIDATE)
- tag << "_" << RELEASE_CANDIDATE
- end
- tag
- end
-
- unless defined? MAJOR
- MAJOR = 0
- MINOR = 8
- TINY = 2
- # RELEASE_CANDIDATE = "RC1"
-
+module Spec
+ module VERSION
+ def self.build_tag
+ tag = "REL_" + [MAJOR, MINOR, TINY].join('_')
+ if defined?(RELEASE_CANDIDATE)
+ tag << "_" << RELEASE_CANDIDATE
+ end
+ tag
+ end
+
+ unless defined? MAJOR
+ MAJOR = 0
+ MINOR = 8
+ TINY = 2
+ # RELEASE_CANDIDATE = "RC1"
+
# RANDOM_TOKEN: 0.375509844656552
- REV = "LastChangedRevision: 2283".match(/LastChangedRevision: (\d+)/)[1]
-
- STRING = [MAJOR, MINOR, TINY].join('.')
- FULL_VERSION = "#{STRING} (r#{REV})"
- TAG = build_tag
-
- NAME = "RSpec"
- URL = "http://rspec.rubyforge.org/"
-
- DESCRIPTION = "#{NAME}-#{FULL_VERSION} - BDD for Ruby\n#{URL}"
- end
- end
+ REV = "$LastChangedRevision: 2283$".match(/LastChangedRevision: (\d+)/)[1]
+
+ STRING = [MAJOR, MINOR, TINY].join('.')
+ FULL_VERSION = "#{STRING} (r#{REV})"
+ TAG = build_tag
+
+ NAME = "RSpec"
+ URL = "http://rspec.rubyforge.org/"
+
+ DESCRIPTION = "#{NAME}-#{FULL_VERSION} - BDD for Ruby\n#{URL}"
+ end
+ end
end
diff --git a/test/util/config.rb b/test/util/config.rb
index 71343556f..9a1017058 100755
--- a/test/util/config.rb
+++ b/test/util/config.rb
@@ -10,6 +10,8 @@ require 'puppettest/parsertesting'
class TestConfig < Test::Unit::TestCase
include PuppetTest
include PuppetTest::ParserTesting
+ CElement = Puppet::Util::Config::CElement
+ CBoolean = Puppet::Util::Config::CBoolean
def setup
super
@@ -535,34 +537,46 @@ yay = /a/path
}
end
- def test_argadding
- c = mkconfig
-
- assert_nothing_raised {
- @config.setdefaults("testing",
- :onboolean => [true, "An on bool"],
- :offboolean => [false, "An off bool"],
- :string => ["a string", "A string arg"],
- :file => ["/path/to/file", "A file arg"]
- )
- }
- options = []
-
- @config.addargs(options)
+ def test_addargs
+ @config.setdefaults("testing",
+ :onboolean => [true, "An on bool"],
+ :offboolean => [false, "An off bool"],
+ :string => ["a string", "A string arg"],
+ :file => ["/path/to/file", "A file arg"]
+ )
+
+ should = []
+ @config.each { |name, element|
+ element.expects(:getopt_args).returns([name])
+ should << name
+ }
+ result = []
+ assert_nothing_raised("Add args failed") do
+ @config.addargs(result)
+ end
+ assert_equal(should, result, "Did not call addargs correctly.")
- @config.each { |param, obj|
- opt = "--%s" % param
- assert(options.find { |ary|
- ary[0] == opt
- }, "Argument %s was not added" % opt)
+ end
- if @config.boolean?(param)
- o = "--no-%s" % param
- assert(options.find { |ary|
- ary[0] == o
- }, "Boolean off %s was not added" % o)
+ def test_addargs_functional
+ @config.setdefaults("testing",
+ :onboolean => [true, "An on bool"],
+ :string => ["a string", "A string arg"]
+ )
+ result = []
+ should = []
+ assert_nothing_raised("Add args failed") do
+ @config.addargs(result)
+ end
+ @config.each do |name, element|
+ if name == :onboolean
+ should << ["--onboolean", GetoptLong::NO_ARGUMENT]
+ should << ["--no-onboolean", GetoptLong::NO_ARGUMENT]
+ elsif name == :string
+ should << ["--string", GetoptLong::REQUIRED_ARGUMENT]
end
- }
+ end
+ assert_equal(should, result, "Add args functional test failed")
end
def test_usesection
@@ -1243,6 +1257,55 @@ inttest = 27
# And make sure other params are unchanged
assert_equal("unval", @config[:unchanged], "Unchanged value has somehow changed")
end
+
+ # Test to make sure that we can set and get a short name
+ def test_celement_short_name
+ element = nil
+ assert_nothing_raised("Could not create celement") do
+ element = CElement.new :short => "n", :desc => "anything"
+ end
+ assert_equal("n", element.short, "Short value is not retained")
+
+ assert_raise(ArgumentError,"Allowed multicharactered short names.") do
+ element = CElement.new :short => "no", :desc => "anything"
+ end
+ end
+
+ # Test to make sure that no two celements have the same short name
+ def test_celement_short_name_not_duplicated
+ config = mkconfig
+ assert_nothing_raised("Could not create celement with short name.") do
+ config.setdefaults(:main,
+ :one => { :default => "blah", :desc => "anything", :short => "o" })
+ end
+ assert_nothing_raised("Could not create second celement with short name.") do
+ config.setdefaults(:main,
+ :two => { :default => "blah", :desc => "anything", :short => "i" })
+ end
+ assert_raise(ArgumentError, "Could create second celement with duplicate short name.") do
+ config.setdefaults(:main,
+ :three => { :default => "blah", :desc => "anything", :short => "i" })
+ end
+ # make sure that when the above raises an expection that the config is not included
+ assert(!config.include?(:three), "Invalid configuration item was retained")
+ end
+
+ # Tell getopt which arguments are valid
+ def test_get_getopt_args
+ element = CElement.new :name => "foo", :desc => "anything"
+ assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
+
+ element.short = "n"
+ assert_equal([["--foo", "-n", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
+
+ element = CBoolean.new :name => "foo", :desc => "anything"
+ assert_equal([["--foo", GetoptLong::NO_ARGUMENT], ["--no-foo", GetoptLong::NO_ARGUMENT]],
+ element.getopt_args, "Did not produce appropriate getopt args")
+
+ element.short = "n"
+ assert_equal([["--foo", "-n", GetoptLong::NO_ARGUMENT],["--no-foo", GetoptLong::NO_ARGUMENT]],
+ element.getopt_args, "Did not produce appropriate getopt args")
+ end
end
# $Id$