Jenkins按标签锁定

5

我想要实现的目标

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

我是如何解决这个问题的

  • 因为jobB需要至少在单个节点上使用2个执行器,而jobA需要1个,所以我需要更改执行器的数量,使每个节点有2个。
  • 应该有一个锁机制,以便如果在节点上运行了jobAjobB构建,则不能在其上启动jobAjobB构建。

我已经做了什么

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

解决方案1:锁定资源

jobA的流水线中,我有:

node('windows-agent-label') {
    lock("${env.NODE_NAME}-exclusive") {
        //...
    }
}

运行任务(第一次)时,我得到了以下结果:

[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]

第二次(当第一次仍在构建时):
[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...

它有效!第二个构建将被阻止,直到第一个释放锁定。然而,第二个构建已经分派给节点并使用执行器插槽。真的不好!如果我将lock()指令移到node()外面,我还没有env.NODE_NAME,所以锁定无法工作。

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

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

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

jobA的流水线中,我有:

lock(label: 'windows-agent-label', quantity: 1) {
    node('windows-agent-label') {
        //...
    }
}

运行该作业后,我得到了以下结果:

[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...

build1绝对没有任何东西运行

我的所有/lockable-resources/都是FREE的。

问题

  • 为什么找不到可用资源?我使用不当吗?
  • 我走在正确的方向上吗?

谢谢!数量1是插件文档中缺失的内容。 - CodeMonkey
1个回答

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') {
        //...
    }
}

因此,这个请求会从所有带有特定标签的锁中获取。它们总是以${NODE_NAME}-exclusive的形式组成(出于选择)。如果我无法获得资源的锁定,那么这意味着它们都被使用了。如果我得到一个锁定,那就意味着NODE_NAME(可以是build1build2等)可用。所以,我去到给定的节点。


警告:如果一个节点离线,它将获取锁,然后永远等待该节点(直到它上线)。 - Samuel GIFFARD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接