Bug #13441

A command that times out will not re-execute if "tries" is set.

Added by Lars Kellogg-Stedman about 1 year ago. Updated 12 months ago.

Status:AcceptedStart date:03/27/2012
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:exec
Target version:-
Affected Puppet version:2.7.14 Branch:
Keywords:

Description

I was expecting something like this to retry execution if the command timed out:

exec { '/path/to/mycommand':
  tries => 2,
  timeout => 10,
}

Unfortunately, the exception generated by a timeout resumes control outside of the retry loop:

    begin
      tries.times do |try|
        # Only add debug messages for tries > 1 to reduce log spam.
        debug("Exec try #{try+1}/#{tries}") if tries > 1
        @output, @status = provider.run(self.resource[:command])
        break if self.should.include?(@status.exitstatus.to_s)
        if try_sleep > 0 and tries > 1
          debug("Sleeping for #{try_sleep} seconds between tries")
          sleep try_sleep
        end
      end
    rescue Timeout::Error
      self.fail "Command exceeded timeout" % value.inspect
    end

I’m not sure how to deal with commands that may need to be retried due to timeouts. Would it be possible to move the retry loop outside of the try/catch?


Related issues

Related to Puppet - Bug #17603: Puppet execute has unexpected semantics Accepted

History

#1 Updated by Ken Barber about 1 year ago

  • Project changed from Puppet Labs Modules to Puppet

#2 Updated by Kelsey Hightower about 1 year ago

  • Category set to exec
  • Status changed from Unreviewed to Investigating
  • Assignee set to Kelsey Hightower

#3 Updated by Kelsey Hightower about 1 year ago

  • Status changed from Investigating to Accepted
  • Assignee deleted (Kelsey Hightower)
  • Affected Puppet version set to 2.7.14

So this is a real bug. I was able to reproduce this with the following manifest:

# This should run for at least 10 seconds
exec { 'timeout_test':
  command => '/bin/sleep 3',
  returns => 2,
  timeout => 2,
  tries   => 5,
}

My command only gets run once:

debug: /Stage[main]//Exec[timeout_test]/returns: Exec try 1/5
debug: Exec[timeout_test](provider=posix): Executing '/bin/sleep 3'
debug: Executing '/bin/sleep 3'
err: /Stage[main]//Exec[timeout_test]/returns: change from notrun to 2 failed: Command exceeded timeout at /Users/kelseyhightower/bug13441.pp:7
debug: /Schedule[never]: Skipping device resources because running on a host
debug: /Schedule[weekly]: Skipping device resources because running on a host
debug: /Schedule[puppet]: Skipping device resources because running on a host
debug: Finishing transaction 2253004880
debug: Storing state
debug: Stored state in 0.01 seconds
notice: Finished catalog run in 2.04 seconds
debug: Finishing transaction 2252422000
debug: Received report to process from hightower-2.local
debug: Processing report from hightower-2.local with processor Puppet::Reports::Store

This is in conflict with the documentation around the exec resource:

The number of times execution of the command should be tried. Defaults to ‘1’. This many attempts will be made to execute the command until an acceptable return code is returned. Note that the timeout paramater applies to each try rather than to the complete set of tries.

Also available in: Atom PDF