简体   繁体   中英

Jenkins lockable resource - lock without unlocking

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

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.

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

eg 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

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>

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM