Oliver
Oliver

Reputation: 1645

Wait for specific stage to complete in Jenkins parallel stages

I have stages running in parallel. Each stage has sub-stages.

stage("Prepare VMs") {
  parallel {
    stage("Prepare Database VM") {
      stage("Install Database") {...}
      stage("Upgrade Database") {...}
    }
    stage("Prepare Server VM") {
      stage("Install Server") {...}
      stage("Start Server") {...}
    }
    stage("Prepare Client VM") {
      stage("Install Client") {...}
    }
  }
}

As the above is now, the sub-stages of each stage run sequentially, but can run in parallel with the other stage.

What I want is for Start Server to wait until Upgrade Database finish. In other words, Install Server can run while Install Database or Upgrade Database run, but Start Server has to wait for Upgrade Database to finish. Is this possible?

My initial approach was to use an AtomicBoolean, but my company's Jenkins does not permit it.

final AtomicBoolean DATABASE_READY = new AtomicBoolean(false);

stage("Prepare VMs") {
  parallel {
    stage("Prepare Database VM") {
      stage("Install Database") {...}
      // At the end of the stage, it sets DATABASE_READY to true.
      stage("Upgrade Database") {...}
    }
    stage("Prepare Server VM") {
      stage("Install Server") {...}
      // Waits for DATABASE_READY.
      stage("Start Server") {...}
    }
    stage("Prepare Client VM") {
      stage("Install Client") {...}
    }
  }
}

Nor can I use CountDownLatch or similar.

Upvotes: 1

Views: 4590

Answers (2)

ycr
ycr

Reputation: 14574

I still can't understand why you can't use sequential stages for your use case :) But anyway here is how you can achieve this with lockable resources. You can read more on the plugin here and here.

Explanation

The lockable resource plugin allows you to create Global locks and let the pipeline acquire them as needed.

If you take the following pipeline. Lock lock ('db_setup_lock') within the Options block allows you to acquire the lock db_setup_lock for both Install Database and Upgrade Database stages, and this lock will only be released upon completion of both Stages. Assuming Install Server will take some time to run there is no possibility of Start Server acquiring the same lock before Prepare Database VM. Hence Start Server has to wait until the lock is released by the Prepare Database VM stages.

pipeline {
    agent any
    stages {
        stage("Prepare VMs") {
            parallel {
                stage("Prepare Database VM") {
                    options {
                       lock ('db_setup_lock')
                    }
                    stages {
                        stage("Install Database") {
                            steps {
                                echo "Install Database"
                                sleep 15
                                }
                            }
                        stage("Upgrade Database") {
                            steps {
                                echo "Upgrade Database start"
                                sleep 30
                                echo "Upgrade Database End"
                            }
                        }
                    }
                }

                stage("Prepare Server VM") {
                    stages {
                        stage("Install Server") {
                            steps {
                                echo "Install Server"
                                sleep 15
                            }
                        }
                        stage("Start Server") {
                             steps {
                                lock('db_setup_lock') {
                                    echo "Starting Server"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Upvotes: 0

MaratC
MaratC

Reputation: 6859

Let the continuous stages take care of that for you.

parallel {
 stage("Prepare VMs") {
  stages {
   stage("Prepare VMs 1") {
    parallel {
     stage("Prepare Database VM") {
      stage("Install Database") {...}
     }
     stage("Prepare Server VM") {
      stage("Install Server") {...}
     }
    }
   }
   stage("Prepare VMs 2") {
   // This will only run when the previous group has finished.
   parallel {
    stage("Prepare Database VM") {
      stage("Upgrade Database") {...}
    }
    stage("Prepare Server VM") {
      stage("Start Server") {...}
    }
   }
  }
 }
 stage("Prepare Client VM")
      stage("Install Client") {...}
 }

Upvotes: 1

Related Questions