有没有办法通过System Groovy脚本获取Jenkins中的RUNNING构建列表? 我尝试循环繁忙的执行程序,但是从执行程序对象,我无法获得构建对象:
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();
}
我也可以定位我感兴趣的JOB:
def item = hudson.model.Hudson.instance.getItem("my_job");
println item.metaClass.methods*.name.sort().unique();
然后我将不得不循环遍历100s(如果不是更多)构建并询问每个构建是否正在运行。
必须有一种更简单/更好的方法来获取正在运行的构建列表。
有很多关于如何通过System Groovy Scripts(其中一些我写过)做各种事情的信息,但我无法弄清楚如何获得正在运行的构建列表:
https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console
https://gist.github.com/dnozay/e7afcf7a7dd8f73a4e05
How to make a Jenkins/Hudson job surveil some others jobs and decide whether to build or not?
{{3}}
答案 0 :(得分:8)
我发现了几种不使用REST API或解析XML的方法:
runningBuilds = Jenkins.instance.getView('All').getBuilds().findAll() { it.getResult().equals(null) }
这假设您没有删除或修改默认"全部"詹金斯的视图。当然,如果你确切知道你的构建将在哪个视图中,你可以替换不同的视图名称。或者你可以尝试这种方法:
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()
与{{3}中使用的Jenkins.instance.getAllItems()
之间是否存在显着差异}}
最后,请注意这些都是效率相对较低的方法。它们遍历每个作业的每个构建,因此如果您保存了很长的构建历史(默认设置是保存每个作业只有10个构建的历史记录)或者有数千个作业,这可能需要一段时间才能运行。有关如何更有效地执行此任务的问题,请参阅this answer。
答案 1 :(得分:3)
这不是特别有效(但比使用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>"
}
}
答案 2 :(得分:1)
您可以使用REST API获取正在运行的构建列表。使用以下网址:
http://myjenkins/jenkins/computer/api/xml?depth=1
您将收到包含<executor>
元素的关注响应。只有正在运行的版本在<url>
中有一个<executor>
元素。另请注意,正在运行的版本具有<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>
因此,使用REST API和url
的 XPath 来仅获取正在运行的构建(请注意,&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