Pipeline: How to add an input step, with timeout, that continues if timeout is reached, using a default value

Issue

How do I add an input step, with timeout, that continues if timeout is reached, using a default value, in a Pipeline job?

Environment

  • CloudBees Jenkins Enterprise
  • Pipeline plugin

Resolution

You can use a try catch block to achieve this.

The following asks for input, with a timeout of 15 seconds. If the timeout is reached the default is true. An if statement checking the input result (userInput) is used to determine what to do next:

def userInput = true
def didTimeout = false
try {
    timeout(time: 15, unit: 'SECONDS') { // change to a convenient timeout for you
        userInput = input(
        id: 'Proceed1', message: 'Was this successful?', parameters: [
        [$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Please confirm you agree with this']
        ])
    }
} catch(err) { // timeout reached or input false
    def user = err.getCauses()[0].getUser()
    if('SYSTEM' == user.toString()) { // SYSTEM means timeout.
        didTimeout = true
    } else {
        userInput = false
        echo "Aborted by: [${user}]"
    }
}

node {
    if (didTimeout) {
        // do something on timeout
        echo "no input was received before timeout"
    } else if (userInput == true) {
        // do something
        echo "this was successful"
    } else {
        // do something else
        echo "this was not successful"
        currentBuild.result = 'FAILURE'
    } 
}

Reference:

Have more questions? Submit a request

4 Comments

  • 0
    Avatar
    Ben Kolera

    The issue with this is that when a user clicks the X button to cancel the build outside of the input rejection. I see that the user in the cause is actually SYSTEM rather than the user that cancelled it.

    What we see when the build is clicked through the X button in the running builds list. The log even says "Aborted by admin" but the user on the cause is actually SYSTEM. This effectively means that there is no good way to tell a timeout apart from a user abort outside of the input. 

    Started by user admin
    [Pipeline] timeout
    Timeout set to expire in 10 sec
    [Pipeline] {
    [Pipeline] input
    Do you approve?
    Proceed or Abort
    Aborted by admin
    [Pipeline] }
    [Pipeline] // timeout
    [Pipeline] echo
    Aborted by SYSTEM

    Vs the Timeout

    Started by user admin
    [Pipeline] timeout
    Timeout set to expire in 10 sec
    [Pipeline] {
    [Pipeline] input
    Do you approve?
    Proceed or Abort
    Cancelling nested steps due to timeout
    [Pipeline] }
    [Pipeline] // timeout
    [Pipeline] echo
    [Pipeline] echo
    Aborted by SYSTEM
  • 0
    Avatar
    Ben Kolera

    I guess it is a weird requirement to actually want to proceed if the input times out rather than dying. If someone else has this requirement one day, we used this hack. :)

     

    userAborted = false
    startMillis = System.currentTimeMillis()
    timeoutMillis = 10000

    try {
      timeout(time: timeoutMillis, unit: 'MILLISECONDS') {
        input 'Do you approve?'
      }
    } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
      cause = e.causes.get(0)
      echo "Aborted by " + cause.getUser().toString()
      if (cause.getUser().toString() != 'SYSTEM') {
        startMillis = System.currentTimeMillis()
      } else {
        endMillis = System.currentTimeMillis()
        if (endMillis - startMillis >= timeoutMillis) {
          echo "Approval timed out. Continuing with deployment."
        } else {
          userAborted = true
          echo "SYSTEM aborted, but looks like timeout period didn't complete. Aborting."
        }
      }
    }

    if (userAborted) {
      currentBuild.result = 'ABORTED'
    } else {
      currentBuild.result = 'SUCCESS'
      echo "Firing the missiles!"
    }

  • 0
    Avatar
    Denys Digtiar

    Hi Ben,

     

    Thank you for clarification and a workaround. Have you considered raising an Improvement request for this.

    https://wiki.jenkins-ci.org/display/JENKINS/How+to+report+an+issue

    https://issues.jenkins-ci.org/

  • 0
    Avatar
    Ben Kolera

    Oh hi there Denys, fancy meeting you here! :)

    I held off submitting an issue because I thought that my use case was a little weird, but if you think that it's worthwhile submitting one I will do so. 

     

    Cheers,
    Ben

     

Please sign in to leave a comment.