Jenkins可锁定资源-无需解锁即可锁定

时间:2018-07-27 06:35:33

标签: jenkins locking jenkins-pipeline canary-deployment

我将“ Locable Resources Plugin”与Jenkins多管道功能一起使用:

lock('my-resource-name') {

}

我遇到一种情况,我需要在一个管道中锁定资源,而在另一个管道中解锁资源。我有解决方法,但如果可能的话,我希望使用锁插件。

我像这样的东西

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

原因

我正在实现Canary版本,并且有3条不同的路径通过我的管道(我考虑了其他解决方案,例如使用输入插件暂停管道-为我提供更多的资源超出了此问题的范围)。 我想在评估金丝雀时锁定/停止管道,然后在升级或回滚完成后再次对其进行解锁。 省略lock语句的正文只会给我java.lang.IllegalStateException: There is no body to invoke

3 个答案:

答案 0 :(得分:3)

做到这一点的一种方法是:

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

GET并不是一个错误,它确实是GET。

等待锁定

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

我也知道Jenkins支持所谓的“里程碑”,这显然是用来在内部版本之间进行通信的东西。但是我不知道是否可以用它以任何有意义的方式解决这个问题。

答案 1 :(得分:0)

从LockableResourcesManager

获得每个锁,然后 如果lock.getName匹配,则执行foreach锁,然后执行lock.reset()释放锁

例如一些麻烦的发现不属于任何版本的锁定锁并清理它们:

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

答案 2 :(得分:0)

可以通过这种方式完成锁定

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) }

解锁要简单得多,因为您知道资源存在(如果不存在,则没有理由尝试对其进行解锁)

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)

请注意,我曾经对此org.6wind.jenkins:lockable-resources:2.7进行过测试,具体实现细节可能会因所使用的版本而异。

<dependency>
    <groupId>org.6wind.jenkins</groupId>
    <artifactId>lockable-resources</artifactId>
    <version>2.7</version>
    <scope>provided</scope>
</dependency>