如何获取分配了包含主节点的标签的所有Jenkins节点的列表?

时间:2017-10-25 13:26:50

标签: jenkins jenkins-pipeline jenkins-groovy

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

因此,我试图获取一个分配了某个标签的节点名称列表。 (对于节点,我可以使用getAssignedLabels()

获取标签

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

我目前的解决方案是迭代jenkins.model.Jenkins.instance.computers并使用getNode() - 方法获取节点。这是有效的,但在詹金斯的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
}

9 个答案:

答案 0 :(得分:6)

这就是我现在正在做的事情。我还没找到别的东西:

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

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

答案 1 :(得分:2)

更新为@ patrick-b答案:如果您的标签包含相同的字符串,则包含可能会出错,我添加了一个拆分步骤,请检查每个标签之间是否包含空格 @NonCPS def hostNames(label) { def nodes = [] jenkins.model.Jenkins.instance.computers.each { c -> c.node.labelString.split(' ').each { l -> if (l != null && l.equals(label)) { nodes.add(c.node.selfLabel.name) } } } return nodes }

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

我认为您可以执行以下操作:

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

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

答案 5 :(得分:0)

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

tb.eval(q"""
  import io.circe.generic.auto._
  import io.circe.parser.decode
  val classInstance = decode[$classType]($json)

  import shapeless.Generic
  Generic[$classType].to(classInstance.toOption.get).tupled
""").asInstanceOf[Product] //(susan,25)

您可以在Jenkins Script Console中进行验证。

答案 6 :(得分: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;

答案 7 :(得分:0)

使用@towel 指出的 switch (language) { case "en-GB": sql ="select col1id,col2id,col3id,descriptions_en,col2description_en,col3iddescription_en from product_by_cols"; break; case "nb-NO": sql ="select col1id,col2id,col3id,descriptions_nb,col2description_nb,col3iddescription_nb from product_by_cols"; break; case "nn-NO": sql ="select col1id,col2id,col3id,descriptions_bn,col2description_bn,col3iddescription_nn from product_by_cols"; break; } var ps = Service.Session.Prepare(sql); // Disable automatic paging. var statement = ps .Bind() .SetAutoPage(false) .SetPageSize(pageSize ?? 500); if (pageState != null && pageState.Length > 0) { statement.SetPagingState(Convert.FromBase64String(pageState)); } // Execute a query on a connection synchronously var rs =await Service.Session.ExecuteAsync(statement); // Store the paging state List<CustomProduct> dbProducts = new List<CustomProduct>(); // Iterate through the RowSet foreach (var row in rs) { dbProducts.Add(new CustomProduct { Col1Descriptions = row.GetValue<string>("descriptions_en"), Col1Id = row.GetValue<int>("col1id"), Col2Description = row.GetValue<string>("col2description_en"), Col2Id = row.GetValue<int>("col2id"), Col3Description = row.GetValue<string>("col3iddescription_en"), Col3Id = row.GetValue<int>("col3id") }); } return new PagedResultWrapper<ICollection<CustomProduct>>(pageSize ?? 500, rs.PagingState,dbProducts ); 可能是大多数情况下的解决方案。我发现 nodesByLabel 的一个限制是无法不加选择地选择所有节点。由于脚本安全,我无法使用任何其他解决方案,其中一些可能非常危险,所以我宁愿不批准它们的使用。

或者,您可以添加一个函数作为管道库,这将允许使用这些函数。由于可以设置管道库,使它们完全在管理员的控制之下,因此采用这条路线会更安全。为此,请设置一个管道库(我认为它是否是全局的并不重要,但对我来说是)。然后将以下内容添加到文件 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)
                }
            }
        }]
    }
}

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

答案 8 :(得分:-1)

添加此内容是因为它是最热门的搜索结果之一。我不确定这个未记录的 URL 是何时添加的,但可以在以下 URL 中查看所有已知节点(至少在最近的 Jenkins 版本中):

http://JENKINS_HOSTNAME:JENKINS_PORT/computer/

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

如果您在 Jenkins 之外工作,则可以抓取和解析 URL 以获取节点列表。