Hello, I was able to do some basic testing for the patch below, when the unless metaparameter is used, the puppet run exits with an error (used self.fail).
I'm not sure how to upload the tests, I watched James Turnbull's "Puppet Release Manager Developing for Puppet" talk on: http://coursestream.sfsu.edu/ess/feed?id=e723afa9-1748-43c7-8231-180d2a7f7d3e&type=MP3, but the online slides didn't show the changing git part of the presentation (didn't show an automation?). I used the following resources (on a mac) to test: $cron_found = "Did not find the cron process" file { "/tmp/cronFound": unless => "/bin/ps -ef | /usr/bin/grep cron | grep -v grep", path => '/tmp/cronFound', content => $cron_found } The cron process is always running, so the command returns 0, so file should not be created, and the puppet process on the client will exit with an error. $garbage_found = "Did not find the garbageProcess process" file { "/tmp/garbageFound": unless => "/bin/ps -ef | /usr/bin/grep garbageProcess | grep -v grep", path => '/tmp/garbageFound', content => $garbage_found } There should be no garbageProcess running, so the command returns != 0, so file should be created. Thoughts? It would be nice to be able to "skip" a resource if the command returned 0, but I'm not sure how to do that (still working on understanding the code). Regards, -Roy --- a/lib/puppet/type.rb 2009-10-02 16:04:43.000000000 -0600 +++ b/lib/puppet/type.rb 2009-10-08 14:46:09.000000000 -0600 @@ -13,6 +13,7 @@ require 'puppet/util/cacher' require 'puppet/file_collection/lookup' require 'puppet/util/tagging' +require 'puppet/util/execution' # see the bottom of the file for the rest of the inclusions @@ -25,6 +26,7 @@ include Puppet::Util::Cacher include Puppet::FileCollection::Lookup include Puppet::Util::Tagging + include Puppet::Util::Execution ############################### # Code related to resource type attributes. @@ -1259,6 +1261,44 @@ end end + def self.newcheckme(myname, &block) + @checksme ||= {} + + check = newmetaparam(myname, &block) + @checksme[myname] = check + end + + def self.checks + @checksme.keys + end + + newcheckme(:unless) do + desc "If this parameter is set, then the type will run unless + the command returns 0. For example:: + + exec { \"/bin/echo root >> /usr/lib/cron/cron.allow\": + unless => \"/usr/bin/grep root /usr/lib/cron/cron.allow 2>/dev/null\" + } + + This would add ``root`` to the cron.allow file (on Solaris) unless + ``grep`` determines it's already there. + + Note that this metaparameter requires the full path to the command. + " + + munge do |cmds| + cmds = [cmds] unless cmds.is_a? Array + + cmds.each do |cmd| + @resource.validateexecmd(cmd) + output, status = @resource.runexec(cmd, true) + if status.exitstatus == 0 + self.fail("Unless returned 0 with command: %s" % [cmd]) + end + end + end + end + class RelationshipMetaparam < Puppet::Parameter class << self attr_accessor :direction, :events, :callback, :subclasses @@ -1726,6 +1766,69 @@ end ############################### + # All of the unless code. + + def checkexec(cmd) + if cmd =~ /^\// + exe = cmd.split(/ /)[0] + unless FileTest.exists?(exe) + raise ArgumentError, "Could not find executable %s" % exe + end + unless FileTest.executable?(exe) + raise ArgumentError, + "%s is not executable" % exe + end + else + raise ArgumentError, + "is somehow not qualified with no search path" + end + end + + def runexec(command, check = false) + output = nil + status = nil + + dir = nil + + checkexec(command) + + dir ||= Dir.pwd + + if check + debug "Executing check '#{command}'" + else + debug "Executing '#{command}'" + end + begin + # Do our chdir + Dir.chdir(dir) do + environment = {} + + withenv environment do + output, status = Puppet::Util::SUIDManager.run_and_capture( + [command] + ) + # The shell returns 127 if the command is missing. + if status.exitstatus == 127 + raise ArgumentError, output + end + end + end + rescue Errno::ENOENT => detail + self.fail detail.to_s + end + + return output, status + end + + def validateexecmd(cmd) + # if we're not fully qualified, require a path + if cmd !~ /^\// + self.fail "'%s' is both unqualifed and specified no search path" % cmd + end + end + + ############################### # All of the scheduling code. # Look up the schedule and set it appropriately. This is done after --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en -~----------~----~----~----~------~----~------~--~---
