Check Jenkins job status after triggering a build remotely

前端 未结 4 826
夕颜
夕颜 2020-12-10 02:39

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/uti         


        
相关标签:
4条回答
  • 2020-12-10 02:57

    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

    0 讨论(0)
  • 2020-12-10 03:01

    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"
    
    0 讨论(0)
  • 2020-12-10 03:07

    When you trigger a job, the job is placed into the queue. The actual build is created only when it starts running and at that point the build gets a build number. If all your executors are busy, it can sometimes take a long time before the build is created and starts running.

    The only way to get the build number when triggering a job, is to use the "build" command of the Jenkins CLI. If you use the -w option, the command will not return until the build starts and then it will print "Started build #N"

    You do not actually need the java cli.jar, just an ssh client is enough. See https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+SSH

    Other than that there is no known solution. You might be able to search through the builds and find a one that was triggered around the time your triggered the job, but that's a lot of work.

    0 讨论(0)
  • 2020-12-10 03:23

    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:

    • start the job
    • parse return 'Location' header
    • poll the queue looking for job to start
      • job queue entry will have an 'executable' entry in its json or xml with job number once it starts
    • poll the job status waiting for a result

    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: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
    

    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
    }
    
    0 讨论(0)
提交回复
热议问题