[JIRA] [lockable-resources-plugin] (JENKINS-34268) Lock multiple resources using the Pipeline lock step

76 views
Skip to first unread message

amuniz@cloudbees.com (JIRA)

unread,
Apr 15, 2016, 4:00:01 AM4/15/16
to jenkinsc...@googlegroups.com
Antonio Muñiz created an issue
 
Jenkins / Improvement JENKINS-34268
Lock multiple resources using the Pipeline lock step
Issue Type: Improvement Improvement
Assignee: Antonio Muñiz
Components: lockable-resources-plugin
Created: 2016/Apr/15 7:59 AM
Priority: Major Major
Reporter: Antonio Muñiz

The current implementation of Pipeline lock step allows to block a single resource.

It should be extended to cover all the functionality of the plugin (applicable to non-freestyle jobs) such as blocking resources by label or request a lock for N resources.

The DSL must be something like this:

lock (resources: ['resource1', 'resource2']) {
  ... execution block ...
}

or

lock (label: 'my-resources') {
  ... execution block ...
}

The behavior of the label parameter would be equivalent to:

lock (resources: ['resource3', 'resource4']) { // if both resource3 and resource4 are labeled as 'my-resources'
  ... execution block ...
}
Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v6.4.2#64017-sha1:e244265)
Atlassian logo

aeon512@gmail.com (JIRA)

unread,
Apr 15, 2016, 4:25:01 AM4/15/16
to jenkinsc...@googlegroups.com
Florian Hug commented on Improvement JENKINS-34268
 
Re: Lock multiple resources using the Pipeline lock step

Besides the actual label functionality, also the possibility to request a certain amount of resources from this label would be essential.

I would personally prefer something like

lock(label: 'fooBar', quantity: 2) {
  // whatever
}

Actually this is what keeps us from using pipelines.

amuniz@cloudbees.com (JIRA)

unread,
Apr 15, 2016, 4:55:01 AM4/15/16
to jenkinsc...@googlegroups.com

Florian Hug Could you explain a real use case where the quantity configuration makes sense please? It's not clear to me why one would want to acquire 2 resources but do not caring about which ones specifically.

aeon512@gmail.com (JIRA)

unread,
Apr 15, 2016, 5:07:01 AM4/15/16
to jenkinsc...@googlegroups.com
Florian Hug edited a comment on Improvement JENKINS-34268
*Background:*
We dynamically create virtual machines which acts as jenkins slave (using the {{swarm-plugin}}) to perform the actual build steps. Thereby, if an error occurs we can archive the whole VM such that a developer can investigate and solve the problem. Using linked snapshots the whole purpose of creating such a new VM takes simply seconds and works very well.

*Problem solved by lockable resources:*
Since the overall amount of memory and cores on the host machine is limited, we used the lockable resources plugin to manage the distribution of memory (slices) and cpu cores.

For example, let's say we have configured 16 resources (Memory Slice 1, Memory Slice 2, ..., Memory Slice 3), each representing e.g. 4 GB Memory. that is a total of 64 GB being available for virtual machines. When a job starts and wants to create a VM with e.g. 16 GB virtual memory, the job simply tries to request 4 slices
 ({{ = quantity }})  of  4 GB  memory
{code:java}
lock(label: 'memory', quantity: 4) {
   // actual build steps
}
{code}
If this succeeds there is enough memory available, and the job can continue. If not, the job blocks until the necessary amount of memory is available again (since other jobs have finished and shut down their VMs).

The same principle applies to CPU (cores) as well.

Does this explanation help?

aeon512@gmail.com (JIRA)

unread,
Apr 15, 2016, 5:07:02 AM4/15/16
to jenkinsc...@googlegroups.com

Background:
We dynamically create virtual machines which acts as jenkins slave (using the swarm-plugin) to perform the actual build steps. Thereby, if an error occurs we can archive the whole VM such that a developer can investigate and solve the problem. Using linked snapshots the whole purpose of creating such a new VM takes simply seconds and works very well.

Problem solved by lockable resources:


