简体   繁体   English

从队列 ID 中获取 Jenkins 作业构建 ID

[英]Get Jenkins Job Build ID from Queue ID

I'm successfully able to use this to kick off a Jenkins Job:我成功地能够使用它来启动 Jenkins 工作:

curl -X POST "http://jenkins_srv:8080/job/MY_JOB/buildwithParameters?this=1&that=2" --user name:pass

I can also get the consoleText from this job using:我还可以使用以下方法从这项工作中获取 consoleText:

curl -X POST "http://jenkins_srv:8080/job/MY_JOB/lastBuild/consoleText"

However, this doesn't scale if I run multiple jobs back to back.但是,如果我背靠背运行多个作业,这不会扩展。 I've noticed that the first curl command has a return that includes:我注意到第一个 curl 命令的返回包括:

Location: http://jenkins_srv:8080/queue/item/123/

I'm assuming that 123 is the job queue id.我假设123是作业队列 ID。

My question is, if I queue jobs 121 , 122 , & 123 back to back, what do I use to check the status of job queue item 122 ?我的问题是,如果我将作业121122123背靠背排队,我用什么来检查作业队列项122的状态? Also, what do I use to determine the actual build id that eventually resulted from job queue item 122 ?另外,我用什么来确定最终由作业队列项122产生的实际构建 ID?

I chose Kdawg's answer, because it helped lead me in the direction that I needed.我选择了 Kdawg 的答案,因为它帮助我朝着我需要的方向前进。 Thank you!谢谢!

I'm also including my own answer, because the solution I implemented was different than Kdawg's answer, and I feel it will add value for other people.我还包括我自己的答案,因为我实施的解决方案与 Kdawg 的答案不同,我觉得它会为其他人增加价值。

First off, I'm new to Jenkins.首先,我是詹金斯的新手。 So if I misspeak, please feel free to correct me.所以如果我说错了,请随时纠正我。 Second, I had a slight learning curve in that there is a difference between a Jenkins "queue item" and a Jenkins "build job".其次,我有一个轻微的学习曲线,因为 Jenkins“队列项目”和 Jenkins“构建工作”之间存在差异。 The instant that a "queue item" has been created, there is no "build job" ID, because no build job has started.创建“队列项”的那一刻,就没有“构建作业”ID,因为没有构建作业开始。 Also, once a build job has started, the queue item has 5 minutes before it is deleted.此外,一旦构建作业开始,队列项在删除前有 5 分钟的时间。

When I perform these tasks:当我执行这些任务时:

curl -X POST "http://jenkins_srv:8080/job/MY_JOB/buildwithParameters?this=1&that=2" --user name:pass
curl -X POST "http://jenkins_srv:8080/job/MY_JOB/buildwithParameters?this=1&that=2" --user name:pass
curl -X POST "http://jenkins_srv:8080/job/MY_JOB/buildwithParameters?this=1&that=2" --user name:pass

Jenkins will schedule 3 build jobs to be run in a queue. Jenkins 将安排 3 个构建作业在队列中运行。 These will be "queue items".这些将是“队列项目”。 These "queue items" will have a "Queue ID".这些“队列项目”将具有“队列 ID”。 In the example given in my original question, lets suppose that these three curl commands create "queue items" with "Queue ID"s 121 , 122 , & 123 .在我的原始问题中给出的示例中,假设这三个 curl 命令使用“队列 ID” 121122123创建“队列项”。

Why is this important?为什么这很重要?

Because depending on the load of your Jenkins server, the item that was queued may or may not be run immediately.因为根据 Jenkins 服务器的负载,排队的项目可能会也可能不会立即运行。 If it runs immediately, then Kdawg's answer is definitely correct.如果它立即运行,那么 Kdawg 的答案肯定是正确的。 Running his commands:运行他的命令:

curl -X GET http://jenkins_srv:8080/queue/item/121/api/json?pretty=true --user name:pass
curl -X GET http://jenkins_srv:8080/queue/item/122/api/json?pretty=true --user name:pass
curl -X GET http://jenkins_srv:8080/queue/item/123/api/json?pretty=true --user name:pass

This will get queue information about each "queue item", and in what returns, there is definitely a way to obtain a "build job" ID, if the build job has started.这将获得有关每个“队列项”的队列信息,并且在返回的内容中,如果构建作业已经开始,肯定有一种方法可以获得“构建作业”ID。 If a build job has not yet started, this information will be blank.如果构建作业尚未开始,则此信息将为空白。

