py调jenkins接口发布-回调函数优化篇

py调jenkins接口发布-优化篇
  之前写的文章,python调jenkins接口【https://www.cnblogs.com/windysai/p/16709313.html】,用于晚上10点后自动构建jenkins任务并发通知,但是有误报情况。
       现象包括:未发布完,就去拿jenkins任务的状态结果判断,误报成构建失败。我觉得如果睡眠时间设置得足够长,例如10分钟(time.sleep(600)),应该不会再出现这种情况,因为需要构建的任务,在10分钟内完成绰绰有余。
  但是我觉得发布任务之间,时间间隔那么久,才能知道所有任务的构建结果(有时一天发布要5个任务),我要知道这个结果后,才能群上通知公司人任务是否都发布成功(即使有些任务没有关系,能并行跑,这样弄完差不多10点30分以后,还是觉得太晚),还不如手动跑、盯着还快 ——》!!!
  然而人都是有惰性的,为了解放我双手及眼睛,我特意去研究python的回调函数,参考【https://blog.csdn.net/sinat_38682860/article/details/115351094】
  经过我周末两天零碎时间的艰苦奋斗,改成这样,基本算没bug。。。了吧,测试过应该没问题,有问题再改= =
 
1、整个思路:
  先观察要发布的任务,取历史最短的构建时间 tt(以秒为单位),写入main函数的:server.build_job 后面的 time.sleep( tt )里,然后过了这个 tt 时间之后,每3秒去请求jenkins任务的构建结果值,直到得到最终构建结果,通知到人
 
先贴代码,再讲注意点:
  1 #!/usr/bin/python3.6
  2 #coding=UTF-8
  3 
  4 '''
  5 输入:jenkins服务器的地址,用户名和密码
  6 输出:已构建任务的状态
  7 '''
  8 import requests
  9 import datetime, time
 10 import timeit
 11 import jenkinsapi
 12 import jenkins
 13 import sys
 14 import random
 15 
 16 from jenkinsapi.jenkins import *
 17 from jenkinsapi.job import *
 18 from jenkinsapi.build import Build
 19 
 20 def mainfunc(func):
 21     '''
 22     :param func: callback func Name
 23     :return:
 24 
 25     '''
 26 
 27     # last_build_number = server.get_job_info(jobname)['lastBuild']['number']
 28     # print("最近一次构建编号为:", last_build_number)
 29     global msg2, end
