from jenkinsapi.jenkins import Jenkins
class CJenkinsAPI():
'''
均采用同步設(shè)置超時機制
創(chuàng)建項目:輸入:configid planid
創(chuàng)建任務(wù):輸入:configid planid 返回:返回碼 msg buildid 額外動作:不寫SQL
查詢?nèi)蝿?wù):輸入:configid planid taskid 返回:返回碼 msg buildid 額外動作:結(jié)束更新SQL(包括成功或失?。?,未結(jié)束則不處理
終止任務(wù):輸入: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:返回碼/返回信息
先根據(jù)配置文件生成項目
'''
#用于測試
nPlanId = 14
strConfigId = "D1057406"
#返回
nRet, strMsg, nBuild = 0, "", 0
#配置文件模版
strConfigTemplate = CJenkinsAPI._strConfigTemplatePath + "/config.template.xml"
#用planID和配置ID作為項目名
strProjectName = "P%d-%s" % (nPlanId, strConfigId )
#訪問數(shù)據(jù)庫拿到構(gòu)建節(jié)點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:
觸發(fā)前先更新配置文件,使用遠(yuǎn)程腳本
觸發(fā)前獲取要出發(fā)的編號
'''
#返回
nRet, strMsg, nBuild = 0, "", 0
#配置文件模版
strConfigTemplate = CJenkinsAPI._strConfigTemplatePath + "/config.template.xml"
#用planID和配置ID作為項目名
strProjectName = "P%d-%s" % (nPlanId, strConfigId )
#訪問數(shù)據(jù)庫拿到構(gòu)建節(jié)點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]
#獲取下一次構(gòu)建編號
nBuild = Jenkins("http://10.129.145.112:8081/jenkins","peterguo","peterguo")[strProjectName.encode("utf8")].get_next_build_number()
#觸發(fā)構(gòu)建
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
#最重要更新的數(shù)據(jù)
dResult2Sql = {}
#取測試用例結(jié)果的個數(shù)信息
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("任務(wù)完成,收集數(shù)據(jù)完成")
#任務(wù)已經(jīng)完成,需要入庫相關(guān)數(shù)據(jù),更新相關(guān)狀態(tài)
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
#觸發(fā)停止命令
oCurBuild.stop()
#等停止
oCurBuild.block_until_complete()
#最重要更新的數(shù)據(jù)
dResult2Sql = {}
#取測試用例結(jié)果的個數(shù)信息
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")
#任務(wù)已經(jīng)完成,需要入庫相關(guān)數(shù)據(jù),更新相關(guān)狀態(tài)
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