How to restrict parallel jobs to particular slaves in Declarative Pipeline

quangthang10d4

I have 3 nodes: A, B, C

On each of these nodes I set up a Jenkins slave with its own root directory They all have the following label: test && database && mysql

I want to run a job in parallel on all 3 nodes, to clean the workspace folder on them To achieve that, I wrote this Jenkins script

def labels = "test && mysql && database"

def getNodesName(labels){
    def targets = []
    def nodes = Jenkins.instance.getLabel(labels).getNodes()
    for(node in nodes){
        targets.add(node.getNodeName())
    }
    return targets
}

def nodes = getNodesName(labels)

def cleanWSTasks(targets){
    tasks = [:]
    for(target in targets){
        tasks[target] = {
            node(target){
                script {
                    cleanWs()
                }
            }
        }
    }
    return tasks
}

pipeline{
    agent none

    stages{

        stage ('Clean Workspace'){
            steps{
                script{
                    parallel cleanWSTasks(nodes)
                }
            }
        }

    }
}

So I thought with node(target) in the cleanWsTasks function I already told Jenkins to restrict the execution of the task only on the particular target node I want. So that all 3 nodes will start cleaning their own workspaces at the same time.

However, what I see is that only 1 node picked up the task to cleanUp the workspace, and it does it 3 times.

For example, it shows:

Running on node A in ...

clean up workspace ..

Running on node A in ...

clean up workspace ..

Running on node A in ...

clean up workspace ..

What did I do wrong in my code? Please help.

Vasiliki Siakka

The node step is working correctly, the problem you're coming across has to do with how you're defining your tasks. In your for loop, you're assigning this closure:

          {
            node(target){
                script {
                    cleanWs()
                }
            }

to tasks[target].

The code inside the closure won't get evaluated until you execute the closure. So even though you assign node(target) inside the for loop, target's value won't get evaluated until parallel tasks runs, which is when the closure is executed. That happens after the for loop has finished running and so target's value is the name of the last node in your list of nodes.

An easy fix for this is to create a variable in your for loop that's equal to target and use that inside the closure, because you will force the evaluation of target to happen inside your for loop, instead of when the closure runs. That would look like this:

def cleanWSTasks(targets){
    tasks = [:]
    for(target in targets){
        def thisTarget = target
        tasks[thisTarget] = {
            node(thisTarget){
                script {
                    cleanWs()
                }
            }
        }
    }
    return tasks
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to lock multiple stages of declarative Jenkins pipeline?

How to make Pipeline job to wait for all triggered parallel jobs?

How to run Jenkins jobs on multiple slaves with a single job configuration?

How to abort a declarative pipeline

How can I copy artifacts from executed jobs with declarative pipeline?

How to change a Jenkins Declarative Pipeline environment variable?

Jenkins Declarative Pipeline parallel stages

Jenkins declarative pipeline parallel steps executors

Gitlab pipeline jobs in the same stage are not running in parallel

Creating a sequential step in a jenkins declarative pipeline preceding a parallel stage

How to detect which parallel stage failed in a Jenkins declarative pipeline?

Dynamically defining parallel steps in declarative jenkins pipeline

How to exclude file from archiveArtifact in declarative pipeline?

How to add sidecar MySQL in declarative Jenkins pipeline?

How to define parallel stages in a declarative Jenkinsfile?

Parallel Example Jenkinsfile Declarative Pipeline Fails

Jenkins parallel declarative pipeline

How to make parallel calls to the same function in stage in Jenkins Declarative Pipeline

How to restrict a particular command in bash?

How to restrict character in a particular cell

Assigning variables in a parallel step using Declarative Pipeline steps in Jenkins

How to limit parallel jobs

Dynamic number of parallel steps in declarative pipeline

How to perform when..else in declarative pipeline

Parallel checkout in declarative Jenkins pipeline on multiple nodes

Parallel items in Jenkins Declarative pipeline

how can restrict processes in parallel

Reduce the pipeline script for running multiple jobs parallel

Parallel runs in declarative pipeline