30 #根据callback返回的状态,决定是否进行下一步操作 31 while True: 32 #如果为true,就执行下一步,否则,再次调用func获取状态结果 33 flag = func() 34 if flag: 35 print('step2: 发送信息') 36 end = timeit.default_timer() 37 spend = end - start 38 spend = round(spend, 2) 39 print("执行时间为: 秒", spend) 40 41 msg2 = msg2 + job_status + '\n' + '执行时间为: ' + str(spend) + '' 42 print("msg2 = ", msg2) 43 44 send_msg(msg2) 45 break 46 47 def callback(): 48 ''' 49 :return: jenkins job build state 50 ''' 51 #jenkins构建job需要至少xx分钟,后续每隔3秒,请求一次;如果显示构建中,则多间隔3秒 52 global last_build_number, job_status 53 print("进入callback函数。。。") 54 last_build_number = server.get_job_info(jobname)['lastBuild']['number'] 55 print("构建中,任务构建编号:", last_build_number) 56 57 58 job_status = server.get_build_info(jobname, last_build_number)['result'] 59 60 time.sleep(3) 61 print("任务状态为:", job_status) 62 print('-' * 30) 63 if job_status == 'SUCCESS': 64 print('step2: jenkins 构建完成!') 65 return True 66 elif job_status == 'ABORTED': 67 print('step2: jenkins 任务被中断,请重新构建!') 68 return True 69 elif job_status == 'FAILURE' or job_status == 'UNSTABLE': 70 print('step2: jenkins 任务构建失败!') 71 return True 72 # 构建中 73 else: 74 ## 再等3秒 75 time.sleep(3) 76 print('step2: jenkins 正在构建。。。') 77 return False 78 79 80 ''' 81 钉钉通知 82 83 ''' 84 def send_msg(text): 85 start = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") 86 headers = {'Content-Type': 'application/json;charset=utf-8'} 87 api_url = "token机器人" 88 json_text= { 89 "msgtype": "text", 90 "text": { 91 "content": '测试' 92 + '\n当前时间:' + str(start) 93 + '\n' + text 94 }, 95 "at": { 96 "atMobiles": [ 97 "加一俺的手机号码" 98 ], 99 "isAtAll": False 100 } 101 } 102 result = requests.post(api_url,json.dumps(json_text),headers=headers).content 103 print(result) 104 105 106 if __name__=="__main__": 107 # jobname = sys.argv[1] ##到时部署生产,传参:任务名 108 109 #前端任务 110 jobname = 'xxx_系统平台_前端' 111 112 #后端任务 113 #jobname = 'xxx_系统平台_后端' 114 115 url = "jenkins登录地址" 116 username='jenkins登录账号' 117 password='jenkins登录账号密码' 118 # 实例化jenkins对象,连接远程的 jenkins server 119 server = jenkins.Jenkins(url, username, password) 120 121 last_build_number = server.get_job_info(jobname)['lastBuild']['number'] 122 print("未构建前,main 初始化,任务上一次构建编号:", last_build_number) 123 124 print('step1: 开始构建 任务') 125 print('-' * 20) 126 msg1 = jobname + "--- step1:开始构建任务" 127 msg2 = jobname + "构建结果:" 128 129 send_msg(msg1) 130 131 #前端 132 param_dict = {'BRANCH': '分支名'} 133 134 #后端 135 # param_dict = {'BRANCH': '分支名', 'Environment': '选项参数'} 136 137 # 开始执行时间 138 start = timeit.default_timer() 139 end = timeit.default_timer() 140 ## 构建任务 141 142 server.build_job(jobname, parameters=param_dict) 143 144 # 等120秒开始,每隔3秒请求,jenkins构建状态 145 #前端等待时间 146 time.sleep(150) 147 #后端等待时间,真实后端设置180秒 148 149 #测试时,不能太短,不然获取不了最近一次编号,而是获取上一次任务构建编号,导致误报 150 #time.sleep(20) 151 152 job_status = 'None' 153 154 155 mainfunc(callback)

2、注意点:

(1)全局变量设置及值修改

有几个:

实例化jenkins对象:server

任务状态:job_status

任务执行和结束时间:start、end

如果函数里面需要修改全局变量的值,要先在函数里面声明该变量为:global

 

(2)测试人为中断发布任务时(ABORTED),main里面的 time.sleep,别设置太短

main里面的time.sleep,别设置太短,我之前设置5秒,发现竟然误报成成功,想想python去调jenkins接口到真正触发构建,是需要时间的。设置20秒差不多了。

 (3)构建中的结果状态为:None,所以一开始统一在main里给任务状态 job_status 赋值为:None

 (4)构建参数化任务,构建任务需要添加构建参数

server.build_job(jobname, parameters=param_dict)

不然报错:requests.exceptions.HTTPError: 400 Client Error: Bad Request for url

 即使保持默认的构建参数,不需要修改,直接写成

server.build_job(jobname)

都会报错 400  Client Error: Bad Request for url

 

3、测试效果

模拟结果值

(1)模拟人为中断:ABORTED
为了快速得到测试结果,我在main函数的:server.build_job 后面的 time.sleep设置了20秒(代码里面也注释说过不能设置太短时间),从触发任务构建到等20秒后,会开始进入 callback 函数里,此时在jenkins控制台把任务中断就能获取任务被中断的通知信息:
 

 

(2) 模拟任务构建失败:FAILURE

故意写错jenkins配置里面的构建:

通知信息:

   

(3) 模拟任务构建不稳定:UNSTABLE
故意在jenkins配置里,写错要发布的机器

 通知信息:

 

 
 
posted @ 2022-09-25 15:13  windysai  阅读(280)  评论(1编辑  收藏  举报