5

I am using Jenkins Lockable Resources plugin to decide which server to be used for various build operations in my declarative pipeline. I have set up my Lockable Resources as shown in the table below:

Resource Name       Labels

Win_Res_1           Windows
Win_Res_2           Windows
Win_Res_3           Windows
Lx_Res_1            Linux
Lx_Res_2            Linux
Lx_Res_3            Linux

I want to lock a label and then get the name of the corresponding locked resource.

I'm writing following code but am not able to get the desired value of r

int num_resources = 1;
def label = "Windows"; /* I have hardcoded it here for simplicity. In actual code, I will get ${lable} from my code and its value can be either Windows or Linux. */

lock(label: "${label}", quantity: num_resources)
{
    def r = org.jenkins.plugins.lockableresources.LockableResourcesManager; /* I know this is incomplete but unable to get correct function call */
    println (" Locked resource r is : ${r} \n");

    /* r should be name of resource for example Win_Res_1. */
}

The documentation for Lockable Resources Plugin is available here: https://jenkins.io/doc/pipeline/steps/lockable-resources/ and https://plugins.jenkins.io/lockable-resources/

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131
Yash
  • 2,944
  • 7
  • 25
  • 43

1 Answers1

7

You can get the name of locked resource using variable parameter of the lock workflow step. This option defines the name of the environment variable that will store the name of the locked resource. Consider the following example.

pipeline {
    agent any

    stages {
        stage("Lock resource") {
            steps {
                script {
                    int num = 1
                    String label = "Windows"

                    lock(label: label, quantity: num, variable: "resource_name") {
                        echo "Locked resource name is ${env.resource_name}"
                    }
                }
            }
        }
    }
}

In this example, the locked resource name can be accessed using env.resource_name variable. Here is the output of the pipeline run.

[Pipeline] {
[Pipeline] stage
[Pipeline] { (Lock resource)
[Pipeline] script
[Pipeline] {
[Pipeline] lock
Trying to acquire lock on [Label: Windows, Quantity: 1]
Lock acquired on [Label: Windows, Quantity: 1]
[Pipeline] {
[Pipeline] echo
Locked resource name is Win_Res_1
[Pipeline] }
Lock released on resource [Label: Windows, Quantity: 1]
[Pipeline] // lock
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

You can see that the value Win_Res_1 was assigned to the env.resource_name variable.

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131
  • 1
    Thanks @Szymon. This works for me !! I somehow overlooked the `variable: 'var'` option. – Yash Apr 09 '20 at 07:21
  • Hi @Szymon, I ran into a problem where when i try to lock a resource which is already locked by other pipelines, above code returns error `No such property: resource_name for class: groovy.lang.Binding` and the print message says `Locked resource name is null`. Ideally in this case the pipeline should have waited for the resource (locked by other pipeline) to be free and then acquire it instead of returning error. Do we need to add anything else for script to wait for a resource if all are busy ? – Yash Apr 30 '20 at 05:20