diff options
| author | Luke Kanies <luke@madstop.com> | 2007-08-22 18:07:52 -0500 |
|---|---|---|
| committer | Luke Kanies <luke@madstop.com> | 2007-08-22 18:07:52 -0500 |
| commit | b9f529a063cabb183966da29739cd924836eb67b (patch) | |
| tree | c0056176c2ff82d0fe90dfc6c97826f6d79917a6 | |
| parent | 0682d7e473cfd8f2fe6bee9eae0868b846fd0d50 (diff) | |
| parent | 282ec893ef895e0d386126ba70494a3b086030b9 (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-- | CHANGELOG | 2 | ||||
| -rw-r--r-- | examples/code/modules/sample-module.pp | 10 | ||||
| -rw-r--r-- | examples/code/modules/sample-module/README.txt | 17 | ||||
| -rw-r--r-- | examples/code/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb | 36 | ||||
| -rw-r--r-- | examples/code/modules/sample-module/manifests/init.pp | 12 | ||||
| -rw-r--r-- | examples/code/modules/sample-module/templates/sample.erb | 5 | ||||
| -rw-r--r-- | lib/puppet/util/autoload.rb | 8 | ||||
| -rw-r--r-- | lib/puppet/util/config.rb | 59 | ||||
| -rw-r--r-- | lib/puppet/util/suidmanager.rb | 1 | ||||
| -rw-r--r-- | test/lib/spec/version.rb | 56 | ||||
| -rwxr-xr-x | test/util/config.rb | 113 |
11 files changed, 254 insertions, 65 deletions
@@ -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$ |
