Permalink
Browse files

[utils] Updates `wait_for` provider to include a way to skip the requ…

…est based on regex
  • Loading branch information...
ashrithr committed Mar 20, 2014
1 parent 56165b8 commit 227dcf47b7d71446ed73b9a1521b565b25f8d70d
Showing with 82 additions and 1 deletion.
  1. +4 −0 utils/lib/puppet/provider/wait_for/ruby.rb
  2. +78 −1 utils/lib/puppet/type/wait_for.rb
@@ -40,6 +40,9 @@ def regex=(regex)
info "polling frequency #{@polling_frequency}, max retries #{@max_retries}"
error_message = "wait_for timed out while waiting until the output of #{@query} matched #{regex}, after #{@max_retries} retries with polling frequency #{@polling_frequency}."
query_and_wait(error_message) do |exit_code, output|
+ unless @giveup_regex.nil?
+ return if output =~ @giveup_regex
+ end
if output =~ regex
info "Query output matched regex."
return regex
@@ -54,6 +57,7 @@ def fetch_parameters
@query = resource[:query]
@polling_frequency = resource[:polling_frequency]
@max_retries = resource[:max_retries]
+ @giveup_regex = resource[:giveup_regex]
end
def query_and_wait(error_message)
@@ -3,7 +3,77 @@
Puppet::Type.newtype(:wait_for) do
@doc = "Waits for something to happen."
- newparam(:query, :namevar => true) do
+ # Borrowed from `exec` resource to implement `refreshonly`
+ # Create a new check mechanism. It's basically just a parameter that
+ # provides one extra 'check' method.
+ def self.newcheck(name, options = {}, &block)
+ @checks ||= {}
+
+ check = newparam(name, options, &block)
+ @checks[name] = check
+ end
+
+ def self.checks
+ @checks.keys
+ end
+
+ newcheck(:refreshonly) do
+ desc <<-'EOT'
+ The command should only be run as a
+ refresh mechanism for when a dependent object is changed. It only
+ makes sense to use this option when this command depends on some
+ other object; it is useful for triggering an action:
+
+ # Pull down the main aliases file
+ file { "/etc/aliases":
+ source => "puppet://server/module/aliases"
+ }
+
+ # Rebuild the database, but only when the file changes
+ exec { newaliases:
+ path => ["/usr/bin", "/usr/sbin"],
+ subscribe => File["/etc/aliases"],
+ refreshonly => true
+ }
+
+ Note that only `subscribe` and `notify` can trigger actions, not `require`,
+ so it only makes sense to use `refreshonly` with `subscribe` or `notify`.
+ EOT
+
+ newvalues(:true, :false)
+
+ # We always fail this test, because we're only supposed to run
+ # on refresh.
+ def check(value)
+ # We have to invert the values.
+ if value == :true
+ false
+ else
+ true
+ end
+ end
+ end
+
+ # Verify that we pass all of the checks. The argument determines whether
+ # we skip the :refreshonly check, which is necessary because we now check
+ # within refresh
+ def check_all_attributes(refreshing = false)
+ self.class.checks.each { |check|
+ next if refreshing and check == :refreshonly
+ if @parameters.include?(check)
+ val = @parameters[check].value
+ val = [val] unless val.is_a? Array
+ val.each do |value|
+ return false unless @parameters[check].check(value)
+ end
+ end
+ }
+ true
+ end
+
+ newparam :name
+
+ newparam(:query) do
desc "The command to execute, the output of this command will be matched against regex."
end
@@ -21,6 +91,13 @@
end
end
+ newparam(:giveup_regex) do
+ desc "Give up if the regex matches command output, with out waiting"
+ munge do |value|
+ Regexp.new(value)
+ end
+ end
+
newparam(:polling_frequency) do
desc "How long to sleep in between retries."
defaultto 0.5

0 comments on commit 227dcf4

Please sign in to comment.