Here's the additional part that, I feel, adds value.这是我觉得增加价值的附加部分。

Once a build job has started, the information in Kdawg's answer will be populated in the response to the three curl -X GET commands.构建作业开始后,Kdawg 的回答中的信息将填充到三个curl -X GET命令的响应中。 Also, by default, Jenkins is designed to scavenge (garbage collection, choose your own term) the "queue item"s every 5 minutes.此外,默认情况下,Jenkins 旨在每 5 分钟清除一次(垃圾收集,选择您自己的术语)“队列项”。 So in other words, if all you have is a "queue item" ID and the 5 minute data retention window passes, then you need another mechanism in order to get a "build job" ID from a "queue item" ID.因此,换句话说,如果您拥有的只是“队列项”ID 并且 5 分钟数据保留窗口过去了,那么您需要另一种机制来从“队列项”ID 中获取“构建作业”ID。

So, in my case, I'm using Jenkins as a front end, and Ansible on the back end to perform server configuration and application deployments.因此,就我而言,我使用 Jenkins 作为前端,使用 Ansible 作为后端来执行服务器配置和应用程序部署。 Some of these application deployments can take 30 minutes or more, well beyond the 5 minute data retention period of the "queue items".其中一些应用程序部署可能需要 30 分钟或更长时间,远远超过“队列项目”的 5 分钟数据保留期。

So the problem that I had to solve, if all I have is a "queue item" ID, then how do I find a "build job" ID, regardless of when I'm checking, seconds later or hours later?所以我必须解决的问题是,如果我只有一个“队列项目”ID,那么我如何找到“构建作业”ID,无论我什么时候检查,几秒钟后或几小时后?

Here was my solution (Note that I required XML output, FYI).这是我的解决方案(请注意,我需要 XML 输出,仅供参考)。

I ran this command:我运行了这个命令:

curl -X POST "http://jenkins_srv:8080/job/MY_JOB/buildwithParameters?this=1&that=2" --user name:pass

This command would return this information:此命令将返回以下信息:

Runtime responseHeaders Date: Day, ## Non Year xx:yy:zz GMT
X-Content-Type-Options: nosniff
Location: http://jenkins_srv:port/queue/item/123/
Content-Length: 0
Server: Jetty(9.4.z-SNAPSHOT)

From here, I can parse out 123 from the Location field.从这里,我可以从Location字段中解析出123

I then slept for 10 seconds.然后我睡了10秒钟。 After the sleep, I run this command on a 10 second loop:睡眠后,我在 10 秒的循环中运行此命令:

curl -X GET http://jenkins_srv:8080/queue/item/123/api/xml

I did that until I either:我这样做直到我:

  1. I got a queue item return that included the xpath //executable/number that's shown in Kdawg's example, or我得到了一个队列项返回,其中包括 Kdawg 示例中显示的 xpath //executable/number,或者
  2. I got HTML 404 status code for more than 10 minutes, meaning the job hasn't been queue'd yet or I passed the 5 minute data retention window.我收到 HTML 404 状态代码超过 10 分钟,这意味着该作业尚未排队,或者我已超过 5 分钟的数据保留窗口。

The loop in this way handles a burdened Jenkins server that's sluggish on handling queue requests.以这种方式的循环处理负担重的 Jenkins 服务器,该服务器在处理队列请求时反应迟缓。 So presumably if I get to the end of 10 minutes, then my approach will still handle the use case that my automation approach has successfully queue'd and run the job, but it's checking Jenkins outside the data retention window.所以大概如果我到了 10 分钟的末尾,那么我的方法仍然会处理我的自动化方法已成功排队并运行作业的用例,但它正在检查数据保留窗口之外的 Jenkins。 In this case, I would run this command:在这种情况下,我将运行以下命令:

curl -X GET http://jenkins_srv:port/job/MY_JOB/api/xml?tree=builds[id,number,result,queueId]&xpath=//build[queueId=123]

This returns the XML info for any "build job" that also contains a queueId of 123 , as shown below:这将返回包含queueId123任何“构建作业”的 XML 信息,如下所示:

<?xml version="1.0"?>
    <build _class="hudson.model.FreeStyleBuild">
        <id>456</id>
        <number>456</number>
        <queueId>123</queueId>
        <result>SUCCESS</result>
    </build>

