I have a script to trigger a job on Jenkins remotely using a token. Here is my script:
JENKINS_URL='http://jenkins.myserver.com/jenkins'
JOB_NAME='job/utilities/job/my_job'
JOB_TOKEN='my_token'
curl "${JENKINS_URL}/${JOB_NAME}/buildWithParameters?token=${JOB_TOKEN}"
After I run it, I get following response:
* Hostname was NOT found in DNS cache
* Trying 10.5.187.225...
* Connected to jenkins.myserver.com (10.5.187.225) port 80 (#0)
> GET /jenkins/job/utilities/job/my_job/buildWithParameters?token=my_token HTTP/1.1
> User-Agent: curl/7.37.1
> Host: jenkins.myserver.com
> Accept: */*
>
< HTTP/1.1 201 Created
* Server nginx/1.6.2 is not blacklisted
< Server: nginx/1.6.2
< Date: Tue, 03 Feb 2015 23:40:47 GMT
< Content-Length: 0
< Location: http://jenkins.myserver.com/jenkins/queue/item/91/
< Connection: keep-alive
< Cache-Control: private
< Expires: Wed, 31 Dec 1969 16:00:00 PST
<
* Connection #0 to host jenkins.myserver.com left intact
I noticed that it returns the queue url in the header: http://jenkins.myserver.com/jenkins/queue/item/91. But I don't know how I should use this return url.
1) I am wondering if anyone knows how I can check the status for the job that I just created?
2) Since the above response does not return the job #, I can't really use this api call:
curl http://jenkins.myserver.com/jenkins/job/utilities/job/my_job/8/api/json
to check for status. So where can I get the job name and job number after I get the location url from the above response?
Thanks
Create a remote Jenkins build trigger in three stepsCreate a Jenkins build job and enable the Trigger builds remotely checkbox. Provide an authentication token; This can be any text string of your choice. Invoke the Jenkins build URL to remotely trigger the build job.
Install Generic Webhook Trigger plugin. Select generic webhook trigger in build trigger actions. Generate a random string and paste in token. Now your job can be triggered with a http request to the following url.
In the new Jenkins Pipeline, under Build Triggers, select the checkbox Trigger builds remotely (e.g., from scripts). Then give Jenkins a token that will be required when triggering the build.
The most common use cases are triggering a build from a scheduler or another automated job. Here in this post we’ll see how we can trigger a job on a remote Jenkins server. To trigger a build, we simply need to http POSTto the specific job API. POST to the buildAPI for simple builds, and to buildWithParametersfor the jobs that need some parameters.
In order to get the status of the build, you must follow the three steps below. Jenkins build, once triggered, will have the below flow: Job Triggered->Waits on Queue (Queue Number)->assign node for the build -> gets a Build Number STEP 3: Get the Build Number
You’ll need to use the “user-api-token”for authentication Job-authentication-token is an authorization token per job. For that, first you have to enable remote trigger of jobs from “Jenkins » Project » Job » Configure » Trigger builds remotely”.
Jenkinsis one of the oldest & most popular CI (Continuous Integration) servers, and many teams still configure and run their daily and ad-hoc build jobs with Jenkins. The build workflows, or simply jobs, are set of runnable commands that generally executes a complete CI-build.
I solved this problem using polling of the Jenkins server. When a job is started remotely the return headers has the job queue URL. Using this one can make more API calls to get status.
Steps:
I used python and the Requests module to do this
#!/usr/bin/python
import requests
import re
import sys
import json
import time
# secs for polling Jenkins API
#
QUEUE_POLL_INTERVAL = 2
JOB_POLL_INTERVAL = 20
OVERALL_TIMEOUT = 3600 # 1 hour
# job specifics: should be passed in
auth_token = 'buildmaster:173223588624f980c3AAA68d4d8efe0c'
jenkins_uri = '192.168.115.187:8080'
job_name = 'rf_systest'
build_token = 'rf_systest_auth_token'
# start the build
#
start_build_url = 'http://{}@{}/job/{}/build?token={}'.format(
auth_token, jenkins_uri, job_name, build_token)
r = requests.post(start_build_url)
# from return headers get job queue location
#
m = re.match(r"http.+(queue.+)\/", r.headers['Location'])
if not m:
# To Do: handle error
print "Job starte request did not have queue location"
sys.exit(1)
# poll the queue looking for job to start
#
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:
#print "no job ID yet for build: {}".format(task)
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)
# poll job status waiting for a result
#
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':
# Do success steps
print "{}: Job: {} Status: {}".format(time.ctime(), job_name, result)
break
elif result == 'FAILURE':
# Do failure steps
print "{}: Job: {} Status: {}".format(time.ctime(), job_name, result)
break
elif result == 'ABORTED':
# Do aborted steps
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)
Output:
Tue Jan 30 16:24:08 2018: Job rf_systest added to queue: http://buildmaster:[email protected]: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:[email protected]: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:[email protected]: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:[email protected]: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:[email protected]: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:[email protected]:8080/job/rf_systest/79/api/json
Tue Jan 30 16:26:21 2018: Job: rf_systest Status: SUCCESS
JSON from a Jenkins queue once its job has started:
{
"_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
}
I had similar problem to get state with rest api only.
this was my solution (it is a weak and not stable solution!):
#Ex. http://jenkins.com/job/test
JOB_URL="${JENKINS_URL}/job/${JOB_NAME}"
#here you can ask for next build job number
function getNextBuildNr(){
curl --silent ${JOB_URL}/api/json | grep -Po '"nextBuildNumber":\K\d+'
}
# this will request the Status of job
function getBuildState(){
buildNr=$1
curl --silent ${JOB_URL}/${buildNr}/api/json | grep -Po '"result":\s*"\K\w+'
}
#this will wait for your Job state, by polling Jenkins every second
function waitForJob() {
buildNr=$1
state=""
while [ "${state}" == "" ]
do
sleep 1
state=$(getBuildState ${buildNr})
echo -n '.'
done
echo -e "\n"
}
#now you can run and build
BUILD_NR=$(getNextBuildNr)
# input here your code/function to trigger the job
waitForJob ${BUILD_NR}
BUILD_STATE=$(getBuildState ${BUILD_NR})
echo "$BUILD_STATE"
You can use Jenkins API for this. A sample Python script:
import json
import requests
import time
job_name = "testjob" . #Give your job name here
def jenkins_job_status(job_name):
try:
url = "https://your_jenkins_endpoint/job/%s/lastBuild/api/json" %job_name #Replace 'your_jenkins_endpoint' with your Jenkins URL
while True:
data = requests.get(url).json()
if data['building']:
time.sleep(60)
else:
if data['result'] == "SUCCESS":
print "Job is success"
return True
else:
print "Job status failed"
return False
except Exception as e:
print str(e)
return False
if __name__ == "__main__":
if jenkins_job_status(job_name):
print "Put your autmation here for 'job is success' condition"
else:
print "Put your autmation here for 'job is failed' condition"
Refer http://www.easyaslinux.com/tutorials/devops/how-to-check-build-status-of-jenkins-job-using-python-script/ for detailed explanation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With