Plugin Information |
|---|
View Lockable Resources on the plugin site for more information. |
Older versions of this plugin may not be safe to use. Please review the following warnings before using an older version:
Quick usage guide
- Install the plugin
- In Manage Jenkins > Configure System go to Lockable Resources Manager
- Select Add Lockable Resource
Brief description of the named fields:
- Name - A name (not containing spaces!) for this particular resource, i.e. DK_Printers.
- Description - A verbose description of this particular resource, i.e.Printers in the Danish Office
- Labels - Space-delimited list of Labels (Not containing spaces) used to identify a pool of resources. i.e. DK_Printers_Office DK_Printer_Production DK_Printer_Engineering
- Reserved by - If anything is written here, the resource will be taken and therefore unavailable for other jobs. i.e. All printers are currently not available due to maintenance.
- Select Add Lockable Resource
- In Jenkins > <job name> > Configure > General
Brief description of the named fields:
- Resources - The name or names of resources needed. In this example, DK_Printers will select all of the three printers in the pool.
- Label - One or more Labels to select resources. In this example, DK_Printer_Production DK_Printer_Engineering will select two labeled printers in the larger pool.
- Start a build.
- Under build #<number> select Locked Resources
- You should see something like: This build has locked the following resources: <resource_name> - <resource description>
- Start a different build which uses the same resource. * You will see *Build Queue in Jenkins status/menu showing job name
- Hover text shows Started <by>, Waiting for resources <resources list>, Waiting for <time>
Pipeline usage
- When the
lockstep is used in a Pipeline, if the resource to be locked isn't already defined in the Jenkins global configuration, it'll be set up automatically. - The arguments to the
lockstep are:resource- The resource name to lock as defined in Global settings. IfinversePrecedenceisn't also specified, the step can be called aslock('some-resource')without the named argument.label- can be used to require locks on multiple resources concurrently. The build will wait until all resources tagged with the given label are available. Only this orresourcecan be used simultaneously.quantity- (optional) specifies the number of resources required within the selected label. If not set, all resources from the label will be required.inversePrecedence- (optional) By default waiting builds are given the lock in the same order they requested to acquire it. IfinversePrecedenceis set to true, this will be done in reverse order instead, so that the newest build to request the lock will be granted it first.variable- (optional) When locking a resource via alabelyou can usevariableto set an environment variable with the name of the locked resource.
Examples:
echo 'Starting' lock('my-resource-name') { echo 'Do something here that requires unique access to the resource' // any other build will wait until the one locking the resource leaves this block } echo 'Finish'lock(resource: 'staging-server', inversePrecedence: true) { node { servers.deploy 'staging' } input message: "Does ${jettyUrl}staging/ look good?" }lock(label: 'test-farm') { parallel test1: { node('farm-server-linux') { sh './run-tests.sh' } }, test2: { node('farm-server-windows') { sh './run-tests.bat' } } }lock(label: 'some_resource', variable: 'LOCKED_RESOURCE') { echo env.LOCKED_RESOURCE }
Changelog
Release 2.5 (2019-3-25)
Release 2.4 (2019-1-18)
JENKINS-46555 - Fix NPE on invalid entries.
Release 2.3 (2018-6-26)
JENKINS-34433 - Signal queued Pipeline tasks on unreserve
Allow locking multiple resources in Pipeline
Release 2.2 (2018-3-6)
JENKINS-40997 - New configuration option to get the name of the locked resource inside the lock block (Pipeline).
- JENKINS-49734 - Add a PauseAction to the build when waiting for locking, so Pipeline representations in the UI are correctly shown.
- JENKINS-43574 - Fixed the "empty" resources lock (message: "acquired lock on []")
Release 2.1 (2017-11-13)
- JENKINS-47235 - Trim whitespace from resource names.
- JENKINS-47754 - Fix broken Freestyle behavior.
Release 1.11.2 (2017-3-15)
- JENKINS-40368 - Locked resources are not always freed up on Pipeline hard kill when there are other pipelines waiting on the Resource
Release 1.11.1 (2017-2-20)
- JENKINS-40879 - Locked areas are executed multiple times in parallel
Release 1.11 (2016-12-19)
- JENKINS-34268 - lock multiple resources concurrently
- JENKINS-34273 - add the number of resources to lock from a given label
Release 1.10 (2016-07-12)
- JENKINS-36479 - properly clean up resources locked by hard-killed or deleted while in progress Pipeline builds.
Release 1.9 (2016-06-01)
- Reserved resources parameter visibility in environment (related to SECURITY-170)
Release 1.8 (2016-04-14)
- Pipeline compatibility: lock step
Release 1.2 (2014-02-05)
- Manual reservation/un-reservation of resources now require specific permissions
Release 1.1 (2014-02-03)
- Allow jobs to require a subset of specified resources (the number of required resources is configurable)
- Allow manual reservation/un-reservation of resources
Release 1.0 (2013-12-12)
- Initial release


55 Comments
Unknown User (testmonkey)
Could you please add some more information? Some pictures would be useful.
In our project we have several network printers of different types and brands. A job needs ONE printer of a certain type. Would this be possible with your plugin? Pick one of a pool?
Unknown User (oleg_nenashev)
The plugin is very similar to existing "Throttle Concurrent Builds", "Lock and Latches" and "Exclusion".
Some info is definitely required. Probably it makes sense to merge new features to one of existing plugins
Unknown User (drosser9)
Actually, this plugin does something that, as far as I can tell, no other plugin does: Create a pool (or pools) of resources that are not attached to specific slave nodes.
One feature this plugin is missing: I need to be able to attach metadata to resources (like in the https://wiki.jenkins-ci.org/display/JENKINS/External+Resource+Dispatcher plugin) so I can expose the metadata back to the test script as environment variables.
Kudos!
Unknown User (alfeberlin)
You can pass the name of the acquired resource(s) into a variable and thus pass at least this piece of information to the job. You can associate meta data to this name (or these names) on your own then.
Unknown User (legendahri)
This plugin solved an existing issue in our project. Thanks!
Request/Suggestion:
As of now, a resource can only be released after a build is finished. Is it possible to release/unlock a resource in the middle of the build? Something like another build step that can be added (ex. additional option in "Add build step" menu).
In our build jobs, the resource is only used at the start and then the build will continue for about 10-20 minutes.
Other jobs will still have to wait for 10-20 minutes even though in reality the resource is already "free".
Unknown User (generatz)
More documentation definitely needed.
This allows the admin to define several resources. Then, in the job configuration, one specifies a pool (list of resources) and then indicates how many of those resources are needed to run. The job queues until sufficient resources are available. When sufficient resources become available, the job allocates those resources and proceeds, then frees the resources.
There is a nifty little page that shows what is currently locked (allocated) and what is free. It also allows a resource to be reserved and therefore unavailable. If locked or reserved, it shows what job or individual, respectively, holds the resource.
I think only one pool is available per job. But each job specification has it's own description of what constitutes the pool for that job. So, yes, I think it will do what was needed in the comment by Daniel Schneider.
There does not appear to be any notion of a resource tree. (Unfortunately, this is what I need, so I'm not using it.)
Unknown User (jwstric2)
I'd have to agree with an above comment that this plugin "does something that, as far as I can tell, no other plugin does: Create a pool (or pools) of resources that are not attached to specific slave nodes" Our group faced some problems in an early project a couple months ago with hardware routers that we dealt with but were looking to create something during down time that would address our needs. Apparently we were a day late and a dollar short ..
Unknown User (lilithian)
Hi,
I am testing this plugin. Is there a way to retrieve the name of the locked resource? Is there a global variable containing this value?
Example I have two resources "resA" & "resB" both having the label "res". I lock the resources using the label. Now I want to know which one it is that I have locked.
Is there a way to find this out?
Best regards,
Baubak
Unknown User (lilithian)
Never mind discovered that the field "Reserved resources variable name" actually created a variable for the resource being used. Was expecting a default variable, and didn't think we needed to set it.
Thanks anyway. The plugin is very useful. Thank you.
Baubak
Unknown User (lilithian)
Hi
It would be good if you could create a profile to be shared by many resources. For example in the Config you define:
In your jobs you only reference the profile P.
Best regards,
Baubak
Unknown User (alfeberlin)
The plugin works just fine for us but seems a little limited to me. Some suggestions for improvements I really would like to have (and consider adding them myself, in case I find the time):
Currently I'm creating things like 32 resources of which each represents 1GB of ram (because I have 32GB of ram available to distribute among virtual machines). Each task which needs to create such a virtual machine requires, depending on its needs, 4, 6 or more of these resources. So several machines using 6 resources each (6GB) can run in parallel, or one using 20 resources and three using 4 etc.
But to create 32 resources with the same label is a PITA; it never looks good, neither in the configuration nor on the overview of required resources etc. If I could create one quantized resource RAM_IN_GB which has a quantization of 32, that would of course be much more convenient.
I would like to have a project require, e. g. 16GB of ram and additionally a VM (a different kind of resource), and maybe a share of the CPU as well.
Currently I only can achieve this by nesting projects (project A requires 16GB of ram, executes project B, and waits for its finishing; project B requires a VM and really does the job). But this of course bloats up my project list and has so many other disadvantages I do not even want to start listing them here (job dependencies, build pipelines, …).
Currently, starting a build puts the build to sleep until all required resources are available, then it acquires the resources, then the build runs, and no matter how the build stops, then all resources are released at once and unconditionally.
This is inconvenient in several cases. For example If a build running on a VM fails, often the VM is actually still running (because a pull-down-step didn't happen and shouldn't happen to ease debugging), so releasing the resource creates a schism (the model of the resource is freed, but the actual resource isn't free to be used by the next project). I then run into instantaneous errors because the next project gets this resource, tries to use it and fails (because it isn't really available).
Currently, always the "topmost" available resource will be used. This means that if I have, e. g. three printers, one will have much more work than the other two. It would be nice the be able to configure, e. g. a round-robin or a random method to achieve an equal load on all resources.
Unknown User (nickolay_martinov)
Using it to run certification jobs that use pools of external resources and to maintain these resources using ElasticAxis. Require certain modifications to plugin, however. Here's an explanation how to manage the pools and do certification testing: PDF on github
Unknown User (phil)
This is a fantastic plugin which really does have something many others don't. This plugin allows you to manage pools of resources (For me, this is pricey systems which must be a part of our test cycle) and allocate them to jobs as they run. If none are available, it will block the job until one frees up. If someone were to continue development on this, or extend it in another plugin, I'd be very happy. Ideally, I'd love:
Really well done to the author and I hope you will continue development of this plugin.
Unknown User (drienkop)
@Phil Schaechter: You can actually reserve/unreserve a resource by calling the following URL:
http://jenkins:8080/lockable-resources/reserve?resource=YOUR_RESOURCE_NAME
http://jenkins:8080/lockable-resources/unreserve?resource=YOUR_RESOURCE_NAME
It would be great if the authors documented this and allowed even more API calls.
Unknown User (kutzi)
You can also use:
http://your-jenkins/plugin/lockable-resources/api/json
to get a list of all lockable resources including reservation status.
This is also not documented and I had to search the source code to find it (see https://github.com/jenkinsci/lockable-resources-plugin/commit/ecd0332f404538d37eefbe878c6ae74c9584f5ec)
Unknown User (yogeshkrbhat)
Is it possible to send lockable resource name as a parameter to job? Assume that valid resource is sent as parameter.
Thanks,
Yogesh
Unknown User (bmatzen)
I would like this as well, the ability to use a build parameter as the resource name, versus hard coding the name. For example, we have a collection of jobs that can each run on a set of servers, and we want the server to be our resource. While we might be able to use a resource pool for this, there are times when we want to manually trigger a build and select the server from a choice build parameter, and have the job grab that as the resource. So if build parameter "TEST_SYSTEM" has the FQDN where we want to run the test, we could specify "${TEST_SYSTEM}" (w/o the quotes of course) as the resource, and on the fly it would get resolved to the FQDN value in TEST_SYSTEM. That would be very handy.
Unknown User (orirosen)
+1 I am also looking into using build parameters for a lock.
I use a build parameter to choose on which hardware server to run my tests, and I cannot find a way yet to lock the hardware so 2 jobs don't clash.
Unknown User (hyei)
Being able to use a build variable from a build parameter for the label would be very useful as well.
Unknown User (christian_ekholm)
Is it possible to allocate different kinds of resources in one build (resources with different label)?
Unknown User (lucymhdavies)
When using this in a pipeiline, if a resource is locked, is there an easy way to find out which running job has that lock?
Unknown User (jameswithers)
Great plugin - so simple and effective.
Could you make the Lockable Resources Manager on the Configure System page collapsible. We have dozens of resources and this makes the config page very large!
Unknown User (fsteff)
Does the current version work as expected when used in a free-flow job?
I set up a small test scenario to play with, and it seems like waiting for resources works, but not waiting for Labels.
Edit: Added to Jenkins JIRA as
JENKINS-44388.Edit 2. Closed as "not an error". The documentation in the plugin has been updated, although the description on this page still needs some cleanup.
My tests below:
I used a resource named TEST, with two labels TEST_1 and TEST_2.
Looking at the available resources, it's reported that I have the "TEST" resource, and one instance of the two labels - as expected.
In a free-flow job, I enable This build requires lockable resources, and the tested the following four setups:
Trial 1
Resources = TEST
Number of resources to request = 0
Expectation: The resource TEST and all labels consumed during the test.
On execution:
The test project does not wait for anything.
None of the resources nor labels are reported used.
Note: This might be correct behaviour - provided 0 is used literal, unlike documented in the plugin: "empty value or 0 means all "
Trial 2
Resources = "TEST"
Number of resources to request = 1
Expectation: All labels on the TEST resource will be consumed.
On execution:
The test project does wait for the TEST resource and does consume all Labels.
Trial 3
Lable = "TEST_1"
Number of resources to request = 0
Expectation: The TEST_1 label will be consumed, leaving "TEST_2" available.
On execution:
The test project does not wait for anything.
None of the resources nor labels are reported used.
Note: This might be correct behaviour - provided 0 is used literal, unlike documented in the plugin: "empty value or 0 means all "
Trial 4
Lable = "TEST_1"
Number of resources to request = 1
Expectation: The TEST_1 label will be consumed, leaving "TEST_2" available.
On execution:
The test project does not wait for anything.
None of the resources nor labels are reported used.
Trial 4 is the error I'm really concerned about, as it seems to indicate that only resources can be taken, and not labels.
Tested on Plugin release 2.0 @ Jenkins 2.57
Unknown User (fsteff)
I wrote this question on StackOverflow (direct link), but for completeness I'm also including it here.
Edit: Added to Jenkins JIRA as
JENKINS-44389Edit 2: Closed as fixed. It's now possible to use Groovy from freestyle jobs, and get the expected result.
tl;dr, More documentation for this plugin is certainly needed. This comment may shed some light on how some things are working - but it also showcases some things that are apparently not working!
I'm was initially attempting to get the Lockable Resources Plugin to lock on a specific resource while also evaluation the value of a system environment variable.
Evaluation the system environment variable is working perfectly, however, I can't seem to get a lock on the correct resource.
This question focused on the specific locking problem!
I have created a three resources called A_TEST, B_TEST and C_TEST. None of them have any Labels. They are all visible from my Jenkins_URL/lockable-resources/ where they can be taken and released without problems.
In my Jenkins Job configuration, I have selected the This build requires lockable resources option, which allows me to specify a Resource, Label or Groovy Expression (and Additional classpath). It additionally allows me to specify Reserved resources variable name and Number of resources to request.
According to the documentation, the Groovy script must return a boolean value, so I determined to try it out:
Test 1
The first test I did was to verify the basic functionality, by setting the following:
This results in the job executing with a lock on the B_TEST resource. The console output reads:
Test 2
In this test I set the following:
When attempting to execute the job, this wrongly waits forever with the text:
(pending--Waiting for the resourced [B_TEST])Test 3
In this test I set the following:
This results in the wrong resource A_TEST to be locked. The console output reads:
Test 4
After rereading the help for each option in the plugin, I discovered that the plugin apparently only allows me to specify either a Resource, Label or Groovy Expression So in this test I set the following:
This results in the job executing wrongly without a lock on any resource. The console output reads:
Test 5
So in this test I set the following:
This results in the job wrongly locking on all resource. The console output reads:
Test 6
According to the documentation of the plugin, in Jenkins-Pipelines this plugin can be used as this:
so I started experimenting with the Groovy Script containing variations of the
lock('B_TEST')call, but this mostly lead to more confusion and errors while the job attempted to start, such as this:But I guess this all makes good sense, as the
lock(){ }call seems suited to take and release the lock only during its capture.The Question
The big question now is, how does all of this actually work? My guess is that somewhere there's a groovy command to specify the Resources/Labels you want to reserve, and the return value (true/false) determines to actually take the lock or not. I have attempted to dive into the source, but didn't have any luck.
Any answer is greatly appreciated.
Unknown User (jimklimov)
Is it possible to pick and lock an available resource from the pool (any would do - so following the example in documentation, say I want some printer, don't care which one - but exclusively dedicated for this job run)?
Unknown User (pmw)
If a job selects a resource by label, the console output has a message saying "
acquiring lock on [resourcename]".But if it selects a resource explicitly by name, the message is "
acquiring lock on []", without the name. it would be helpful if it could include the name in this case too.Unknown User (klamb)
I have a job that only wants to lock under certain conditions. When I want to bypass the lock, I pass in a lockname of ''.
This works, but it prints this in the console :
This is fine, But, it would be nice if there were a way to explicitly disable the lock so that the console wouldn't have to report a non-bug.
I am thinking something like this:
LOCKDISABLED = true if (condition) { LOCKDISABLED = true } lock(resource 'myresource', disabled: LOCKDISABLED ) { // stuff }Unknown User (rgodavarthi)
@Ken Lamb You can do the following for your usecase I believe :
String checkCondition(def resource=''){ if(resource == 'myresource') { return resource }else { return JOB_NAME } } //Examples of usage with lock step lock(resource: checkCondition('myresource')) { println "The regular stuff"// stuff } lock(resource: checkCondition()) { println "The real stuff"// stuff }Unknown User (klamb)
Thank you for the suggestion. I ended up using something very similar to this.
Unknown User (rgodavarthi)
I have a set of jobs which want to acquire lock on a resource "xyz". I want one of the job to have high priority while trying to acquiring the lock. How can I achieve this.
I noticed that some code was removed in 2015 that was adding a priority based lock precedence.
In my case default and inverse precedence do not help
Is it possible to edit the resource queue dynamically to move the high priority request to the front of queue?
Unknown User (mohdnisart)
Thank you very much for this plugin.It is a very useful plugin
Is there anyway to get the utilisation of resources?. Basically I need to plan for adding more resources based on the usage of a particular label.
Unknown User (ssbarnea)
Is it possible to require a resource with zero quantity?
Here is why this would be extremely useful: I want to use resource locking to prevent running jobs when some external services are down. Mainly we do lock/unlock one resource with the name of the service, via a script or manually using Jenkins UI.
Now jobs should not run while the resource is locked but we do not want them to lock any resource as we want to allow them to run in parallel. This translates to a job which waits for a lock but does not reserve anything while running.
Does this work or not?
Unknown User (vsluzky)
How to get locked resource(s) name(s) when using lock from a pipeline?
I need to start a process and pass reserved name as a parameter
Unknown User (jimklimov)
Hello, the usual usage of the plugin is to lock by label - e.g. that you want any instance of the labeled resource(s), such as "some printer" following the example above.
It is possible to grab a specific resource by name, but this probably requires to process locking with Evaluate as a Groovy script. See https://github.com/jenkinsci/lockable-resources-plugin/pull/72 and https://github.com/jenkinsci/lockable-resources-plugin/issues/73 for more details on my solution to this (I hope relevant code for plugin is already in upstream binaries).
Unknown User (vsluzky)
I do need to reserve by label, get the reserved resource name, and then use it. Here is my use case:
Is it possible?
Unknown User (jimklimov)
Did you have time to read issue #73 linked above?
It is about nearly same use-case, complete with sample code from our approach to making it work. Now, we did this in freestyle jobs so far, but I see little reason that those groovy script snippets could not be stuffed into pipeline (maybe not the simpler "declarative" one though).
Note this needs interplay of several plugins: a build of Lockable Resources with PR#72 included, so it can process build args and their values (as we pass them with the label of the type of resource, or name of specific resource we want to test against - that code in Evaluate Groovy discerns the difference); and the EnvInject plugin to get the ultimately chosen name of a locked resource instance back from groovy variables to shell variables that we can use in Shell script steps - e.g. to reflash a particular testbed hostname - as well as to forward into spawned sub-jobs.
Hope this helps,
Jim Klimov
Unknown User (ashi_kec)
Hi Klimov,
Your answer is very complex for a common user to make sense.
Also the status of plugin - does it contain needed fixes #72 #73 ?
I hope please you can clarify in a bit simpler way.
Unknown User (vsluzky)
I did looked #72 and #73 and could not find that they help. IMO Release 2.2 fully answers my question. When can I expect it to be delivered? According to the log, it should be available, but it's not
Unknown User (ashi_kec)
It is available and I installed already on Jenkins.
Unknown User (vsluzky)
A try to lock a resource from a pipeline is never satisfied if resource is not available when pipeline starts. Is it a known issue?
Steps to reproduce:
Expected result:
A resource is reserved and pipeline continues working
Actual behavior:
Pipeline keeps waiting for a resource while it's available
Unknown User (jimklimov)
From log, it looks like it is working as it should (I see that per your detailed description it apparently does not): You have one defined resource with label "Win81" and it is already occupied by someone else; this job will stay in queue until it gets free, so this one can grab that resource.
Can you look into `jenkins.log` on the master server? Every few seconds there should be log messages from this plugin evaluating resources it is waiting for - maybe that would uncover what else went wrong?..
I did not yet use it from pipeline context, but in our older freestyle jobs (and with evaluation as Groovy script per my earlier comment above) it works as expected - so a few seconds after a resource gets released (manually Unreserved, or a job that used it has ended) the plugin discovers the change of state, and another queued job gets and grabs it.
Unknown User (vsluzky)
Thank you for looking into the issue, Jim.
For some unknown reason the issue was not reproduced today
If that happens again, which jenkins.log file should I look for?
Unknown User (jimklimov)
On master instance,
${JENKINS_HOME}/logs/jenkins.logIIRC.Unknown User (vsluzky)
I face that problem again with a Freestyle project.
Here's the history:
I created a few lockable resources, created jobs that reserved 1 resource per label and worked with them for a while
Then I updated lockable resources and the jobs.
Now reservation works only by resource, not by label
If I don't specify number of requested resources per label, the locked resource is empty
If I specify 1 requested resource per label, it waits forever
${JENKINS_HOME}/logs/jenkins.log does not expose any lockable resource info.
I tried to restart Jenkins - did not help
Uninstall and reinstall Lockable Plugin (the lockable resources were not removed; I reused them) - did not help
Unknown User (ashi_kec)
Hi Developer,
Could you please update plugin-details / help / Examples, so that user gets to know about what is new in version 2.2 ?
Unknown User (vsluzky)
I found a bug: Locked variable is assigned only to one of threads during parallel execution.
Below is a simple pipeline script that displays the problem.
It starts 3 threads in parallel each locking a resource by label. I specified a single available resource with this label.
The locked resource should be assigned to a variable, but it is assigned only once in the first executed thread.
Here is the script to reproduce the problem:
node('slave') {
def execs = [:]
execs[1] = {
lock(label: 'Win81x64Pool', quantity: 1, variable: "MY_VAR") {
println "LOCKED=" + env.MY_VAR
sleep(3)
}
}
execs[2] = {
lock(label: 'Win81x64Pool', quantity: 1, variable: "MY_VAR") {
println "LOCKED=" + env.MY_VAR
sleep(3)
}
}
execs[3] = {
lock(label: 'Win81x64Pool', quantity: 1, variable: "YOUR_VAR") {
println "LOCKED=" + env.YOUR_VAR
sleep(3)
}
}
parallel execs
}
and here is an exempt from console output. Please note that LOCKED=null for second and third threads
Unknown User (kami)
Hi, I have a question, I'm trying to use the plugin with Declarative pipeline and I lost one executor while the resource is freedom when I use lock into the pipeline block, when I use it out of the block the execution never is send to the queue(I know that this is not the right way). Could you explain me if is possible use the plugin without block an executor with Declarative pipeline?
Unknown User (myxal)
Can the lock be somehow used in a declarative pipeline across multiple stages? I couldn't get the pipeline to work with lock being at a higher level than under steps {...}.
That would still be okay if the lock step only performed the lock and it was up to me to put a "release" step elsewhere in the pipeline, but there doesn't seem to be a release step, and the lock step won't work without a body of its own
Unknown User (gurce)
I had some trouble creating resources via Jenkins DSL (groovy) code. In the end I managed to do it via some uberClassLoader technique, so thought I'd share the approach here:
def lrm = Jenkins.instance.getPluginManager().uberClassLoader.loadClass("org.jenkins.plugins.lockableresources.LockableResourcesManager")Unknown User (fsteff)
Use Lockable Resource as a mutex, sharing a resource between multiple freestyle jobs. (Also, how to use parameters to set the lockable resource, and used node.)
Scenario
We have multiple jobs that need to access the same hardware. Some of these jobs are split into sub-jobs, and a mutex like functionality are needed to avoid a mixup.
Pre-requvisits
Implementation
The hardware (two in this explanation) are called HiL1 and HiL2.
In order to create the mutex, two lockable resources are needed, and for ease of use they get the same names: HiL1 and HiL2. Optionally, additional two lockable resources are needed to keep track of the execution: HiL1_sub and HiL2_sub.
The main jobs are the owners of the mutex, and they can pass on a mutex token to sub-jobs, which is used to lock on the actual nodes.
Each of the main jobs can be started specifying to get either a random lock on one of, or a specific lock on one of, the two lockable resources, by specifying either HiL, HiL1 or HiL2.
Main jobs
The main jobs are implemented as below. Example name is Jenkins_Test/Lockable_Resources_Job1_Test
// Beware, this executes before the console log is initialized, so the Groovy println output ends up in jenkins.out.log !! this.binding.variables.each {k,v -> println "$k = $v"} if ( (resourceName.startsWith(RESOURCE_FOR_THIS_JOB)) && (!resourceName.endsWith("_sub")) ) { // println "Gotit" return true } return falseFor each sub-job needed,
Add to the build section
Sub-jobs
Each sub job should be implemented as below. Example name is: Jenkins_Test/Lockable_Resources_Test_Job1_Sub
// Set the node to execute on. // Can be either HiL1 or HiL2 if (RESOURCE_CONSUMED_BY_TOP_JOB.startsWith("HiL")) { return RESOURCE_CONSUMED_BY_TOP_JOB }// Beware, this executes before the console log is initialized, so the Groovy println output ends up in jenkins.out.log !! this.binding.variables.each {k,v -> println "$k = $v"} if (resourceName == RESOURCE_CONSUMED_BY_TOP_JOB + "_sub") { // println "Gotit" return true } return falseNow manually triggering a sub-job will not work. Only by starting one of the main jobs, the sub-jobs can be executed.
Unknown User (avergison)
A simple pipeline script locking a single lock as follows:
lock('qp5_nonconcurrent_build') {Here's the log output:
And it waits forever.
Aborting and restarting (or rebuilding a prior build) at no avail - all hanging again.
However, the immediately prior run ended nicely:
We're pretty confident no one else inside Jenkins is using this name.
This came to happen all of a sudden.
Any clue?
Thanks,
Andre
Unknown User (ashi_kec)
You can check which job is blocking the resource on - <jenkins-url>/lockable-resources/
Unknown User (wbrode)
I believe the documentation on this page is confusing resource with label and vice versa. A resource is a single entity while a label can be applied over multiple resources to create a pool of resources. Could the maintainer update the documentation/example to fix this? Example of correct usage:
Then you can do:
to acquire one of the printers.
Unknown User (gsturge)
Thanks! The doc had me very confused.
Unknown User (mario_goorden)
Is it possible to show the jenkins jobs which are waiting for a locked resource ?
It would als be nice to be able to kill those jobs with an option 'purge waiting for resource jobs'