記錄瞬間
近期操作Jenkins調用比較多,當然Jenkins本身也提供了jenkins-cli.jar的使用方法,可以直接通過命令行進行調用,
但是,由於不想引入太多的jar包,導致直接使用Jenkins api需求強烈
下面就把近期收集到的一些常見用法做一個簡單總結,希望對初學者有所幫助。
9、直接調用Jenkins的job API進行構建的方法 Simple example - sending "String Parameters": curl -X POST JENKINS_URL/job/JOB_NAME/build \ --user USER:TOKEN \ --data-urlencode json='{"parameter": [{"name":"id", "value":"123"}, {"name":"verbosity", "value":"high"}]}' Another example - sending a "File Parameter": curl -X POST JENKINS_URL/job/JOB_NAME/build \ --user USER:PASSWORD \ --form file0=@PATH_TO_FILE \ --form json='{"parameter": [{"name":"FILE_LOCATION_AS_SET_IN_JENKINS", "file":"file0"}]}' E.g.curl -X POST http://JENKINS_URL/job/JOB_NAME/build --form file0=@/home/user/Desktop/sample.xml --form json='{"parameter": [{"name":"harness/Task.xml", "file":"file0"}]}' Please note, in this example, the symbol '@' is important to mention. Also, the path to the file is absolute path. In order to make this command work, you need to configure your Jenkins job to take a file parameter and 'name' in this command corresponds to 'file location' field in the Jenkins job configuration. In above example, 'harness' is just a name of folder that may not exist in your workspace, you can write "name":"Task.xml" and it will place the Task.xml at root of your workspace. Remember that name in this command should match with File location in file parameter in job configuration. 一個插件,可以通過此插件傳參並調用Jenkins上的其他任務 Trigger/call builds on other projects Build Triggers 2.1運行jenkins-job 2.1.1無參任務curl -X POST http://localhost:8080/jenkins/job/plugin%20demo/build --user admin:admin 2.1.2含參任務 不設置參數/使用默認參數curl -X POST http://localhost:8080/jenkins/job/commandTest/buildWithParameters --user admin:admin 2.1.3設置參數方法1curl -X POST http://localhost:8080/jenkins/job/commandTest/buildWithParameters -d port=80 2.1.4設置參數方法2curl -X POST http://localhost:8080/jenkins/job/commandTest/buildWithParameters -d port=80 --data-urlencode json='"{\"parameter\": [{\"name\": \"port\", \"value\": \"80\"}]}”' 2.1.5多參數http://localhost:8080/jenkins/job/commandTest/buildWithParameters -d param1=value1¶m2=value 2.2 創建job 2.2.1 需創建目錄 1).創建job目錄~/.jenkins/jobs/jobfromcmd 2).創建config.xml文件(可從其他工程中復制) 3).運行命令curl -X POST http://localhost:8080/jenkins/createItem?name=jobfromcmd --user admin:admin --data-binary "@config.xml" -H "Content-Type: text/xml” 2.2.2 不需創建目錄 1).創建config.xml文件(可從其他工程中復制) 2).運行命令(在config.xml同一目錄下)curl -X POST http://localhost:8080/jenkins/createItem?name=jobfromcmd --user admin:admin --data-binary "@config.xml" -H "Content-Type: text/xml” 2.2.3直接使用控制台,不需創建xml文件(將xml內容寫入控制台中運行)echo '<?xml version="1.0" encoding="UTF-8"?><project>…</project>' | curl -X POST -H 'Content-type:text/xml' -d @- http://localhost:8080/jenkins/createItem?name=jobfromcmd 2.3 刪除job curl -X POST http://localhost:8080/jenkins/job/jobfromcmd/doDelete 2.4 查詢job的狀態 curl --silent ${JENKINS_SERVER}/job/JOB_NAME/lastBuild/api/json 2.5 自動disable Project: curl --user ${UserName}:${PASSWORD} -o /dev/null --data disable JENKINS_URL/job/JOBNAME/disable 2.6獲取build的num curl --silent ${JENKINS_SERVER}/job/JOB_NAME/lastBuild/buildNumber 2.7獲取最近成功的build的num curl --silent ${JENKINS_SERVER}/job/JOB_NAME/lastStableBuild/buildNumber 2.8獲取某一次構建結果信息 curl -o build.tmp2 -s --header n:${newbuild} ${jobPage}buildHistory/ajax 構建中: <img height="16" alt="pending > Console Output" width="16" src="/static/ea09c638/images/16x16/grey_anime.gif" tooltip="pending > Console Output" /> 排隊中: <img height="16" alt="In progress > Console Output" width="16" src="/static/ea09c638/images/16x16/grey_anime.gif" tooltip="In progress > Console Output" /> 成功: alt="成功 > 控制台輸出" <img height="16" alt="Success > Console Output" width="16" src="/static/ea09c638/images/16x16/blue.png" tooltip="Success > Console Output" /> 警告: <img height="16" alt="Unstable > Console Output" width="16" src="/static/ea09c638/images/16x16/yellow.png" tooltip="Unstable > Console Output" /> 失敗: <img height="16" alt="Aborted > Console Output" width="16" src="/static/ea09c638/images/16x16/grey.png" tooltip="Aborted > Console Output" /> l = ["123", "234", "098"] for i in l: jenkins_url = "http://127.0.0.1:8080/jenkins/job/test/lastBuild/buildNumber" result = requests.get(jenkins_url) print("last build is : " + result.text) buildNumber = result.text j_url = "http://127.0.0.1:8080/jenkins/job/test/buildWithParameters" j_data = {"test": i} result = requests.post(j_url, data=j_data) print(result.text) while 1: jenkins_url = "http://127.0.0.1:8080/jenkins/job/test/buildHistory/ajax" headers = {"n": str(int(buildNumber) + 1)} print(headers) result = requests.get(jenkins_url, headers=headers) if 'alt="成功 > 控制台輸出"' in result.text or \ 'alt="Success > Console Output"' in result.text: print("Yes !!!!!...") break else: time.sleep(2) print("sleep 1 second.") print(result.text) 其中可以直接將token放到url鏈接中,格式如下: http://USER:API_TOKEN@Jenkins_IP:8080 Jenkins RestAPI調用出現Error 403 No valid crumb was included in the request 方法一(不推薦): 在jenkins 的Configure Global Security下 , 取消“防止跨站點請求偽造(Prevent Cross Site Request Forgery exploits)”的勾選 方法二: 1、獲取用戶API token http://Jenkins_IP:8080/user/zhangyi/configure 點擊 show API Token,假設是API_TOKEN 2、計算CRUMB CRUMB=$(curl -s 'http://USER:API_TOKEN@Jenkins_IP:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)') 3、請求時附帶CRUMB信息即可 curl -X POST -H "$CRUMB" http://USER:API_TOKEN@cd.web.tc.ted:8080/reload 可以使用如下鏈接對特定的job進行遠程調用。 curl -X POST http://192.168.43.130:8080/jenkins/job/test/build --user xxx --data-urlencode json='{"parameter":[{"name":"v1","value":"123123"},{"name":"v2","value":"asdfghjkl"},{"name":"v3","value":"qwertyuiop"}]}' 獲取最后一次執行的狀態。 str=`curl --silent http://192.168.43.130:8080/jenkins/job/test/lastBuild/api/json --user xxx | sed 's/,/\ /g' | sed -r 's/.*"result":"([^ ]+)" .*/\1/'` echo $str FAILURE 或者 SUCCESS 或者 null
增加一段python代碼,用來實現一個小例子
# coding:utf-8 import os import time import zipfile from xml.etree.ElementTree import ElementTree import chardet import requests class GetJar(object): def __init__(self): self.data = { 'mn': "xx/xx/xx", 'app': "oo", 'env': "wawo" } pass def create_json(self): base_path = "/jar" # 根據不同環境需要進行配置的一個基礎路徑 jar_info = {} back_path = base_path + '/' +self.data['mn'] + '/' + self.data['app'] if not os.path.isdir(back_path): os.makedirs(back_path) jar_info['back_path'] = back_path jar_info["mn"] = self.data['mn'] jar_info["app"] = self.data['app'] jar_info["env"] = self.data['env'] return jar_info # 檢查pom文件是否存在jar包,並將jar包命名返回 def check_pom_and_find_jar(self, root_path): jar_names = [] for rt, dirs, files in os.walk(root_path): for fn in files: if fn == "pom.xml": pom_file = os.path.join(rt, fn).replace("\\", "/") nodes, ns = self.get_xml_object(pom_file) if nodes == '0' and ns == '0': continue art_id = "" ver = "" mark = 0 for child in nodes: if child.tag == "{}parent".format(ns): for sub in child: if sub.tag == "{}version".format(ns): ver = sub.text if child.tag == "{}version".format(ns): ver = child.text if child.tag == "{}artifactId".format(ns): art_id = child.text if child.tag == "{}packaging".format(ns) and child.text == "jar": mark = 1 if mark == 1: jar_names.append(art_id + "-" + ver + ".jar") return jar_names # 解析pom文件,如果沒有jacoco插件,就按照特定方式進行插入 def get_xml_object(self, pom_file): ns = "" mark = 0 f_code = open(pom_file, 'rb') f_data = f_code.read() file_encoding = chardet.detect(f_data).get('encoding') f_code.close() try: with open(pom_file, encoding=file_encoding, mode="r") as pf: for line in pf.readlines(): # if line.startswith("<project "): try: ns_line = line.split("xmlns=")[1].split()[0] if ">" in ns_line: ns_line = ns_line.replace(">", '') ns = "{" + "{}".format(ns_line.rstrip().replace('"', '')) + "}" mark = 1 except Exception: pass if mark == 1: break except Exception as e: print("文件 {} 非 UTF-8 編碼 {}.{}.".format(pom_file, file_encoding, e)) return "0", "0" tree = ElementTree() tree.parse(pom_file) return tree.getroot(), ns def get_jar(self, repo_path, sub_path='./'): jar_names = self.check_pom_and_find_jar(repo_path) print("展示所有的jar包名稱: {}".format(jar_names)) base_url = "http://Jenkins_job_url/" # 需要替換一下! url_build = base_url + "buildWithParameters" url_num = base_url + "lastBuild/buildNumber" url_state = base_url + "buildHistory/ajax" jar_info = self.create_json() for jar in jar_names: # 獲取最后一次的執行數字 result = requests.get(url_num) buildNumber = result.text jar_info['jar_name'] = jar # 發送執行請求 requests.post(url_build, data=jar_info) try: headers = {"n": str(int(buildNumber) + 1)}
# headers = {"n": str(int(buildNumber) + 1), "Accept-Language": "zh-CN,zh;q=0.9"}
# 如果需要進行中文回顯,可以加入Accept-Language參數
except Exception as e: print("解析最后一次Jenkins執行數據出錯 - {}".format(e)) continue while 1: # 查詢發送后的狀態 result = requests.get(url_state, headers=headers) if 'alt="成功 > 控制台輸出"' in result.text or \ 'alt="Success > Console Output"' in result.text: break else: time.sleep(2) print("sleep 2 second.") if os.path.isfile(jar_info['back_path'] + '/' + jar): zf = zipfile.ZipFile(jar_info['back_path'] + '/' + jar) try: zf.extractall(path=sub_path + '/classes') except Exception as e: print("解壓縮失敗 = {}".format(jar_info['back_path'] + '/' + jar)) finally: zf.close() if __name__ == '__main__': jar = GetJar() jar.get_jar(r'/path/to/repo/')
====================底線====================