Jenkins lockable resource - lock without unlocking
Asked Answered
K

4

10

I'm using the "Locable Resources Plugin" together with the Jenkins multipipeline functionality:

lock('my-resource-name') {

}

I have a situation where I need to lock a resource in one pipeline and unlock it in another. I have workarounds, but I would prefer using the lock plugin, if possible.

I imagagine something like this

lock("my-resource-name")
..... 
unlock("my-resource-name)

The why of it

I'm implementing canary releases, and there are three different paths through my pipeline (I considered other solutions, like pausing the pipeline with the input plugin - providing me with more is out of scope for this question). I would like to lock/halt the pipeline while the canary is evaluated, and then, when the promotion or rollback is done, unlock it again. Omitting the body for the lock statement just gives me java.lang.IllegalStateException: There is no body to invoke

Kab answered 27/7, 2018 at 6:35 Comment(1)
Did you find any soultion? I am looking for the same.Vivacious
K
11

One way of doing it is this:

curl -XGET https://your-jenkins/lockable-resources/reserve?resource=myresource
curl -XGET https://your-jenkins/lockable-resources/unreserve?resource=myresource

The GET is not a mistake, it really is GET.

To wait for a lock

lock("my-resource-name") {}

I also know Jenkins support something called "milestones" apparently is something used to communicate between builds. But I have no idea if it can be used to solve this problem in any meaningful way.

Kab answered 27/7, 2018 at 11:2 Comment(0)
A
4

The lock can be done this way

import org.jenkins.plugins.lockableresources.LockableResource
import org.jenkins.plugins.lockableresources.LockableResourcesManager

...

LockableResourcesManager lockableResourcesManager = LockableResourcesManager.get()
LockableResource lockableResource = lockableResourcesManager.fromName(resourceName)
// if the resource doesn't exists, create it
if (lockableResource == null) {
    lockableResourcesManager.createResource(resourceName)
    lockableResource = lockableResourcesManager.fromName(resourceName)
}

// wait until lock is successful
waitUntil { lockableResourcesManager.lock([lockableResource].toSet(), currentBuild.rawBuild, null) }

The unlock is much simpler because you know the resource exists (if it doesn't there is no reason to try to unlock it)

LockableResourcesManager lockableResourcesManager = LockableResourcesManager.get()
LockableResource lockableResource = lockableResourcesManager.fromName(resourceName)
// do not pass currentBuild.rawBuild as in your case is not the build that locked this resource
// so I am passing null instead
lockableResourcesManager.unlock([lockableResource], null)

Note that I used to test this org.6wind.jenkins:lockable-resources:2.7, the implementation details may vary depending on the version used.

<dependency>
    <groupId>org.6wind.jenkins</groupId>
    <artifactId>lockable-resources</artifactId>
    <version>2.7</version>
    <scope>provided</scope>
</dependency>
Amylopectin answered 16/10, 2020 at 19:19 Comment(0)
O
2

from LockableResourcesManager get each lock, then foreach lock do if lock.getName matches then do lock.reset() to release the lock

e.g. some groovy to find locked locks not owned by any builds and clean them up:

print "START\n"
def all_lockable_resources = org.jenkins.plugins.lockableresources.LockableResourcesManager.get().resources
all_lockable_resources.each { r->
   if (r.isLocked() || r.isReserved()) { 
        println "Lock " + r + " is locked or reserved by " + r.getBuild() + " B CARSE " + r.getLockCause()

        b = r.getBuild()

        if (b) {
           if (b.isBuilding()) { println "build:" + b + " is building" } 
           if (b.getResult().equals(null)) { println "build:" + b + " result is not in yet" }

           if ( ! b.isBuilding() && ! b.getResult().equals(null)) { 
              println "build:" + b + " is not building and result is " + b.getResult() + " yet the lock " + r + " is locked."
              println "ACTION RELEASE LOCK " + r

              println "getLockCause:" + r.getLockCause() 
              println "getDescription:" + r.getDescription() 
              println "getReservedBy:" + r.getReservedBy() 
              println "isReserved:" + r.isReserved() 
              println "isLocked:" + r.isLocked() 
              println "isQueued:" + r.isQueued() 

              //release the lock
              r.reset() 

              println "getLockCause:" + r.getLockCause() 
              println "getDescription:" + r.getDescription() 
              println "getReservedBy:" + r.getReservedBy() 
              println "isReserved:" + r.isReserved() 
              println "isLocked:" + r.isLocked() 
              println "isQueued:" + r.isQueued() 

           }
        }

   }
}

API: http://javadoc.jenkins.io/plugin/lockable-resources/org/jenkins/plugins/lockableresources/LockableResource.html

Oppress answered 10/10, 2018 at 16:37 Comment(0)
M
0

or navigate to https://jenkins-host/lockable-resources/ page. here we can find list of all the lockable resources. we can manually lock or reserve these.

Moldy answered 10/11, 2021 at 12:42 Comment(1)
Manually locking and unlocking is an anti-pattern for automation.Vaporish

© 2022 - 2025 — McMap. All rights reserved.