An additional change needs to be made for this to work -- a "path" metaparameter also needs to be made, or the full path of the command will be required for the command in the unless statement.
Regards, -Roy On Wed, Sep 30, 2009 at 10:42 AM, Roy Nielsen <[email protected]> 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 > > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
