Hello,

Here's another shot at a tamed "unless" metaparameter..

Any help to test would be appreciated -

Regards,
-Roy

--- a/lib/puppet/type.rb        2009-10-02 16:04:43.000000000 -0600
+++ b/lib/puppet/type.rb        2009-10-02 16:04:06.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,39 @@
         end
     end

+    newcheckme(:unless) do
+        desc "If this parameter is set, then this ``exec`` 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 command requires the full path to the command.
+            "
+
+        validate do |cmds|
+            cmds = [cmds] unless cmds.is_a? Array
+
+            cmds.each do |cmd|
+                @resource.validateexecmd(cmd)
+            end
+        end
+
+        # Return true if the command does not return 0.
+        def check(value)
+            if self.checkme
+                output, status = @resource.runexe(value, true)
+            else
+                self.fail "Parameter empty"
+            end
+            return status.exitstatus != 0
+        end
+    end
+
     class RelationshipMetaparam < Puppet::Parameter
         class << self
             attr_accessor :direction, :events, :callback, :subclasses
@@ -1726,6 +1761,109 @@
     end

     ###############################
+    # All of the unless code.
+
+    def self.newcheckme(name, &block)
+        @checks ||= {}
+
+        check = newmetaparam(name, &block)
+        @checksme[name] = check
+    end
+
+    def self.checks
+        @checksme.keys
+    end
+
+    #
+    # Verify that we pass all of the checks.
+    #
+    def checkme
+        self.class.checksme.each { |check|
+            if @parameters.include?(check)
+                val = @parameters[check].value
+                val = [val] unless val.is_a? Array
+                val.each do |value|
+                    unless @parameters[check].check(value)
+                        return false
+                    end
+                end
+            end
+        }
+        return true
+    end
+
+    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,
+                "%s is somehow not qualified with no search path" %
+                    self[:command]
+        end
+    end
+
+    def runexe(command, check = false)
+        output = nil
+        status = nil
+
+        dir = nil
+
+        checkexec(command)
+
+        if dir = self[:cwd]
+            unless File.directory?(dir)
+                if check
+                    dir = nil
+                else
+                    self.fail "Working directory '%s' does not exist" % dir
+                end
+            end
+        end
+
+        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
-~----------~----~----~----~------~----~------~--~---

Reply via email to