In a declarative jenkins pipeline - can I set the agent label dynamically?

Gilad Shahrabani picture Gilad Shahrabani · Oct 8, 2017 · Viewed 58.3k times · Source

Is there a way to set the agent label dynamically and not as plain string?

The job has 2 stages:

  1. First stage - Runs on a "master" agent, always. At the end of this stage I will know on which agent should the 2nd stage run.
  2. Second stage - should run on the agent decided in the first stage.

My (not working) attempt looks like this:

pipeline {
    agent { label 'master' }
    stages {
        stage('Stage1') {
            steps {
                script {
                    env.node_name = "my_node_label"
                }
                echo "node_name: ${env.node_name}"
            }
        }

        stage('Stage2') {
            agent { label "${env.node_name}" }
            steps {
                echo "node_name: ${env.node_name}"
            }
        }
    }
}

The first echo works fine and "my_node_label" is printed. The second stage fails to run on an agent labeled "my_node_label" and the console prints:

There are no nodes with the label ‘null’

Maybe it can help - if I just put "${env}" in the label field I can see that this is a java class as it prints:

There are no nodes with the label ‘org.jenkinsci.plugins.workflow.cps.EnvActionImpl@79c0ce06’

Answer

Vitaly picture Vitaly · Mar 6, 2018

Here is how I made it: mix scripted and declarative pipeline. First I've used scripted syntax to find, for example, branch I'm on. Then define AGENT_LABEL variable. This var can be used anywhere along the declarative pipeline

def AGENT_LABEL = null

node('master') {
  stage('Checkout and set agent'){
     checkout scm
     ### Or just use any other approach to figure out agent label: read file, etc
     if (env.BRANCH_NAME == 'master') {
        AGENT_LABEL = "prod"
     } else {
        AGENT_LABEL = "dev"
     }
   }
}

pipeline {
    agent {
       label "${AGENT_LABEL}"
    }

    stages {
        stage('Normal build') {
           steps {
              echo "Running in ${AGENT_LABEL}"
              sh "hostname"
           }
        } 

        stage ("Docker build") {
           agent{
             dockerfile {
                dir 'Dockerfiles'
                label "${AGENT_LABEL}"
             }
            }
            steps{
                sh "hostname"
            }
        }
    }
}