I don't think this will quite work -- you want to define a 'check'  
parameter type, like exec does, and then modify some of the core  
system to actually run those checks.  This is currently done in the  
'returns' parameter of exec, but it should probably be moved into the  
Type's 'evaluate' method or something similar.

On Sep 30, 2009, at 9:42 AM, Roy Nielsen wrote:

> Hello,
>
> Below is a patch to the 0.25.1 rc1 /lib/puppet/type.rb file with the  
> code for an "unless" metaparameter.
>
> Unfortunately, I haven't had time (or the resources) to test it yet.
>
> Regards,
> -Roy
>
> --- a/lib/puppet/type.rb        2009-09-29 17:21:42.000000000 -0600
> +++ b/lib/puppet/type.rb        2009-09-30 10:21:14.000000000 -0600
> @@ -1259,6 +1259,44 @@
>          end
>      end
>
> +    newmetaparam(:unless) do
> +        desc "If this parameter is set in the package type, then  
> this ``package``
> +            will install unless the command returns 0 .  For  
> example::
> +
> +                 package { \"puppet.pkg.dmg\":
> +                    path => \"/usr/bin:/usr/sbin:/bin\",
> +                    unless => \"ps -acx | grep puppet 2>/dev/null\"
> +                 }
> +
> +            This would install the puppet.pkg.dmg package unless a  
> process
> +            containing the ``puppet`` string is found in the  
> process list.
> +
> +            Note that this command follows the same rules as the  
> exec command,
> +            which is to say that it must be fully qualified if the  
> path is not set.
> +                "
> +
> +        validate do |cmds|
> +            cmds = [cmds] unless cmds.is_a? Array
> +
> +            cmds.each do |cmd|
> +                @resource.validatecmd(cmd)
> +            end
> +        end
> +
> +        # Return true if the command does not return 0.
> +        def check(value)
> +            begin
> +                output, status = @resource.run(value, true)
> +            rescue Timeout::Error
> +                err "Check %s exceeded timeout" % value.inspect
> +                return false
> +            end
> +
> +            return status.exitstatus != 0
> +        end
> +    end
> +
> +
>      class RelationshipMetaparam < Puppet::Parameter
>          class << self
>              attr_accessor :direction, :events, :callback, :subclasses
> @@ -1726,6 +1764,116 @@
>      end
>
>      ###############################
> +    # All of the unless code.
> +
> +    def checkexe(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
> +        elsif path = self[:path]
> +            exe = cmd.split(/ /)[0]
> +            withenv :PATH => self[:path].join(":") do
> +                path = %{which #{exe}}.chomp
> +                if path == ""
> +                    raise ArgumentError,
> +                        "Could not find command '%s'" % exe
> +                end
> +            end
> +        else
> +            raise ArgumentError,
> +                "%s is somehow not qualified with no search path" %
> +                    self[:command]
> +        end
> +    end
> +
> +    def run(command, check = false)
> +        output = nil
> +        status = nil
> +
> +        dir = nil
> +
> +        checkexe(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 = {}
> +
> +                if self[:path]
> +                    environment[:PATH] = self[:path].join(":")
> +                end
> +
> +                if envlist = self[:environment]
> +                    envlist = [envlist] unless envlist.is_a? Array
> +                    envlist.each do |setting|
> +                        if setting =~ /^(\w+)=((.|\n)+)$/
> +                            name = $1
> +                            value = $2
> +                            if environment.include? name
> +                                warning(
> +                                "Overriding environment setting  
> '%s' with '%s'" %
> +                                    [name, value]
> +                                )
> +                            end
> +                            environment[name] = value
> +                        else
> +                            warning "Cannot understand environment  
> setting %s" % setting.inspect
> +                        end
> +                    end
> +                end
> +
> +                withenv environment do
> +                    Timeout::timeout(self[:timeout]) do
> +                        output, status =  
> Puppet::Util::SUIDManager.run_and_capture(
> +                            [command], self[:user], self[:group]
> +                        )
> +                    end
> +                    # 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 validatecmd(cmd)
> +        # if we're not fully qualified, require a path
> +        if cmd !~ /^\//
> +            if self[:path].nil?
> +                self.fail "'%s' is both unqualifed and specified no  
> search path" % cmd
> +            end
> +        end
> +    end
> +
> +    ###############################
>      # All of the scheduling code.
>
>      # Look up the schedule and set it appropriately.  This is done  
> after
>
>
> >


-- 
A gentleman is a man who can play the accordion but doesn't. --Unknown
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com


--~--~---------~--~----~------------~-------~--~----~
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