詹金斯锁标签

时间:2019-02-19 10:49:38

标签: jenkins jenkins-pipeline jenkins-plugins

我要实现的目标

  • 我有jobA,在一台计算机上需要1个执行程序。
  • 我有jobB,在同一台计算机上需要2个执行程序,在X台计算机上需要1个执行程序。
  • 我希望他们能够使用相同的计算机(虽然不能同时使用)->他们目前使用的是不同的计算机。
  • 他们的所有任务都使用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]

第2次(第一个仍在建设中):

[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 个答案:

答案 0 :(得分:0)

解决方案

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等)。所以,我转到给定的节点。