繁体   English   中英

如何通过 groovy 脚本获取正在运行的 jenkins 构建列表?

[英]How to get a list of running jenkins builds via groovy script?

有没有办法通过系统 Groovy 脚本获取 Jenkins 中正在运行的构建列表? 我尝试遍历繁忙的执行程序,但从执行程序 object 中,我无法获得构建 object:

def busyExecutors = Jenkins.instance.computers
                                .collect { 
                                  c -> c.executors.findAll { it.isBusy() }
                                }
                                .flatten() // reminder: transforms list(list(executor)) into list(executor)

busyExecutors.each { e -> 
  println('=====print out methods of executor object=======');
  println e.metaClass.methods*.name.sort().unique();

}

我也可以像这样定位我感兴趣的工作:

def item = hudson.model.Hudson.instance.getItem("my_job");
println item.metaClass.methods*.name.sort().unique(); 

但随后我将不得不循环遍历 100 秒(如果不是更多)构建并询问每个构建是否正在运行。

必须有一种更简单/更好的方法来获取正在运行的构建列表。

有很多关于如何通过系统 Groovy 脚本(其中一些是我写的)做各种事情的信息,但我不知道如何获得正在运行的构建列表:

如何使用 groovy 获取 jenkins 中当前正在运行的作业的节点名称

https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console

https://gist.github.com/dnozay/e7afcf7a7dd8f73a4e05

如何让 Jenkins/Hudson 工作监视其他一些工作并决定是否构建?

我在不使用REST API或解析XML的情况下找到了几种方法:

runningBuilds = Jenkins.instance.getView('All').getBuilds().findAll() { it.getResult().equals(null) }

这假设您没有删除或修改Jenkins中的默认“全部”视图。 当然,如果您确切知道构建将在哪个视图中,则可以替换不同的视图名称。或者您可以尝试以下方法:

runningBuilds = Jenkins.instance.getItems().collect { job->
  job.builds.findAll { it.getResult().equals(null) }
}.flatten()

虽然这种方法不需要视图名称,但它也有局限性。 它不会下降到文件夹或Multibranch Pipelines或类似的东西。 您需要手动下载到文件夹或编辑某种方式自动执行它。 例如,这是一个适用于Multibranch Pipeline的版本:

Jenkins.instance.getItemByFullName(multibranchPipelineProjectName).getItems().each { repository->
  repository.getItems().each { branch->
    branch.builds.each { build->
      if (build.getResult().equals(null)) {
        // do stuff here ...
      }
    }
  }
}

我认为使用比build.getResult().equals(null)更准确的方法来确定构建是否正在运行,但是我找不到好的API文档,所以我不确定。 这只是我发现使用对象内省工作的第一种方法。

同样由于缺乏API文档的,我不知道是否有之间的差异显著Jenkins.instance.getItems()我这里使用和Jenkins.instance.getAllItems()这是在使用这个答案

最后,请注意这些都是效率相对较低的方法。 它们遍历每个作业的每个构建,因此如果您保存了很长的构建历史(默认设置是保存每个作业只有10个构建的历史记录)或者有数千个作业,这可能需要一段时间才能运行。 请参阅如何有效地列出**使用Groovy在Jenkins上当前正在运行的所有**作业 ,以询问如何更有效地执行此任务。

这不是特别有效(但比使用API​​更有效)。 它将使用HTML链接打印出所有当前正在运行的构建。 可以在脚本控制台中运行,也可以通过脚本运行

def now = new Date()  // Get the current time
// Get a list of all running jobs
def buildingJobs = Jenkins.instance.getAllItems(Job.class).findAll { 
  it.isBuilding() }

buildingJobs.each { job->
    // Enumerate all runs
    allRuns = job._getRuns()
    allRuns.each { item ->
        // If NOT currently building... check the next build for this job
        if (!item.isBuilding()) return

        // Access and calculate time information for this build.
        def startedAt = new Date(item.getStartTimeInMillis())
        def duration_mins = ((now.getTime() - item.getStartTimeInMillis()) / 60000).intValue()

        estDurationMins = (item.getEstimatedDuration() / 60000).intValue()
        String jobname = item.getUrl()
        jobname = jobname.replaceAll('job/', '')  // Strip redundant folder info.

        println "${duration_mins.toString().padLeft(5)}/" +
            "${estDurationMins.toString().padLeft(4)}  - " +
            "<a href=${baseURL}${item.getUrl()}>${jobname}</a>"
    }
}

您可以使用REST API获取正在运行的构建列表。 使用以下网址:

http://myjenkins/jenkins/computer/api/xml?depth=1

您将获得包含<executor>元素的以下响应。 只有正在运行的构建<executor>有一个<url>元素。 另请注意, 正在运行的构建具有<idle>false</idle>值:

<computerSet>
    <busyExecutors>1</busyExecutors>
    <computer>
        ...
        <executor>
            <idle>true</idle>
            <likelyStuck>false</likelyStuck>
            <number>0</number>
            <progress>-1</progress>
        </executor>
        <executor>
            <currentExecutable>
                <number>328</number>
                <!-- This is the url from the current running build -->
                <url>http://myJenkins/jenkins/job/someJob/328/</url>             
            </currentExecutable>
            <currentWorkUnit/>
            <idle>false</idle>
            <likelyStuck>false</likelyStuck>
            <number>1</number>
            <progress>24</progress>
        </executor>
        ...
    </computer> 
<computerSet>

因此,使用带有XPath for url的REST API仅获取正在运行的构建(请注意, &wrapper参数是根xml元素的名称,以避免在XPath不匹配或返回多个节点时出错):

http://myJenkins/jenkins/computer/api/xml?depth=1&xpath=//url&wrapper=builds

你会得到类似的东西:

<builds>
    <url>
http://myJenkins/jenkins/job/someJob/300/
    </url>
    <url>
http://myJenkins/jenkins/job/another/332/
    </url>
</builds>

因此,在Groovy中,您可以获取REST API,解析返回的Xml,然后将regex应用于每个<url>以从运行的构建中获取数据:

// get the xml from the rest api
def builds = 'http://myJenkins/jenkins/computer/api/xml?depth=1&xpath=//url&wrapper=builds'.toURL().text
// parse the xml result
def xml = new XmlSlurper().parseText(builds)
// for each url get the job name
def jobNames = xml.url.collect{ url ->
    // regex to get the jobName and a build number
    def group = (url =~ /.*\/job\/([^\/]+)\/(\d+)/)
    println group[0] // [http://myJenkins/jenkins/job/someJob/300, someJob, 300]
    def jobName = group[0][1]
    return jobName
    // to get the build number
    // def buildNr = group[0][2]
}
println jobNames

用于快速查看所有构建、排队和进行中的快速命令。

curl 'https://jenkins.example.com/computer/api/json?depth=1' | jq. | grep url | sort -h

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM