flix
flix

Reputation: 177

Jenkins - Not creating dedicated workspaces in a parallel stage

My Jenkins Setup is as follows: I do have multiple Jenkins slaves which have the same label e.g. jenkins_node.

Now I wanted to parallelize my current pipeline which didn't have a parallel stage before, because there was only one node available.

The stages I want to run in parallel are for different CMake Build types (Debug and Release). If those stages are run on the same node, they must not share the same workspace. Otherwise the compile process will fail.

If one of the executors is occupied with another build job, the pipline (also the parallel steps) get executed on the same node. In that case the workspace is shared and the build process fails.

I would expect that Jenkins takes care of this by creating dedicated workspaces in case of a parallel stage e.g. by using the @2 suffix like documented here.

This is a sample pipeline to reproduce the problem. Release and Debug share the same workspace if executed on the same node. How can I enforce that dedicated workspaces are used for those stages?

pipeline {
    agent { label 'jenkins_node' }
    options {
            timeout(time: 3, unit: 'HOURS')
            timestamps()
    }
    stages {
        stage('create file') {
            steps{
                touch 'my_file_test_file.txt'
            }
        }
        stage('Builds') {
            parallel {
                stage('Release') {
                    steps{
                        //trigger release build here
                        touch 'release.txt'
                        echo pwd()
                        bat 'dir'
                    }
                }
                stage('Debug') {
                    steps{
                        //trigger debug build here
                        touch 'debug.txt'
                        echo pwd()
                        bat 'dir'
                    }
                }
            }
        }
    }
    post{
        cleanup {
            cleanWs()
        }
    }
}

here's the log of one test run:

Started by user ***
[Pipeline] Start of Pipeline
[Pipeline] node (hide)
Running on *** in c:\jenkins\demo_playground
[Pipeline] {
[Pipeline] timeout
Timeout set to expire in 3 hr 0 min
[Pipeline] {
[Pipeline] timestamps
[Pipeline] {
[Pipeline] stage
[Pipeline] { (create file)
[Pipeline] touch
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Builds)
[Pipeline] parallel
[Pipeline] { (Branch: Release)
[Pipeline] { (Branch: Debug)
[Pipeline] stage
[Pipeline] { (Release)
[Pipeline] stage
[Pipeline] { (Debug)
[Pipeline] touch
[Pipeline] touch
[Pipeline] pwd
[Pipeline] echo
 c:\jenkins\demo_playground
[Pipeline] bat
[Pipeline] pwd
[Pipeline] echo
 c:\jenkins\demo_playground
[Pipeline] bat
 
 c:\jenkins\demo_playground>dir
  Volume in drive C is OSDisk
  Volume Serial Number is 8ECE-9CEF
 
  Directory of c:\jenkins\demo_playground
 
 03/16/2022  02:12 PM    <DIR>          .
 03/16/2022  02:12 PM    <DIR>          ..
 03/16/2022  02:12 PM                 0 debug.txt
 03/16/2022  02:12 PM                 0 my_file_test_file.txt
 03/16/2022  02:12 PM                 0 release.txt
                3 File(s)              0 bytes
                2 Dir(s)  33,649,197,056 bytes free
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
 
 c:\jenkins\demo_playground>dir
  Volume in drive C is OSDisk
  Volume Serial Number is 8ECE-9CEF
 
  Directory of c:\jenkins\demo_playground
 
 03/16/2022  02:12 PM    <DIR>          .
 03/16/2022  02:12 PM    <DIR>          ..
 03/16/2022  02:12 PM                 0 debug.txt
 03/16/2022  02:12 PM                 0 my_file_test_file.txt
 03/16/2022  02:12 PM                 0 release.txt
                3 File(s)              0 bytes
                2 Dir(s)  33,649,197,056 bytes free
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // parallel
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] cleanWs
 [WS-CLEANUP] Deleting project workspace...
 [WS-CLEANUP] Deferred wipeout is used...
 [WS-CLEANUP] done
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // timestamps
[Pipeline] }
[Pipeline] // timeout
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

As you can see, the workspace is shared between the Release and Debug stage.

Update 1 (2022-03-21):

As highlighted by @MaratC I modified my script to allocate the agent per stage, but still. If executed on one slave (because the other one is occupied), I sill get the same result. So for me this issue is still open.

pipeline {
    agent none
    options {
            timeout(time: 3, unit: 'HOURS')
            timestamps()
    }
    stages {
        stage('create file') {
            agent {
                node {
                    label 'jenkins_node'
                }
            }
            steps{
                touch 'my_file_test_file.txt'
            }
        }
        stage('Builds') {
            parallel {
                stage('Release') {
                agent {
                    node {
                        label 'jenkins_node'
                    }
                }
                    steps{
                        //trigger release build here
                        touch 'release.txt'
                        echo pwd()
                        bat 'dir'
                    }
                }
                stage('Debug') {
                agent {
                    node {
                        label 'jenkins_node'
                    }
                }
                    steps{
                        //trigger debug build here
                        touch 'debug.txt'
                        echo pwd()
                        bat 'dir'
                    }
                }
            }
        }
    }
    post{
        cleanup {
            cleanWs()
        }
    }
}

Upvotes: 1

Views: 1902

Answers (1)

MaratC
MaratC

Reputation: 6889

Here's my version of your pipeline:

jenkins_node = "some_node_with_lots_of_executors"
pipeline {
    agent { node { label 'master' } }
    options {
            timeout(time: 3, unit: 'HOURS')
            timestamps()
    }
    stages {
        stage('create file') {
            agent { node { label "${jenkins_node}" } }
            steps { echo pwd() }
        }
        stage('Builds') {
            parallel {
                stage('Release') {
                    agent { node { label "${jenkins_node}" } }
                    steps { echo pwd() }
                }
                stage('Debug') {
                    agent { node { label "${jenkins_node}" } }
                    steps { echo pwd() }
                }
            }
        }
    }
    post { cleanup { cleanWs() } }
}

Here's the output:

[Pipeline] node
14:20:16  Running on <some_node> in /home/jenkins/workspace/test_pipeline
[Pipeline] {
[Pipeline] pwd
[Pipeline] echo
14:20:16  /home/jenkins/workspace/test_pipeline
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Builds)
[Pipeline] parallel
[Pipeline] { (Branch: Release)
[Pipeline] { (Branch: Debug)
[Pipeline] stage
[Pipeline] { (Release)
[Pipeline] stage
[Pipeline] { (Debug)
[Pipeline] node
[Pipeline] node
14:20:16  Running on <some_node> in /home/jenkins/workspace/test_pipeline
14:20:16  Running on <some_node> in /home/jenkins/workspace/test_pipeline@2
[Pipeline] {
[Pipeline] {
[Pipeline] pwd
[Pipeline] echo
14:20:16  /home/jenkins/workspace/test_pipeline
[Pipeline] }
[Pipeline] pwd
[Pipeline] echo
14:20:16  /home/jenkins/workspace/test_pipeline@2
[Pipeline] }
[Pipeline] // node
[Pipeline] // node

From what can be seen, Jenkins allocates two separate workspaces (test_pipeline, test_pipeline@2) for two parallel stages if they run on the same node at the same time.

Upvotes: 0

Related Questions