summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-10-31 16:01:28 -0500
committerLuke Kanies <luke@madstop.com>2008-10-31 16:01:28 -0500
commite76cac7df102389b7ee487be4031caf0e7e2ab04 (patch)
tree0b9bd8d260613a5b41d9c72fa984065e5cb2d5f4 /lib/puppet
parent801b8a643d353176675023adaa25f26d0ec67403 (diff)
parentf0635179b60f5cf30d1f7070f4c3c998ad5131c0 (diff)
downloadpuppet-e76cac7df102389b7ee487be4031caf0e7e2ab04.tar.gz
puppet-e76cac7df102389b7ee487be4031caf0e7e2ab04.tar.xz
puppet-e76cac7df102389b7ee487be4031caf0e7e2ab04.zip
Merge branch '0.24.x'
Conflicts: CHANGELOG
Diffstat (limited to 'lib/puppet')
-rw-r--r--lib/puppet/feature/base.rb3
-rw-r--r--lib/puppet/parameter.rb2
-rw-r--r--lib/puppet/parser/ast/astarray.rb3
-rw-r--r--lib/puppet/parser/ast/hostclass.rb7
-rw-r--r--lib/puppet/parser/lexer.rb5
-rw-r--r--lib/puppet/parser/parser_support.rb6
-rw-r--r--lib/puppet/provider/augeas/augeas.rb189
-rw-r--r--lib/puppet/type/augeas.rb150
-rw-r--r--lib/puppet/type/k5login.rb2
-rwxr-xr-xlib/puppet/type/mount.rb2
-rwxr-xr-xlib/puppet/type/tidy.rb22
-rw-r--r--lib/puppet/util/log.rb17
12 files changed, 384 insertions, 24 deletions
diff --git a/lib/puppet/feature/base.rb b/lib/puppet/feature/base.rb
index 518e9b419..0b12d730a 100644
--- a/lib/puppet/feature/base.rb
+++ b/lib/puppet/feature/base.rb
@@ -22,3 +22,6 @@ Puppet.features.add(:mongrel, :libs => %w{rubygems mongrel puppet/network/http_s
# We have lcs diff
Puppet.features.add :diff, :libs => %w{diff/lcs diff/lcs/hunk}
+
+# We have augeas
+Puppet.features.add(:augeas, :libs => ["augeas"])
diff --git a/lib/puppet/parameter.rb b/lib/puppet/parameter.rb
index f90193fc8..06dfe5b91 100644
--- a/lib/puppet/parameter.rb
+++ b/lib/puppet/parameter.rb
@@ -63,7 +63,7 @@ class Puppet::Parameter
end
unless regs.empty?
@doc += " Values can also match ``" +
- regs.join("``, ``") + "``."
+ regs.collect { |r| r.inspect }.join("``, ``") + "``."
end
end
diff --git a/lib/puppet/parser/ast/astarray.rb b/lib/puppet/parser/ast/astarray.rb
index 8f09aa922..0fccbca75 100644
--- a/lib/puppet/parser/ast/astarray.rb
+++ b/lib/puppet/parser/ast/astarray.rb
@@ -30,10 +30,9 @@ class Puppet::Parser::AST
items << child
end
}
-
rets = items.flatten.collect { |child|
child.safeevaluate(scope)
- }
+ }.flatten
return rets.reject { |o| o.nil? }
end
diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb
index 7f89f8151..4f5c4797c 100644
--- a/lib/puppet/parser/ast/hostclass.rb
+++ b/lib/puppet/parser/ast/hostclass.rb
@@ -56,7 +56,12 @@ class Puppet::Parser::AST::HostClass < Puppet::Parser::AST::Definition
# Don't create a subscope for the top-level class, since it already
# has its own scope.
- scope = subscope(scope, resource) unless resource.title == :main
+ unless resource.title == :main
+ scope = subscope(scope, resource)
+
+ scope.setvar("title", resource.title)
+ scope.setvar("name", resource.name)
+ end
# Add the parent scope namespaces to our own.
if pnames
diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb
index 9226434da..dd6c29d9f 100644
--- a/lib/puppet/parser/lexer.rb
+++ b/lib/puppet/parser/lexer.rb
@@ -157,6 +157,11 @@ class Puppet::Parser::Lexer
TOKENS.add_token :COMMENT, %r{#.*}, :skip => true
+ TOKENS.add_token :MLCOMMENT, %r{/\*(.*?)\*/}m do |lexer, value|
+ lexer.line += value.count("\n")
+ [nil,nil]
+ end
+
TOKENS.add_token :RETURN, "\n", :skip => true, :incr_line => true, :skip_text => true
TOKENS.add_token :SQUOTE, "'" do |lexer, value|
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index 853d6aa86..1583973a7 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -291,10 +291,14 @@ class Puppet::Parser::Parser
if tmp == ""
tmp = "main"
end
-
+
Puppet.debug addcontext("Adding code to %s" % tmp)
# Else, add our code to it.
if other.code and code
+ # promote if neededcodes to ASTArray so that we can append code
+ # ASTArray knows how to evaluate its members.
+ other.code = ast AST::ASTArray, :children => [other.code] unless other.code.is_a?(AST::ASTArray)
+ code = ast AST::ASTArray, :children => [code] unless code.is_a?(AST::ASTArray)
other.code.children += code.children
else
other.code ||= code
diff --git a/lib/puppet/provider/augeas/augeas.rb b/lib/puppet/provider/augeas/augeas.rb
new file mode 100644
index 000000000..cadbd667b
--- /dev/null
+++ b/lib/puppet/provider/augeas/augeas.rb
@@ -0,0 +1,189 @@
+#--
+# Copyright (C) 2008 Red Hat Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Author: Bryan Kearney <bkearney@redhat.com>
+
+require 'augeas' if Puppet.features.augeas?
+
+Puppet::Type.type(:augeas).provide(:augeas) do
+#class Puppet::Provider::Augeas < Puppet::Provider
+ include Puppet::Util
+
+ confine :true => Puppet.features.augeas?
+
+ has_features :parse_commands, :need_to_run?,:execute_changes
+
+ # Extracts an 2 dimensional array of commands which are in the
+ # form of command path value.
+ # The input can be
+ # - A string with one command
+ # - A string with many commands per line
+ # - An array of strings.
+ def parse_commands(data)
+ commands = Array.new()
+ if data.is_a?(String)
+ data.each_line do |line|
+ cmd_array = Array.new()
+ tokens = line.split(" ")
+ cmd = tokens.shift()
+ file = tokens.shift()
+ other = tokens.join(" ")
+ cmd_array << cmd if !cmd.nil?
+ cmd_array << file if !file.nil?
+ cmd_array << other if other != ""
+ commands << cmd_array
+ end
+ elsif data.is_a?(Array)
+ data.each do |datum|
+ commands.concat(parse_commands(datum))
+ end
+ end
+
+ return commands
+ end
+
+ def open_augeas
+ flags = 0
+ (flags = 1 << 2 ) if self.resource[:type_check] == :true
+ root = self.resource[:root]
+ load_path = self.resource[:load_path]
+ debug("Opening augeas with root #{root}, lens path #{load_path}, flags #{flags}")
+ Augeas.open(root, load_path,flags)
+ end
+
+ # Used by the need_to_run? method to process get filters. Returns
+ # true if there is a match, false if otherwise
+ # Assumes a syntax of get /files/path [COMPARATOR] value
+ def process_get(cmd_array)
+ return_value = false
+
+ #validate and tear apart the command
+ fail ("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length < 4
+ cmd = cmd_array.shift()
+ path = cmd_array.shift()
+ comparator = cmd_array.shift()
+ arg = cmd_array.join(" ")
+
+ #check the value in augeas
+ aug = open_augeas()
+ result = aug.get(path) || ''
+ unless result.nil?
+ case comparator
+ when "!=":
+ return_value = true if !(result == arg)
+ when "=~":
+ regex = Regexp.new(arg)
+ loc = result=~ regex
+ return_value = true if ! loc.nil?
+ else
+ return_value = true if (result.send(comparator, arg))
+ end
+ end
+ return_value
+ end
+
+ # Used by the need_to_run? method to process match filters. Returns
+ # true if there is a match, false if otherwise
+ def process_match(cmd_array)
+ return_value = false
+
+ #validate and tear apart the command
+ fail("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length < 4
+ cmd = cmd_array.shift()
+ path = cmd_array.shift()
+ verb = cmd_array.shift()
+
+ #Get the values from augeas
+ aug = open_augeas()
+ result = aug.match(path) || ''
+ # Now do the work
+ if (!result.nil?)
+ case verb
+ when "size":
+ fail("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length != 2
+ comparator = cmd_array.shift()
+ arg = cmd_array.shift().to_i
+ return_value = true if (result.size.send(comparator, arg))
+ when "include":
+ arg = cmd_array.join(" ")
+ return_value = true if result.include?(arg)
+ when "==":
+ begin
+ arg = cmd_array.join(" ")
+ new_array = eval arg
+ return_value = true if result == new_array
+ rescue
+ fail("Invalid array in command: #{cmd_array.join(" ")}")
+ end
+ end
+ end
+ return_value
+ end
+
+ # Determines if augeas acutally needs to run.
+ def need_to_run?
+ return_value = true
+ filter = resource[:onlyif]
+ unless (filter == "")
+ cmd_array = filter.split
+ command = cmd_array[0];
+ cmd_array[1]= File.join(resource[:context], cmd_array[1])
+ begin
+ data = nil
+ case command
+ when "get" then return_value = process_get(cmd_array)
+ when "match" then return_value = process_match(cmd_array)
+ end
+ rescue Exception => e
+ fail("Error sending command '#{command}' with params #{cmd_array[1..-1].inspect}/#{e.message}")
+ end
+ end
+ return_value
+ end
+
+ # Actually execute the augeas changes.
+ def execute_changes
+ aug = open_augeas
+ commands = resource[:changes]
+ context = resource[:context]
+ commands.each do |cmd_array|
+ fail("invalid command #{cmd_array.join[" "]}") if cmd_array.length < 2
+ command = cmd_array[0]
+ cmd_array.shift()
+ cmd_array[0]=File.join(context, cmd_array[0])
+ debug("sending command '#{command}' with params #{cmd_array.inspect}")
+ begin
+ case command
+ when "set": aug.set(cmd_array[0], cmd_array[1])
+ when "rm", "remove": aug.rm(cmd_array[0])
+ when "clear": aug.clear(cmd_array[0])
+ when "insert", "ins": aug.insert(cmd_array[0])
+ else fail("Command '#{command}' is not supported")
+ end
+ rescue Exception => e
+ fail("Error sending command '#{command}' with params #{cmd_array.inspect}/#{e.message}")
+ end
+ end
+ success = aug.save()
+ if (success != true)
+ fail("Save failed with return code #{success}")
+ end
+
+ return :executed
+ end
+
+end
diff --git a/lib/puppet/type/augeas.rb b/lib/puppet/type/augeas.rb
new file mode 100644
index 000000000..61339407b
--- /dev/null
+++ b/lib/puppet/type/augeas.rb
@@ -0,0 +1,150 @@
+#--
+# Copyright (C) 2008 Red Hat Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Publicretu
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Author: Bryan Kearney <bkearney@redhat.com>
+
+Puppet::Type.newtype(:augeas) do
+ include Puppet::Util
+
+ feature :parse_commands, "Parse the command string"
+ feature :need_to_run?, "If the command should run"
+ feature :execute_changes, "Actually make the changes"
+
+ @doc = "Apply the changes (single or array of changes) to the filesystem
+ via the augeas tool.
+
+ Requires:
+ - augeas to be installed (http://www.augeas.net)
+ - ruby-augeas bindings
+
+ Sample usage with a string:
+ augeas{\"test1\" :
+ context => \"/files/etc/sysconfig/firstboot\",
+ changes => \"set RUN_FIRSTBOOT YES\",
+ onlyif => \"match other_value size > 0\",
+ }
+
+ Sample usage with an array and custom lenses:
+ augeas{\"jboss_conf\":
+ context => \"/files\",
+ changes => [
+ \"set /etc/jbossas/jbossas.conf/JBOSS_IP $ipaddress\",
+ \"set /etc/jbossas/jbossas.conf/JAVA_HOME /usr\"
+ ],
+ load_path => \"$/usr/share/jbossas/lenses\",
+ }
+ "
+
+ newparam (:name) do
+ desc "The name of this task. Used for uniqueness"
+ isnamevar
+ end
+
+ newparam (:context) do
+ desc "Optional context path. This value is pre-pended to the paths of all changes"
+ defaultto ""
+ end
+
+ newparam (:onlyif) do
+ desc "Optional augeas command and comparisons to control the execution of this type.
+ Supported onlyif syntax:
+ get [AUGEAS_PATH] [COMPARATOR] [STRING]
+ match [MATCH_PATH] size [COMPARATOR] [INT]
+ match [MATCH_PATH] include [STRING]
+ match [MATCH_PATH] == [AN_ARRAY]
+
+ where
+ AUGEAS_PATH is a valid path scoped by the context
+ MATCH_PATH is a valid match synatx scoped by the context
+ COMPARATOR is in the set [> >= != == <= <]
+ STRING is a string
+ INT is a number
+ AN_ARRAY is in the form ['a string', 'another'] "
+ defaultto ""
+ end
+
+
+ newparam(:changes) do
+ desc "The changes which should be applied to the filesystem. This
+ can be either a string which contains a command or an array of commands.
+ Commands supported are:
+
+ set [PATH] [VALUE] Sets the value VALUE at loction PATH
+ rm [PATH] Removes the node at location PATH
+ remove [PATH] Synonym for rm
+ clear [PATH] Keeps the node at PATH, but removes the value.
+ ins [PATH] Inserts an empty node at PATH.
+ insert [PATH] Synonym for ins
+
+ If the parameter 'context' is set that that value is prepended to PATH"
+
+ munge do |value|
+ provider.parse_commands(value)
+ end
+ end
+
+
+ newparam(:root) do
+ desc "A file system path; all files loaded by Augeas are loaded underneath ROOT"
+ defaultto "/"
+ end
+
+ newparam(:load_path) do
+ desc "Optional colon separated list of directories; these directories are searched for schema definitions"
+ defaultto ""
+ end
+
+
+ newparam(:type_check) do
+ desc "Set to true if augeas should perform typechecking. Optional, defaults to false"
+ newvalues(:true, :false)
+
+ defaultto :false
+ end
+
+ # This is the acutal meat of the code. It forces
+ # augeas to be run and fails or not based on the augeas return
+ # code.
+ newproperty(:returns) do |property|
+ include Puppet::Util
+ desc "The expected return code from the augeas command. Should not be set"
+
+ defaultto 0
+
+ # Make output a bit prettier
+ def change_to_s(currentvalue, newvalue)
+ return "executed successfully"
+ end
+
+ # if the onlyif resource is provided, then the value is parsed.
+ # a return value of 0 will stop exection becuase it matches the
+ # default value.
+ def retrieve
+ if @resource.provider.need_to_run?()
+ :need_to_run
+ else
+ 0
+ end
+ end
+
+ # Actually execute the command.
+ def sync
+ @resource.provider.execute_changes()
+ end
+ end
+
+end
diff --git a/lib/puppet/type/k5login.rb b/lib/puppet/type/k5login.rb
index 2372f658a..d22be11b7 100644
--- a/lib/puppet/type/k5login.rb
+++ b/lib/puppet/type/k5login.rb
@@ -46,7 +46,7 @@ Puppet::Type.newtype(:k5login) do
write(@resource.should(:principals))
should_mode = @resource.should(:mode)
unless self.mode == should_mode
- self.mode should_mode
+ self.mode = should_mode
end
end
diff --git a/lib/puppet/type/mount.rb b/lib/puppet/type/mount.rb
index 1679b73a3..4eb149488 100755
--- a/lib/puppet/type/mount.rb
+++ b/lib/puppet/type/mount.rb
@@ -143,7 +143,7 @@ module Puppet
desc "Whether to dump the mount. Not all platforms
support this. Valid values are ``1`` or ``0``. Default is ``0``."
- newvalue(%r{(0|1)}) { }
+ newvalue(%r{(0|1)})
defaultto {
if @resource.managed?
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index fe8bde9ab..c352ec85b 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -2,7 +2,10 @@ module Puppet
newtype(:tidy, :parent => Puppet.type(:file)) do
@doc = "Remove unwanted files based on specific criteria. Multiple
criteria are OR'd together, so a file that is too large but is not
- old enough will still get tidied."
+ old enough will still get tidied.
+
+ You must specify either the size or age of the file (or both) for
+ files to be tidied."
newparam(:path) do
desc "The path to the file or directory to manage. Must be fully
@@ -249,6 +252,23 @@ module Puppet
newparam(:recurse) do
desc "If target is a directory, recursively descend
into the directory looking for files to tidy."
+
+ newvalues(:true, :false, :inf, /^[0-9]+$/)
+
+ # Replace the validation so that we allow numbers in
+ # addition to string representations of them.
+ validate { |arg| }
+ munge do |value|
+ newval = super(value)
+ case newval
+ when :true, :inf: true
+ when :false: false
+ when Integer, Fixnum, Bignum: value
+ when /^\d+$/: Integer(value)
+ else
+ raise ArgumentError, "Invalid recurse value %s" % value.inspect
+ end
+ end
end
newparam(:rmdirs) do
diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb
index 0dfd36dfa..b57faad42 100644
--- a/lib/puppet/util/log.rb
+++ b/lib/puppet/util/log.rb
@@ -369,11 +369,7 @@ class Puppet::Util::Log
end
def handle(msg)
- # Only add messages from objects, since anything else is
- # probably unrelated to this run.
- if msg.objectsource?
- @report.newlog(msg)
- end
+ @report.newlog(msg)
end
end
@@ -505,15 +501,6 @@ class Puppet::Util::Log
Log.newmessage(self)
end
- # Was the source of this log a Puppet resource or parameter?
- def objectsource?
- if defined? @objectsource and @objectsource
- @objectsource
- else
- false
- end
- end
-
# If they pass a source in to us, we make sure it is a string, and
# we retrieve any tags we can.
def source=(source)
@@ -521,10 +508,8 @@ class Puppet::Util::Log
# We can't just check for whether it responds to :path, because
# plenty of providers respond to that in their normal function.
if (source.is_a?(Puppet::Type) or source.is_a?(Puppet::Parameter)) and source.respond_to?(:path)
- @objectsource = true
@source = source.path
else
- @objectsource = false
@source = source.to_s
end
if source.respond_to?(:tags)