23

我正在创建一个 Jenkins 管道作业,我需要在标有特定标签的所有节点上运行一个作业。

因此,我试图获取分配有特定标签的节点名称列表。(有了一个节点,我可以得到标签getAssignedLabels()

中的nodes-listjenkins.model.Jenkins.instance.nodes似乎不包含我需要在搜索中包含的主节点。

我目前的解决方案是迭代jenkins.model.Jenkins.instance.computers并使用getNode()- 方法来获取节点。这可行,但在 Jenkins 的 javadoc 中,我正在阅读此列表可能不是最新的。

从长远来看,我会(动态地)添加云节点,我担心那时我将无法使用computers

获取所有当前节点列表的正确方法是什么?

这就是我现在正在做的事情:

@NonCPS
def nodeNames(label) {
    def nodes = []
    jenkins.model.Jenkins.instance.computers.each { c ->
        if (c.node.labelString.contains(label)) {
            nodes.add(c.node.selfLabel.name)
        }
    }   
    return nodes
}
4

9 回答 9

14

更新的答案:在管道中用于nodesByLabel获取分配给标签的所有节点。

于 2019-04-30T08:00:55.580 回答
13

这就是我现在正在做的方式。我还没有找到其他东西:

@NonCPS
def hostNames(label) {
  def nodes = []
  jenkins.model.Jenkins.get.computers.each { c ->
    if (c.node.labelString.contains(label)) {
      nodes.add(c.node.selfLabel.name)
    }
  }
  return nodes
}

jenkins.model.Jenkins.get.computers包含主节点和所有从节点。

于 2018-04-03T08:36:05.783 回答
6

更新到@patrick-b 答案:如果您的标签包含相同的字符串,则包含可能是错误的,我添加了一个拆分步骤,检查每个用空格分隔的标签。

@NonCPS
def hostNames(label) {
    def nodes = []
    jenkins.model.Jenkins.get.computers.each { c ->
        c.node.labelString.split(/\s+/).each { l ->
            if (l != null && l.equals(label)) {
                nodes.add(c.node.selfLabel.name)
             }
        }
    }

    return nodes
}
于 2019-01-11T11:02:56.820 回答
5

这是一个更具可读性和简洁性的功能解决方案:

def nodes = jenkins.model.Jenkins.get().computers
  .findAll{ it.node.labelString.contains(label) }
  .collect{ it.node.selfLabel.name }

您可以在 Jenkins Script Console中验证它。

于 2020-09-28T17:04:47.017 回答
1

尝试使用 for (aSlave in hudson.model.Hudson.instance.slaves) {}andaSlave.getLabelString());获取所有节点的所有标签。您可以通过这种方式为每个标签构建一个节点列表。

于 2017-10-25T20:01:35.863 回答
1

我认为你可以这样做:

def nodes = Jenkins.get.getLabel('my-label').getNodes()
for (int i = 0; i < nodes.size(); i++) {
    node(nodes[i].getNodeName()) {
        // on node
    }
}

我不确定这是否适用于云节点。

于 2018-11-22T10:45:07.470 回答
1

nodesByLabel在大多数情况下,@towel 指出的使用可能是解决方案。我发现的一个限制nodesByLabel 是没有办法不加选择地选择所有节点。由于脚本安全性,我也不能使用任何其他解决方案,其中一些可能非常危险,所以我宁愿不批准它们的使用。

或者,您可以添加一个函数作为管道库,这将允许使用这些函数。由于可以设置管道库,因此它们完全在管理员的控制之下,因此使用这条路线更安全。为此,请设置一个管道库(我认为它是否是全球性的并不重要,但对我来说确实如此)。然后将以下内容添加到文件中vars/parallelRunOnNodes.groovy

def call(Closure callback) {
    parallel jenkins.model.Jenkins.get().computers.collectEntries { agent ->
        def nodeLabel = agent.node.selfLabel.name
        ["${nodeLabel}": {
            node("${nodeLabel}") {
                stage("${nodeLabel}") {
                    callback(nodeLabel)
                }
            }
        }]
    }
}

然后可以按如下方式使用:

pipeline {
    agent none
    stages {
        stage('Parallel on all nodes') {
            steps {
                parallelRunOnNodes { nodeLabel ->
                    println(nodeLabel)
                }
            }
        }
    }
}

显然可以根据需要进行调整,例如,您可以添加其他参数来过滤,也许您不关心并行等。

于 2021-05-10T10:27:15.113 回答
0

这是我的答案

String labelIWantServersOf = "XXXX"; // This is the label assosiated with nodes for which i want the server names of
List serverList = [];

for (aSlave in hudson.model.Hudson.instance.slaves) {          
  if (aSlave.getLabelString().indexOf(labelIWantServersOf ) > -1) {
     if(!aSlave.getComputer().isOffline() ){
          serverList.add(aSlave.name);        
     }
  }    
}

return serverList;
于 2021-04-16T15:00:11.357 回答
-2

这是关于如何在 Jenkins 服务器上列出节点的热门 Google 热门文章之一。如果您只是在寻找节点列表,可以在以下服务器 URL 中查看:

http://JENKINS_HOSTNAME:JENKINS_PORT/computer/

结果是一个表格,显示已知节点的名称、操作系统、JVM 版本、时钟同步状态、远程处理版本和响应时间。它还显示节点图像(好吧,JAR)是否明显过时或受到错误/安全警报的影响。

如果无法访问 API 调用,则始终可以抓取和解析 URL,以获取节点列表和表中包含的任何其他数据。

于 2021-06-09T18:14:47.943 回答