我使用Jenkins服务器的轮询解决了这个问题。当远程启动作业时,返回头中会包含作业队列URL。利用这个URL,可以进行更多的API调用以获取状态。
步骤:
- 启动作业
- 解析返回的 'Location' 头
- 轮询队列以查找要启动的作业
- 作业队列条目在其JSON或XML中具有带有作业编号的 'executable' 条目,一旦启动即可显示
- 轮询作业状态等待结果
我使用Python和Requests模块完成了这个过程。
import requests
import re
import sys
import json
import time
QUEUE_POLL_INTERVAL = 2
JOB_POLL_INTERVAL = 20
OVERALL_TIMEOUT = 3600
auth_token = 'buildmaster:173223588624f980c3AAA68d4d8efe0c'
jenkins_uri = '192.168.115.187:8080'
job_name = 'rf_systest'
build_token = 'rf_systest_auth_token'
start_build_url = 'http://{}@{}/job/{}/build?token={}'.format(
auth_token, jenkins_uri, job_name, build_token)
r = requests.post(start_build_url)
m = re.match(r"http.+(queue.+)\/", r.headers['Location'])
if not m:
print "Job starte request did not have queue location"
sys.exit(1)
queue_id = m.group(1)
job_info_url = 'http://{}@{}/{}/api/json'.format(auth_token, jenkins_uri, queue_id)
elasped_time = 0
print '{} Job {} added to queue: {}'.format(time.ctime(), job_name, job_info_url)
while True:
l = requests.get(job_info_url)
jqe = l.json()
task = jqe['task']['name']
try:
job_id = jqe['executable']['number']
break
except:
time.sleep(QUEUE_POLL_INTERVAL)
elasped_time += QUEUE_POLL_INTERVAL
if (elasped_time % (QUEUE_POLL_INTERVAL * 10)) == 0:
print "{}: Job {} not started yet from {}".format(time.ctime(), job_name, queue_id)
job_url = 'http://{}@{}/job/{}/{}/api/json'.format(auth_token, jenkins_uri, job_name, job_id)
start_epoch = int(time.time())
while True:
print "{}: Job started URL: {}".format(time.ctime(), job_url)
j = requests.get(job_url)
jje = j.json()
result = jje['result']
if result == 'SUCCESS':
print "{}: Job: {} Status: {}".format(time.ctime(), job_name, result)
break
elif result == 'FAILURE':
print "{}: Job: {} Status: {}".format(time.ctime(), job_name, result)
break
elif result == 'ABORTED':
print "{}: Job: {} Status: {}".format(time.ctime(), job_name, result)
break
else:
print "{}: Job: {} Status: {}. Polling again in {} secs".format(
time.ctime(), job_name, result, JOB_POLL_INTERVAL)
cur_epoch = int(time.time())
if (cur_epoch - start_epoch) > OVERALL_TIMEOUT:
print "{}: No status before timeout of {} secs".format(OVERALL_TIMEOUT)
sys.exit(1)
time.sleep(JOB_POLL_INTERVAL)
输出:
Tue Jan 30 16:24:08 2018: Job rf_systest added to queue: http://buildmaster:173223588624f980c344668d4d8efe0c@192.168.115.187:8080/queue/item/164/api/json
Tue Jan 30 16:24:39 2018: Job rf_systest not started yet from queue/item/164
Tue Jan 30 16:25:00 2018: Job started URL: http://buildmaster:173223588624f980c344668d4d8efe0c@192.168.115.187:8080/job/rf_systest/79/api/json
Tue Jan 30 16:25:01 2018: Job: rf_systest Status: None. Polling again in 20 secs
Tue Jan 30 16:25:21 2018: Job started URL: http://buildmaster:173223588624f980c344668d4d8efe0c@192.168.115.187:8080/job/rf_systest/79/api/json
Tue Jan 30 16:25:21 2018: Job: rf_systest Status: None. Polling again in 20 secs
Tue Jan 30 16:25:41 2018: Job started URL: http://buildmaster:173223588624f980c344668d4d8efe0c@192.168.115.187:8080/job/rf_systest/79/api/json
Tue Jan 30 16:25:41 2018: Job: rf_systest Status: None. Polling again in 20 secs
Tue Jan 30 16:26:01 2018: Job started URL: http://buildmaster:173223588624f980c344668d4d8efe0c@192.168.115.187:8080/job/rf_systest/79/api/json
Tue Jan 30 16:26:01 2018: Job: rf_systest Status: None. Polling again in 20 secs
Tue Jan 30 16:26:21 2018: Job started URL: http://buildmaster:173223588624f980c344668d4d8efe0c@192.168.115.187:8080/job/rf_systest/79/api/json
Tue Jan 30 16:26:21 2018: Job: rf_systest Status: SUCCESS
一旦Jenkins队列的作业开始,就从中获取JSON:
{
"_class": "hudson.model.Queue$LeftItem",
"actions": [
{
"_class": "hudson.model.CauseAction",
"causes": [
{
"_class": "hudson.model.Cause$RemoteCause",
"addr": "10.20.30.60",
"note": null,
"shortDescription": "Started by remote host 10.20.30.60"
}
]
}
],
"blocked": false,
"buildable": false,
"cancelled": false,
"executable": {
"_class": "org.jenkinsci.plugins.workflow.job.WorkflowRun",
"number": 45,
"url": "http://192.168.115.187:8080/job/rf_systest/45/"
},
"id": 95,
"inQueueSince": 1517342648136,
"params": "",
"stuck": false,
"task": {
"_class": "org.jenkinsci.plugins.workflow.job.WorkflowJob",
"color": "blue_anime",
"name": "rf_systest",
"url": "http://192.168.115.187:8080/job/rf_systest/"
},
"url": "queue/item/95/",
"why": null
}
while True:
中花费的时间。 (我的默认值为5秒) - Maartic:\temp>py test.py Traceback (most recent call last): File "c:\temp\test.py", line 3, in <module> import requests ModuleNotFoundError: No module named 'requests'
- sero