侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

持续集成JenkinsAPI常见用法

2022-07-01 星期五 / 0 评论 / 0 点赞 / 73 阅读 / 29345 字

【背景】:部门在搞持续集成,使用jenkins作为核心调度,要再其基础上进行二次封装,所以需要研究下jenkins的api。笔者主要负责搭建平台,在研究用法也花费了些时间,本文主要做个简要的记录,希望

【背景】:部门在搞持续集成,使用jenkins作为核心调度,要再其基础上进行二次封装,所以需要研究下jenkins的api。笔者主要负责搭建平台,在研究用法也花费了些时间,本文主要做个简要的记录,希望能为各位朋友节省时间。

【环境】:(默认读者已经具备了基本的持续集成经验和jenkins用法

1. Jenkins1.455 

2. 系统Suse

3. Tomcat 6.0.37

4. Java 1.6.0_26

5. patch-parameter 

【API介绍】

 Jenkins提供了html、json、python API,实质都是以http get/post方式调用的。查看http://www.xxx.xxx/jenkins/api/ 即可得到相应的说明,如图:

 

【API实践】

1.创建

curl -X POST http://www.xxx.xxx/jenkins/createItem?name=JavaStd  --user peterguo:peterguo --data-binary "@javastd.config.xml" -H "Content-Type: text/xml"

2.禁用 

curl -X POST http://www.xxx.xxx/jenkins/job/JavaStd/disable  --user peterguo:peterguo

3.启用 

curl -X POST http://www.xxx.xxx/jenkins/job/JavaStd/enable --user peterguo:peterguo

4.删除 

curl -X POST http://www.xxx.xxx/jenkins/job/JavaStd/doDelete --user peterguo:peterguo

5.获取项目描述 

curl -X GET http://www.xxx.xxx/jenkins/job/JavaStd/description --user peterguo:peterguo

6.获取配置文件 

curl -X GET http://www.xxx.xxx/jenkins/job/JavaStd/config.xml --user peterguo:peterguo

7.触发SCM检查 

curl -X GET http://www.xxx.xxx/jenkins/job/JavaStd/polling --user peterguo:peterguo

8.普通触发 

curl -X GET http://www.xxx.xxx/jenkins/job/JavaStd/build --user peterguo:peterguo

9.带参数触发

curl -X GET "http://www.xxx.xxx/jenkins/job/helloworld-freestyle/buildWithParameters?bAllTest=&Choices=2&strParam=abc" --user peterguo:peterguo

10.带文件触发

curl  -X POST "http://localhost:8080/job/Demo/buildWithParameters?assertMethod=online" -F "[email protected]"

11.参数和补丁触发  

curl -X POST "http://www.xxx.xxx/jenkins/job/helloworld-freestyle/buildWithParameters?bAllTest=&Choices=2&strParam=abc" --user peterguo:peterguo -F "action=upload" -F "[email protected]"

注:带补丁触发需要先安装补丁插件,并设置项目的补丁参数

【通过Python-curl库调用】

 提供python使用pycurl调用的例子片段,实际和curl调用一样,优点是易整合。

import pycurlurl = "http://10.129.145.112:8081/jenkins/job/helloworld-freestyle/config.xml"crl = pycurl.Curl()crl.setopt(pycurl.VERBOSE,1)crl.setopt(pycurl.FOLLOWLOCATION, 1)crl.setopt(pycurl.MAXREDIRS, 5)crl.setopt(pycurl.USERPWD, "peterguo:peterguo") crl.setopt(pycurl.CONNECTTIMEOUT, 60)crl.setopt(pycurl.TIMEOUT, 300)crl.setopt(pycurl.HTTPPROXYTUNNEL,1)crl.fp = StringIO.StringIO()crl.setopt(pycurl.URL, url)crl.setopt(crl.WRITEFUNCTION, crl.fp.write)crl.perform()ret = crl.fp.getvalue()

【通过Python-jenkinsapi库调用】

   这里给出代码

from jenkinsapi.jenkins import Jenkinsclass CJenkinsAPI():      '''    均采用同步设置超时机制    创建项目:输入:configid planid             创建任务:输入:configid planid   返回:返回码 msg buildid  额外动作:不写SQL    查询任务:输入:configid planid taskid  返回:返回码 msg buildid  额外动作:结束更新SQL(包括成功或失败),未结束则不处理    终止任务:输入:configid planid taskid  返回:返回码 msg buildid  额外动作:终止成功写SQL    '''    __doc__ = '''Usage: /t/tCJenkinsAPI.createProject/t/tCJenkinsAPI.triggerBuild/t/t'''    _strConfigTemplatePath = ""    _strConfigDataPath = ""    def __init__(self):        import pycurl         pass            def __del__(self):        pass    @staticmethod    def createProject(nPlanId, strConfigId):        '''        Return:返回码/返回信息        先根据配置文件生成项目        '''        #用于测试        nPlanId = 14         strConfigId = "D1057406"                    #返回        nRet, strMsg, nBuild = 0, "", 0                #配置文件模版        strConfigTemplate = CJenkinsAPI._strConfigTemplatePath + "/config.template.xml"                #用planID和配置ID作为项目名        strProjectName = "P%d-%s" % (nPlanId, strConfigId )                 #访问数据库拿到构建节点IP和SVN        strBuildNodeIP = ""        strProjectSVN = ""                oProxy = CSqlProxy("10.129.145.112", "ci_test", "ci_test", "ci_plat")        #SVN从t_build_plan中取        lSelectRet = CSqlProxy.selectFromTable(oProxy.m_oCon, "t_build_plan", ["f_svn"], " where f_plan_id='%d' " % nPlanId)        strProjectSVN = lSelectRet[0]["f_svn"]        #配置信息从t_ci_config中取        lSelectRet = CSqlProxy.selectFromTable(oProxy.m_oCon, "t_ci_config", ["f_node_ip", "f_run_param"], " where f_config_id='%s' " % strConfigId)        strBuildNodeIP = lSelectRet[0]["f_node_ip"]        strRunParam = lSelectRet[0]["f_run_param"]        oProxy.close()                strNodeFlag = {True:"", False:"slave_"}["10.129.145.112" in strBuildNodeIP]        dReplaceInfo = {"PROJ_DESC"     : "This is generate by Ci-plat, with plan_id[%d] and config_id[%s]" % (nPlanId, strConfigId),/                        "SVN_URL"       : strProjectSVN.replace("http://tc-svn.tencent.com", "svn://172.27.198.49:8081"),/                        "BUILD_NODE_IP" : strNodeFlag + strBuildNodeIP,/                        "BUILD_SCRIPT"  : '''sh build.sh %s ''' % strRunParam, /                        "JUNIT_TEST_PATH"   :"target/surefire-reports/*.xml", /                        "COVERAGE_PATH" :"target/site/cobertura/", /                        }        #利用模版生成配置文件        oConf = CCiConfig(strConfigTemplate, dReplaceInfo)        strCurConfigXml = CJenkinsAPI._strConfigDataPath + "/" + strProjectName + ".config.xml"        oConf.dump2file(strCurConfigXml)                strCommand = 'curl -X POST http://10.129.145.112:8081/jenkins/createItem?name=%s --user peterguo:peterguo --data-binary "@%s" -H "Content-Type: text/xml"' % (strProjectName, strCurConfigXml)        nRet = os.system(strCommand)        strMsg = {True:"SucceedCreate,Url:", False:"FailedCreate,Url:"}[nRet==0]        print "%d|%s|%d" % (nRet, tran2UTF8(strMsg)+"[http://10.129.145.112:8081/jenkins/job/%s]" % strProjectName, nBuild)            @staticmethod        def triggerBuild(nPlanId, strConfigId):        '''        Return:        触发前先更新配置文件,使用远程脚本        触发前获取要出发的编号        '''        #返回        nRet, strMsg, nBuild = 0, "", 0                #配置文件模版        strConfigTemplate = CJenkinsAPI._strConfigTemplatePath + "/config.template.xml"          #用planID和配置ID作为项目名        strProjectName = "P%d-%s" % (nPlanId, strConfigId )                 #访问数据库拿到构建节点IP和SVN        strBuildNodeIP = ""        strProjectSVN = ""                oProxy = CSqlProxy("10.129.145.112", "ci_test", "ci_test", "ci_plat")        #SVN从t_build_plan中取        lSelectRet = CSqlProxy.selectFromTable(oProxy.m_oCon, "t_build_plan", ["f_svn"], " where f_plan_id='%d' " % nPlanId)        strProjectSVN = lSelectRet[0]["f_svn"]        #配置信息从t_ci_config中取        lSelectRet = CSqlProxy.selectFromTable(oProxy.m_oCon, "t_ci_config", ["f_node_ip", "f_run_param"], " where f_config_id='%s' " % strConfigId)        strBuildNodeIP = lSelectRet[0]["f_node_ip"]        strRunParam = lSelectRet[0]["f_run_param"]        oProxy.close()                strNodeFlag = {True:"", False:"slave_"}["10.129.145.112" in strBuildNodeIP]        dReplaceInfo = {"PROJ_DESC"     : "This is generate by Ci-plat, with plan_id[%d] and config_id[%s]" % (nPlanId, strConfigId),/                        "SVN_URL"       : strProjectSVN.replace("http://tc-svn.tencent.com", "svn://172.27.198.49:8081"),/                        "BUILD_NODE_IP" : strNodeFlag + strBuildNodeIP,/                        "BUILD_SCRIPT"  : '''sh build.sh %s ''' % strRunParam, /                        "JUNIT_TEST_PATH"   :"target/surefire-reports/*.xml", /                        "COVERAGE_PATH" :"target/site/cobertura/", /                        }        #利用模版生成配置文件        oConf = CCiConfig(strConfigTemplate, dReplaceInfo)        strCurConfigXml = CJenkinsAPI._strConfigDataPath + "/" + strProjectName + ".config.xml"        oConf.dump2file(strCurConfigXml)                #更新配置文件        strCommand = 'curl -X POST http://10.129.145.112:8081/jenkins/job/%s/config.xml --user peterguo:peterguo --data-binary "@%s" -H "Content-Type: text/xml"' % (strProjectName, strCurConfigXml)        nRet = os.system(strCommand)        strMsg += {True:"更新配置成功", False:"更新配置失败"}[nRet==0]                #获取下一次构建编号        nBuild = Jenkins("http://10.129.145.112:8081/jenkins","peterguo","peterguo")[strProjectName.encode("utf8")].get_next_build_number()                #触发构建        strCommand = 'curl -X POST http://10.129.145.112:8081/jenkins/job/%s/build --user peterguo:peterguo ' % (strProjectName)        nRet = os.system(strCommand)        strMsg = {True:"SucceedTrigger,Url:", False:"FailedTrigger,Url:"}[nRet==0]        print "%d|%s|%d" % (nRet, tran2UTF8(strMsg)+"[http://10.129.145.112:8081/jenkins/job/%s/%d]" % (strProjectName, nBuild), nBuild )            @staticmethod    def infoBuild(nPlanId, strConfigId, nTaskId):        '''        Return:        '''        strProjectName = "P%d-%s" % (nPlanId, strConfigId )         oProxy = CSqlProxy("10.129.145.112", "ci_test", "ci_test", "ci_plat")        strWhere = " where f_task_id='%d' " % int(nTaskId)        lSelectRet = CSqlProxy.selectFromTable(oProxy.m_oCon, "t_build_task", ["f_build_id"], strWhere)        oProxy.close()        nBuildId = int(lSelectRet[0]["f_build_id"])        oCurBuild = Jenkins("http://10.129.145.112:8081/jenkins","peterguo","peterguo")[strProjectName.encode("utf8")].get_build(nBuildId)        bRunning = oCurBuild.is_running()        if bRunning == True:            print "1|Running|%d" % nBuildId             return        #最重要更新的数据        dResult2Sql = {}                #取测试用例结果的个数信息        if oCurBuild.has_resultset():            dResult = oCurBuild.get_actions()        else:            dResult = {"failCount":0, "totalCount":0, "skipCount":0}         oDeltaDur = oCurBuild.get_duration()        oBuildBegin = utc2LocalDatetime(oCurBuild.get_timestamp())        oBuildEnd = oBuildBegin + oDeltaDur        dResult2Sql["f_case_fail"] = dResult['failCount']        dResult2Sql["f_case_total"] = dResult['totalCount']        dResult2Sql["f_case_skip"] = dResult['skipCount']        dResult2Sql["f_build_duration"] = "%.3f" % (oDeltaDur.days * 24 * 60 + oDeltaDur.seconds / 60.0)        dResult2Sql["f_build_url"] = oCurBuild.baseurl        dResult2Sql["f_build_result"] = {True:0, False:1}[oCurBuild.is_good()]        dResult2Sql["f_task_status"] = TASK_DONE        dResult2Sql["f_build_time"] = oBuildBegin.strftime("%Y-%m-%d %H:%M:%S")        dResult2Sql["f_build_end"] = oBuildEnd.strftime("%Y-%m-%d %H:%M:%S")        dResult2Sql["f_msg_info"] = tran2GBK("任务完成,收集数据完成")                #任务已经完成,需要入库相关数据,更新相关状态        oProxy = CSqlProxy("10.129.145.112", "ci_test", "ci_test", "ci_plat")        strWhere = " where f_task_id='%d' " % int(nTaskId)        CSqlProxy.updateValueToDBTable(oProxy.m_oCon, "t_build_task", dResult2Sql.keys(), dResult2Sql.values(), strWhere)        oProxy.close()        #for item in dResult2Sql.items():        #    print item[0], str(item[1])        print "%d|%s|%d" % (0, "SucceedUpdated", nBuildId)            @staticmethod        def stopBuild(nPlanId, strConfigId, nTaskId):        '''        Return:        '''        strProjectName = "P%d-%s" % (nPlanId, strConfigId )         oProxy = CSqlProxy("10.129.145.112", "ci_test", "ci_test", "ci_plat")        strWhere = " where f_task_id='%d' " % int(nTaskId)        lSelectRet = CSqlProxy.selectFromTable(oProxy.m_oCon, "t_build_task", ["f_build_id"], strWhere)        oProxy.close()        nBuildId = int(lSelectRet[0]["f_build_id"])                oCurBuild = Jenkins("http://10.129.145.112:8081/jenkins","peterguo","peterguo")[strProjectName.encode("utf8")].get_build(nBuildId)        bRunning = oCurBuild.is_running()        if bRunning == False:            print "2|AlreadyStopped|%d" % nBuildId            return        #触发停止命令        oCurBuild.stop()                        #等停止        oCurBuild.block_until_complete()                #最重要更新的数据        dResult2Sql = {}                #取测试用例结果的个数信息        if oCurBuild.has_resultset():            dResult = oCurBuild.get_actions()        else:            dResult = {"failCount":0, "totalCount":0, "skipCount":0}         oDeltaDur = oCurBuild.get_duration()        oBuildBegin = utc2LocalDatetime(oCurBuild.get_timestamp())        oBuildEnd = oBuildBegin + oDeltaDur        dResult2Sql["f_case_fail"] = dResult['failCount']        dResult2Sql["f_case_total"] = dResult['totalCount']        dResult2Sql["f_case_skip"] = dResult['skipCount']        dResult2Sql["f_build_duration"] = "%.3f" % (oDeltaDur.days * 24 * 60 + oDeltaDur.seconds / 60.0)        dResult2Sql["f_build_url"] = oCurBuild.baseurl        dResult2Sql["f_build_result"] = {True:0, False:1}[oCurBuild.is_good()]        dResult2Sql["f_task_status"] = TASK_ABORTED        dResult2Sql["f_build_time"] = oBuildBegin.strftime("%Y-%m-%d %H:%M:%S")        dResult2Sql["f_build_end"] = oBuildEnd.strftime("%Y-%m-%d %H:%M:%S")        dResult2Sql["f_msg_info"] = tran2GBK("TaskStopped")                #任务已经完成,需要入库相关数据,更新相关状态        oProxy = CSqlProxy("10.129.145.112", "ci_test", "ci_test", "ci_plat")        strWhere = " where f_task_id='%d' " % int(nTaskId)        CSqlProxy.updateValueToDBTable(oProxy.m_oCon, "t_build_task", dResult2Sql.keys(), dResult2Sql.values(), strWhere)        oProxy.close()        #for item in dResult2Sql.items():        #    print item[0], str(item[1])        print "%d|%s|%d" % (1, tran2UTF8("SucceedStopped"), nBuildId)    @staticmethod        def deleteProject(nPlanId, strConfigId):               '''       Return:返回码/返回信息 curl -X POST http://10.129.145.112:8081/jenkins/job/JavaStd/doDelete --user peterguo:peterguo       '''           strProjectName = "P%d-%s" % (nPlanId, strConfigId )        strCommand = 'curl -X POST http://10.129.145.112:8081/jenkins/job/%s/doDelete --user peterguo:peterguo' % (strProjectName)       CColorPrint.colorPrintStr("CMD:[%s]" % strCommand, "green")       nRet = os.system(strCommand)       strMsg = {True:"SucceedDeleted", False:"FailedDeleted"}[nRet==0]       print nRet, tran2UTF8(strMsg), 0


广告 广告

评论区