Since the overall amount of memory and cores on the host machine is limited, we used the lockable resources plugin to manage the distribution of memory (slices) and cpu cores.

For example, let's say we have configured 16 resources (Memory Slice 1, Memory Slice 2, ..., Memory Slice 3), each representing e.g. 4 GB Memory. that is a total of 64 GB being available for virtual machines. When a job starts and wants to create a VM with e.g. 16 GB virtual memory, the job simply tries to request 4 slices of memory

lock(label: 'memory', quantity: 4) {
   // actual build steps
}

If this succeeds there is enough memory available, and the job can continue. If not, the job blocks until the necessary amount of memory is available again (since other jobs have finished and shut down their VMs).

The same principle applies to CPU (cores) as well.

Does this explanation help?

aeon512@gmail.com (JIRA)

unread,
Apr 15, 2016, 5:08:01 AM4/15/16
to jenkinsc...@googlegroups.com
Florian Hug edited a comment on Improvement JENKINS-34268
*Background:*
We dynamically create virtual machines which acts as jenkins slave (using the {{swarm-plugin}}) to perform the actual build steps. Thereby, if an error occurs we can archive the whole VM such that a developer can investigate and solve the problem. Using linked snapshots the whole purpose of creating such a new VM takes simply seconds and works very well.

*Problem solved by lockable resources:*
Since the overall amount of memory and cores on the host machine is limited, we used the lockable resources plugin to manage the distribution of memory (slices) and cpu cores.

For example, let's say we have configured 16 resources (Memory Slice 1, Memory Slice 2, ..., Memory Slice 3), each representing e.g. 4 GB Memory. that is a total of 64 GB being available for virtual machines. When a job starts and wants to create a VM with e.g. 16 GB virtual memory, the job simply tries to request 4 slices ({{ = quantity }}) of 4 GB memory
{code:java}

lock(label: 'memory', quantity: 4) {
   // actual build steps
}
{code}

If this succeeds there is enough memory available, and the job can continue. If not, the job blocks until the necessary amount of memory is available again (since other jobs have finished and shut down their VMs).

The same principle applies to CPU (cores) as well.

Does this explanation help?

amuniz@cloudbees.com (JIRA)

unread,
Apr 15, 2016, 5:27:02 AM4/15/16
to jenkinsc...@googlegroups.com

Thanks for take the time to explain!

Makes sense, although nothing is preventing the steps inside the lock block to consume more CPU/RAM than virtually acquired, right?

aeon512@gmail.com (JIRA)

unread,
Apr 15, 2016, 5:33:01 AM4/15/16
to jenkinsc...@googlegroups.com

Yes and no
No: Once the VM is configured to a certain amount of CPU/RAM, that amount is fixed and no process inside the VM can use more. If a process inside such a VM want's to consume more memory it simply receives an OutOfMemory exception.
Yes: However, in theory, you can lock a different amount than you configure the VM.

However, in our pipeline scripts we define a variable, e.g. required_memory_slices and use this variable to specify the necessary quantity as well as use this variable when setting up the virtual machine. Hence, in this case, it is guaranteed that we lock the same amount that we configure the VM to use, and hence no process can consume more CPU/RAM.

amuniz@cloudbees.com (JIRA)

unread,
Apr 15, 2016, 6:03:01 AM4/15/16
to jenkinsc...@googlegroups.com

Ok, looks good. I've created a separate issue (JENKINS-34273) for quantity support in Pipeline as it can be handled independently of this one.

BTW you have there a nice CI configuration

aeon512@gmail.com (JIRA)

unread,
Apr 15, 2016, 6:28:01 AM4/15/16
to jenkinsc...@googlegroups.com

Thanks And we are keen on switching to the new Pipeline - but JENKINS-34273 is absolutely necessary for us.

aeon512@gmail.com (JIRA)

unread,
Apr 23, 2016, 2:08:02 AM4/23/16
to jenkinsc...@googlegroups.com

Antonio Muñiz, maybe you could have a look at PR26 where I tried to implement the functionality for label and quantity. Since this is my first Jenkins plugin contribution (and my first actual Java implementation) I'm open for any kind of feedback. Would be great if we get this merged in.