In this way, I was able to authoritatively get a "build job" ID while only having a "queue item" ID regardless of the time difference between when I started and when I checked back.通过这种方式,我能够权威地获得一个“构建作业”ID,而只有一个“队列项”ID,而不管我开始和检查之间的时间差。

Assuming that you have a location of http://jenkins_srv:8080/queue/item/123/ , you can GET http://jenkins_srv:8080/queue/item/123/api/json?pretty=true to return information about that queue item (you can also not include ?pretty=true if you don't care about formatting, or use api/xml if you want the results in XML).假设你有一个位置http://jenkins_srv:8080/queue/item/123/ ,你可以GET http://jenkins_srv:8080/queue/item/123/api/json?pretty=true来返回有关的信息该队列项(如果您不关心格式,您也可以不包含?pretty=true ,或者如果您想要 XML 格式的结果,则使用api/xml )。

I don't know if there's standard documentation on the queue API, but it appears that if the queue item has completed (maybe also if it's currently being built?) it will have an executable node.我不知道是否有关于队列 API 的标准文档,但似乎如果队列项已完成(也许当前正在构建?)它将有一个executable节点。 One for my server looked like this:我的服务器的一个看起来像这样:

"executable" : {
    "_class" : "org.jenkinsci.plugins.workflow.job.WorkflowRun",
    "number" : 10,
    "url" : "http://192.168.99.100:32769/job/configure/10/"
}

You can then GET the API for the URL specified in executable.url .然后,您可以为executable.url指定的 URL GET API。 In my case, GET http://192.168.99.100:32769/job/configure/10/api/json?pretty=true .就我而言, GET http://192.168.99.100:32769/job/configure/10/api/json?pretty=true From there, you should have all the information you need, including whether or not the build is currently being built, how long the build took/has taken, the result, etc.从那里,您应该拥有所需的所有信息,包括当前是否正在构建构建、构建花费/已经花费了多长时间、结果等。

Also, if you want information on your entire build queue, you can GET http://jenkins_srv:8080/queue/api/json?pretty=true此外,如果您想了解整个构建队列的信息,您可以GET http://jenkins_srv:8080/queue/api/json?pretty=true

Astonishing that Jenkins doesn't track a request to its conclusion with a unique ID.令人惊讶的是 Jenkins 没有使用唯一 ID 跟踪请求到其结论。

One element that persists between the queued item and the build item is the list of parameters.在排队项和构建项之间持续存在的一个元素是参数列表。 If you have the ability/authority to change the config of the jobs, then add an optional parameter REQUEST_ID that the client plucks from the air (eg a UUID) and passes in over REST.如果您有能力/权限更改作业的配置,则添加客户端从空中提取的可选参数 REQUEST_ID(例如 UUID)并通过 REST 传递。 Then you can quiz the queue and look for the one with your REQUEST_ID, and you can quiz the list of builds and look for the one with your REQUEST_ID.然后,您可以测验队列并查找具有您的 REQUEST_ID 的那个,并且您可以测验构建列表并查找具有您的 REQUEST_ID 的那个。

There's an interesting thing about this that if you want to queue multiple builds in the loop, you might end up getting SAME QUEUE_ID, This happens especially when you have the same parameter and queued builds have not started up.有一个有趣的事情是,如果您想在循环中对多个构建进行排队,您最终可能会得到相同的 QUEUE_ID,尤其是当您具有相同的参数并且排队的构建尚未启动时,会发生这种情况。 Basically, Jenkins assumes that you are just trying to build this and instead of multiple builds it just assumes that it needs to spin up only a single build, hence the SAME QUEUE_ID, To overcome this, if you add an extra parameter while building the job like UQ_ID=CURRENT_TIMESTAMP (This param doesn't need to be in build) then you will get the unique build number基本上,Jenkins 假设您只是在尝试构建它,而不是多个构建,它只是假设它只需要启动一个构建,因此使用相同的 QUEUE_ID,为了克服这个问题,如果您在构建作业时添加额外的参数像 UQ_ID=CURRENT_TIMESTAMP (此参数不需要在构建中)然后您将获得唯一的构建号

If there's no param at all in the build you should define at least one param, Because parameterless build won't allow ANY parameter to be passed in the api如果构建中根本没有参数,您应该至少定义一个参数,因为无参数构建不允许在 api 中传递任何参数

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

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