diff options
author | Luke Kanies <luke@madstop.com> | 2008-10-31 16:01:28 -0500 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2008-10-31 16:01:28 -0500 |
commit | e76cac7df102389b7ee487be4031caf0e7e2ab04 (patch) | |
tree | 0b9bd8d260613a5b41d9c72fa984065e5cb2d5f4 /lib/puppet | |
parent | 801b8a643d353176675023adaa25f26d0ec67403 (diff) | |
parent | f0635179b60f5cf30d1f7070f4c3c998ad5131c0 (diff) | |
download | puppet-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.rb | 3 | ||||
-rw-r--r-- | lib/puppet/parameter.rb | 2 | ||||
-rw-r--r-- | lib/puppet/parser/ast/astarray.rb | 3 | ||||
-rw-r--r-- | lib/puppet/parser/ast/hostclass.rb | 7 | ||||
-rw-r--r-- | lib/puppet/parser/lexer.rb | 5 | ||||
-rw-r--r-- | lib/puppet/parser/parser_support.rb | 6 | ||||
-rw-r--r-- | lib/puppet/provider/augeas/augeas.rb | 189 | ||||
-rw-r--r-- | lib/puppet/type/augeas.rb | 150 | ||||
-rw-r--r-- | lib/puppet/type/k5login.rb | 2 | ||||
-rwxr-xr-x | lib/puppet/type/mount.rb | 2 | ||||
-rwxr-xr-x | lib/puppet/type/tidy.rb | 22 | ||||
-rw-r--r-- | lib/puppet/util/log.rb | 17 |
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) |