Jenkins 按标签锁定

Sam*_*ARD 5 jenkins jenkins-plugins jenkins-pipeline

我想要实现的目标

  • jobA在一台机器上需要 1 个执行器。
  • 我需要jobB在同一台机器上有 2 个执行器,在 X 台机器上需要 1 个执行器。
  • 我希望他们能够使用相同的机器(尽管不是同时)-> 他们目前使用不同的机器。
  • 他们的所有任务都使用 100% CPU。因此,同一台机器上不能同时存在两个构建。

我如何解决这个问题

  • 因为jobB单个节点上至少需要 2 个执行器,并且jobA需要 1 个,所以我需要将执行器的数量更改为每个节点 2 个。
  • 应该有一个锁定机制,以便如果jobAjobB构建在节点上运行,则任何jobAjobB构建都无法在该节点上启动。

我做了什么

我将机器上的执行器数量从 1 更改为 2。

解决方案一:锁定资源

jobA在的管道中,我有:

node('windows-agent-label') {
    lock("${env.NODE_NAME}-exclusive") {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

运行该作业(第一次)给了我:

[Pipeline] Start of Pipeline
[Pipeline] node
Running on build1 in J:\jenkins\workspace\jobA
[Pipeline] {
[Pipeline] lock
Trying to acquire lock on [build1-exclusive]
Resource [build1-exclusive] did not exist. Created.
Lock acquired on [build1-exclusive]
Run Code Online (Sandbox Code Playgroud)

第二次(第一次仍在构建中):

[Pipeline] Start of Pipeline
[Pipeline] node
Running on build1 in J:\jenkins\workspace\jobA@2
[Pipeline] {
[Pipeline] lock
Trying to acquire lock on [build1-exclusive]
Found 0 available resource(s). Waiting for correct amount: 1.
[build1-exclusive] is locked, waiting...
Run Code Online (Sandbox Code Playgroud)

有用!第二个构建将被阻止,直到第一个构建释放锁。然而,第二个已经被分派到节点并使用执行器槽。实在不好看啊!如果我将lock()指令移到指令之外node(),我还没有指令env.NODE_NAME,因此锁无法工作。

显然,还有另一种方法...

解决方案 2:通过请求标签来锁定

我有一个名为的标签windows-agent-label,其中包含 2 个节点:build1build2

jobA在的管道中,我有:

lock(label: 'windows-agent-label', quantity: 1) {
    node('windows-agent-label') {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

运行这项工作给了我:

[Pipeline] Start of Pipeline
[Pipeline] lock
Trying to acquire lock on [Label: windows-agent-label, Quantity: 1]
Found 0 available resource(s). Waiting for correct amount: 1.
[Label: windows-agent-label, Quantity: 1] is locked, waiting...
Run Code Online (Sandbox Code Playgroud)

绝对没有任何东西在运行build1

我的一切/lockable-resources/都是FREE

问题

  • 为什么找不到可用资源?我是否滥用它?
  • 我的方向正确吗?

Sam*_*ARD 6

解决方案

lock文档中,缺少(未记录)参数:variable。当与 一起使用时label,它将env所获取的锁的名称存储到一个变量中。

这里缺少: https: //plugins.jenkins.io/lockable-resources

在那里可见:https ://issues.jenkins-ci.org/browse/JENKINS-40997

lock(label: 'windows-agent-label', quantity: 1, variable: 'LOCK_NAME') {
    node(env.LOCK_NAME - '-exclusive') {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,这会请求某个标签下的所有锁。它们总是(通过选择)形成为${NODE_NAME}-exclusive。如果我无法锁定资源,则意味着它们都已用完。如果我得到一个,那就意味着NODE_NAME(could be build1, build2, ...) 可用。所以,我转到给定的节点。