lock(label: "MyLabelName", quantity: 3) {
    // body
}

Note however, that for closing this Issue the functionality to specify a list of resources is still missing. JENKINS-34273 however could be closed completely.
I couldn't figure out how the DataBoundSetter for this would need to be modified within the actual LockStep. The actual implementation for dealing with several required resources is already available.

haneyd@roguewave.com (JIRA)

unread,
Jun 14, 2016, 7:45:02 PM6/14/16
to jenkinsc...@googlegroups.com

Should the fix for this include exposing the names of the acquired resource within the body? For instance if I have something like:

lock (label: 'my-resources') {
  ... execution block ...
}

It would be useful to know whether resource1 or resource2 was acquired by the lock.

This message was sent by Atlassian JIRA (v7.1.7#71011-sha1:2526d7c)
Atlassian logo

tadej.j@nez.si (JIRA)

unread,
Jun 15, 2016, 3:43:02 AM6/15/16
to jenkinsc...@googlegroups.com

David Haney, I think the problem you mention would be solved by pursuing merging PR #20 tracked by JENKINS-31437.

amuniz@cloudbees.com (JIRA)

unread,
Jun 15, 2016, 4:11:02 AM6/15/16
to jenkinsc...@googlegroups.com

the problem you mention would be solved by pursuing merging PR #20

No. That PR is only valid for freestyle jobs and it's about exposing arbitrary properties not the name of locked resources.

tadej.j@nez.si (JIRA)

unread,
Jun 15, 2016, 4:34:03 AM6/15/16
to jenkinsc...@googlegroups.com

Antonio Muñiz, oh, I see. Still, it would be great if one could set properties/environement variables for each resource and they would then be accessible within the lock execution block. Or it that possible already?

niels.wegner@edict.de (JIRA)

unread,
Sep 28, 2016, 11:56:02 AM9/28/16
to jenkinsc...@googlegroups.com

May be the locked resource might be return via given variable as requested in JENKINS-30269. This would be a similar way as if configured thru a job config.

justinrainwater78@gmail.com (JIRA)

unread,
Oct 14, 2016, 7:12:02 PM10/14/16
to jenkinsc...@googlegroups.com

Just curious has anyone tried nested locking as a workaround? I'm curious if that would work.
So instead of
lock (resources: ['resource1', 'resource2'])

{ ... execution block ... }

it would be:
lock('resource1) {
lock('resource2)

{ ... execution block ... }

}

// Some comments here
public String getFoo()
{
    return foo;
}

justinrainwater78@gmail.com (JIRA)

unread,
Oct 14, 2016, 7:13:02 PM10/14/16
to jenkinsc...@googlegroups.com
Justin Rainwater edited a comment on Improvement JENKINS-34268
Just curious has anyone tried nested locking as a workaround? I'm curious if that would work.
So instead of
{code}
    lock (resources: ['resource1', 'resource2']) {
      ... execution block ...
   }
{code}

it would be:
{code}
    lock('resource1) {
        lock('resource2) {
            ... execution block ...
        }
    }
{code :java }
// Some comments here
public String getFoo()
{
    return foo;
}
{code}

rene_dupuit@hotmail.com (JIRA)

unread,
Nov 5, 2016, 5:18:06 AM11/5/16
to jenkinsc...@googlegroups.com

Implemented in PR36.
The proposed DSL syntaxe is (each parameter is optional, some are aliases such as "label" / "labels" / "capability" / "capabilities"):

lock(resource: 'resource1 resource2', resources: ['resource1', 'resource2'], 
    label: 'label1 label2', labels: ['label1', 'label2'],
    capability: 'label1 label2', capabilities: ['label1', 'label2'],
    quantity: 2, variable: 'MY_VAR') {
        ... execution block ...
}

Note that "quantity" is only relevant for "labels" / "capabilities" (not "resources", since they are unique and defined by names)

pwolf@cloudbees.com (JIRA)

unread,
Dec 7, 2016, 11:44:03 AM12/7/16
to jenkinsc...@googlegroups.com
Patrick Wolf assigned an issue to Unassigned
 
Change By: Patrick Wolf
Assignee: CloudBees Inc.

pwolf@cloudbees.com (JIRA)

unread,
Dec 7, 2016, 11:44:04 AM12/7/16
to jenkinsc...@googlegroups.com
Patrick Wolf assigned an issue to CloudBees Inc.
Change By: Patrick Wolf
Assignee: Antonio Muñiz CloudBees Inc.

stalle+jenkins-ci@gmail.com (JIRA)

unread,
Dec 8, 2016, 10:39:01 AM12/8/16
to jenkinsc...@googlegroups.com
Staffan Forsell commented on Improvement JENKINS-34268
 
Re: Lock multiple resources using the Pipeline lock step

Will PR36 be merged/released soon? This would resource allocation of some old ssh builders that we would like to do from pipelines. I there anything I can do to help? Is there a test build that we could run?

amuniz@cloudbees.com (JIRA)

unread,
Dec 13, 2016, 6:46:02 AM12/13/16
to jenkinsc...@googlegroups.com

scm_issue_link@java.net (JIRA)

unread,
Dec 16, 2016, 2:00:17 PM12/16/16
to jenkinsc...@googlegroups.com
SCM/JIRA link daemon commented on Improvement JENKINS-34268
 
Re: Lock multiple resources using the Pipeline lock step

Code changed in jenkins
User: Antonio Muniz
Path:
src/main/java/org/jenkins/plugins/lockableresources/BackwardCompatibility.java
src/main/java/org/jenkins/plugins/lockableresources/LockStep.java
src/main/java/org/jenkins/plugins/lockableresources/LockStepExecution.java
src/main/java/org/jenkins/plugins/lockableresources/LockableResource.java
src/main/java/org/jenkins/plugins/lockableresources/LockableResourcesManager.java
src/main/java/org/jenkins/plugins/lockableresources/actions/LockableResourcesRootAction.java
src/main/java/org/jenkins/plugins/lockableresources/queue/LockRunListener.java
src/main/java/org/jenkins/plugins/lockableresources/queue/LockableResourcesStruct.java
src/main/java/org/jenkins/plugins/lockableresources/queue/QueuedContextStruct.java
src/main/resources/org/jenkins/plugins/lockableresources/LockStep/config.jelly
src/main/resources/org/jenkins/plugins/lockableresources/LockStep/help-label.html
src/main/resources/org/jenkins/plugins/lockableresources/LockStep/help-quantity.html
src/main/resources/org/jenkins/plugins/lockableresources/LockStep/help-resource.html
src/test/java/org/jenkins/plugins/lockableresources/LockStepTest.java
http://jenkins-ci.org/commit/lockable-resources-plugin/974572db98214f7b9293a303c9fd8371877250a0
Log:
Merge pull request #42 from amuniz/pr-26-fix

JENKINS-34268JENKINS-34273 Lock multiple resources with specific quantity

Compare: https://github.com/jenkinsci/lockable-resources-plugin/compare/ba48550fa5bc...974572db9821

brendan@shapesecurity.com (JIRA)

unread,
Dec 16, 2016, 5:21:02 PM12/16/16
to jenkinsc...@googlegroups.com

Now that the PR that fixes this ticket is merged, I'd like to request a release of this plugin as soon as is appropriate.

amuniz@cloudbees.com (JIRA)

unread,
Dec 19, 2016, 1:13:03 PM12/19/16
to jenkinsc...@googlegroups.com
Antonio Muñiz resolved as Fixed
 

Released as 1.11

Change By: Antonio Muñiz
Status: Open Resolved
Resolution: Fixed

stalle+jenkins-ci@gmail.com (JIRA)

unread,
Dec 20, 2016, 3:57:01 AM12/20/16
to jenkinsc...@googlegroups.com
Staffan Forsell commented on Improvement JENKINS-34268
 
Re: Lock multiple resources using the Pipeline lock step

Antonio Muñiz
Hi! Nice to see this merged.
Looking at the merged content, I can't seem to find any pipeline syntax for actually knowing what resource was locked.
Specifically the proposed syntax from PR36 above: ", variable: 'MY_VAR'" is missing.
Our use case is that we wan't to specify a label containing node names for legacy builders that can't run the slave.jar (java7) anymore. We wan't to lock a resources (host name) from he label and then ssh to that machine any execute some build steps. This works with the FreestyleJob functionality of #Reserved resources variable name". Any thought of adding this to pipeline?

karl@koomie.com (JIRA)

unread,
Dec 20, 2016, 3:01:04 PM12/20/16
to jenkinsc...@googlegroups.com

I'm also unable to successfully use the MY_VAR option. It's awesome to be able to lock multiple resources now, but can't recreate the capability of a Freestyle job without being able to query the results.

glance+jenkins@acc.umu.se (JIRA)

unread,
Dec 30, 2016, 9:57:02 AM12/30/16
to jenkinsc...@googlegroups.com

I did a really ugly workaround for the missing resourceVariable :

lock(label: 'LABEL', quantity: 1)

{ echo org.jenkins.plugins.lockableresources.LockableResourcesManager.class.get().getResourcesFromBuild(currentBuild.getRawBuild())[0].getName() }

That will get you which resource you locked.

dafalcon@akamai.com (JIRA)

unread,
Mar 11, 2017, 12:26:08 AM3/11/17
to jenkinsc...@googlegroups.com
Dan Falcone edited a comment on Improvement JENKINS-34268
After implementing Anton Lundin's suggestion, I received the following error in my build (followed by a stacktrace):
{code:java}
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method{code}
To fix it, I went to Manage Jenkins > In process Script Approval, clicked Approve on the pending signature approval, and reran the build.  I had to repeat the process 4-5 times to approve all the required signatures
, but it worked great after that .
This message was sent by Atlassian JIRA (v7.3.0#73011-sha1:3c73d0e)
Atlassian logo

dafalcon@akamai.com (JIRA)

unread,
Mar 11, 2017, 12:26:08 AM3/11/17
to jenkinsc...@googlegroups.com

After implementing Anton Lundin's suggestion, I received the following error in my build (followed by a stacktrace):

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method

To fix it, I went to Manage Jenkins > In process Script Approval, clicked Approve on the pending signature approval, and reran the build.  I had to repeat the process 4-5 times to approve all the required signatures.

chris.dickinson@nio.io (JIRA)

unread,
May 3, 2019, 2:05:04 PM5/3/19
to jenkinsc...@googlegroups.com

Anyone hoping to make use of locking a dynamic list of resources will probably find this feature (if it was ever implemented) doesn't work in v2.4 of the plugin.

So, I whipped up the following helper function which should allow you to do so:

 

def lockResources(listOfResources, closure) {
    if (listOfResources.size() > 1) {
        lockResources(listOfResources[1..-1], { lock(listOfResources[0]) { closure() }})
    } else {
        lock(listOfResources[0]) { closure() }
    }
}

Example usage:

def resources = ['foo', 'bar', 'baz']
lockResources(myResources, { 
    print('hello, world') 
})

 

 

This message was sent by Atlassian Jira (v7.11.2#711002-sha1:fdc329d)

tobias-jenkins@23.gs (JIRA)

unread,
Dec 8, 2019, 4:30:04 AM12/8/19
to jenkinsc...@googlegroups.com

Chris Dickinson Can you open a new ticket instead of commenting on a closed one (where nobody will ever see your comments, I stumbled on it by accident) if you have issues with the plugin? Anyway, locking of multiple resources is implemented since 2.3. The syntax (as generated by the snippet generator) is:

lock(extra: [[resource: 'b'], [label: 'c', quantity: 1]], resource: 'a') {
    // some block
}

 

This message was sent by Atlassian Jira (v7.13.6#713006-sha1:cc4451f)
Atlassian logo
Reply all
Reply to author
Forward
0 new messages