定制筛选功能列表
诞生记
最近在使用Jenkins列表视图的时候发现当创建的工程比较多的时候想准确的定位某个或某类工程的时候比较麻烦,滚动条贼长,各个工程间隔比较远的时候查看起来比较麻烦,当然如果你是管理员打可以直接编辑视图里面的工程,但是工程较多的时候这种方式感觉比较低效,况且大部分的Jenkins用户不是管理者,并不会提供管理员权限。
为了提高效率以及方便非管理人员也能筛选出列表视图里面比较关心的工程,根据目前想到的场景创建一个_Update_view工程,通过参数构建动态修改列表视图中的工程实现类筛选功能。用户只需要工程是执行权限就能够根据设置好的方式更新列表视图里面的jobs。在此先叫他动态列表视图。
首先演示一下效果:
test_all视图工程如下
演示1、勾选test和comp后视图里面显示test和compile相关的工程
演示2、勾选test,并在search里面添加pipe,则在test_all里面搜索含test或者pipe字符的工程显示到the_test_you_care视图
功能介绍
Update_view工程主要功能介绍
- 获取参数
- 布尔参数:根据常用场景定制好的参数
- 字符参数:更加自由的自定义参数
- 获取工程列表
- 工程列表先限定从当前目录下获取,比如我这里的the_test_you_care就是直接从test_all里面获取的(当然也可以从多个视图里面获取工程列表)
- 根据参数从工程列表中筛选出所需要的工程
- 将筛选好的工程显示到当前视图(the_test_you_care)
工程及代码实现
工程参数相关配置
工程源码:
[root@CSDN /home/Sudley/update_view]#cat update_view.py
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# author: Sudley
# ctime: 2020/04/01
import sys
import jenkins
import xml.etree.ElementTree as ET
class Update_view:
def __init__(self,url,xml_file,bargv,search):
'''
初始化Update_view
url jenkins链接
xml_file 用于暂存view_config的xml文件
src_view 原工程视图
show_view 筛选后展示的视图
bargv 工程参数化构建传入的bool参数,字典形式
search 工程参数化构建出入的字符参数,以,分隔的字符串列表,最终的字符筛选列表
'''
self.jenkins_url = url
self.xml_file = xml_file
self.username = "sudley"
self.sudley_token = "11a84d40b6dae03b4f61903a0770849edd"
self.server = jenkins.Jenkins(self.jenkins_url.format(self.username,self.sudley_token))
#参数处理,生成关键字列表
self.search = search
#排除传入空字符串的情况,空字符会筛选出所有的工程
for i in range(0,self.search.count('')):
self.search.remove('')
self.bargv = bargv
for i in range(0,len(self.bargv)):
self.key,self.value = self.bargv.popitem()
if self.value == 'true':
self.search.append(self.key)
#print(self.search)
#print(0)
def save_to_xml(self,view_name=''):
#将config信息保存为xml文件用于解析,返回解析好的tree
self.view_name = view_name
self.view_config = self.server.get_view_config(self.view_name)
#print(self.view_config_all)
with open(self.xml_file,'w') as f:
f.write(self.view_config)
f.write('\n')
tree = ET.parse(self.xml_file)
return tree
def get_all_jobs_in_view(self,view_name='test_all'):
#获取view_name视图jobs列表,返回jobs列表
self.all_jobs = []
self.view_name = view_name
#获取config信息的tree
tree = self.save_to_xml(self.view_name)
root = tree.getroot()
for jobNames in root.findall('jobNames'):
for string in jobNames:
if string.text:
#print(string.text)
self.all_jobs.append(string.text)
return self.all_jobs
def clean_the_view(self,view_name=""):
#删除视图里面所有的jobs,输入视图名称,返回视图config的删掉jobs后的tree
self.view_name = view_name
#获取string数量,ET删除多个子标签时需要执行多次remove操作
self.num = len(self.get_all_jobs_in_view(self.view_name))
tree = self.save_to_xml(self.view_name)
root = tree.getroot()
for i in range(0,self.num):
for jobNames in root.findall('jobNames'):
for string in jobNames:
if string.text:
jobNames.remove(string)
#tree.write(self.xml_file)
return tree
def set_the_view_you_care(self,view_name='the_test_you_care'):
#目标视图中设置你所需要的jobs
self.new_jobs_list = ['_Update_view'] #这里默认将此工程加到show_view
self.view_name = view_name
if len(self.search) != 0:
#如果搜索列表为非空列表,则在all_jobs列表中找到与之匹配的工程
for key in self.search:
for job_name in self.all_jobs:
if key in job_name:
self.new_jobs_list.append(job_name)
#上面方法获取的jobs列表可能存在重复,需要使用集合去除重复元素
self.new_jobs_list = list(set(self.new_jobs_list))
#注意需要对jobs进行排序
self.new_jobs_list.sort()
#print(self.new_jobs_list)
#先清除目标视图原有的jobs再将筛选到的self.new_jobs_list列表的jobs添加进去
tree = self.clean_the_view(self.view_name)
root = tree.getroot()
for jobNames in root.findall('jobNames'):
for job_name in self.new_jobs_list:
string = ET.SubElement(jobNames,'string')
string.text = job_name
tree.write(self.xml_file)
with open(self.xml_file,'r') as f:
new_view_config = f.read()
#使用新配置更新view_config
self.server.reconfig_view(self.view_name,new_view_config)
return self.new_jobs_list
if __name__ == '__main__' :
#读取脚本参数
url = sys.argv[1]
xml_file = sys.argv[2]
src_view = sys.argv[3]
show_view = sys.argv[4]
keys = sys.argv[5]
values = sys.argv[6]
search = sys.argv[7]
#将keys:values转换成字典
bdict = dict(zip(keys.split(','),values.split(',')))
lsearch = list(search.split(','))
print(bdict,lsearch)
#start
up_view = Update_view(url=url,xml_file=xml_file,bargv=bdict,search=lsearch)
#print(up_view.search)
#先获取到src_view里面的jobs列表
all_jobs = up_view.get_all_jobs_in_view(src_view)
#通过筛选,将列表信息显示到show_view
up_view.set_the_view_you_care(show_view)
增强版,加上触发功能
单单是筛选出来关键工程可能还不够,有时候也许还希望再次触发之前失败的工程,在此增加一个增强功能,添加触发参数EXCUTE,支持批量触发工程。
EXCUTE包含3个参数:
- all_stop:终止筛选到的所有工程执行进程。
- all_start:触发筛选到的所有工程。
- start_the_fail_jobs:触发筛选到的工程中上一次构建状态是fail或者abort的工程。
这里我们需要获取工程的状态,可直接调用之前的模块
Python-jenkins模块获取jobs的执行状态
修改后的工程参数如下:
还有就是工程实现上感觉有“坏味道”:
1、它把config保存成xml在用ET解析xml文件,这样不仅需要一个文件转存配置,而且代码实现也比较繁琐。
2、update_view.py后面加的参数太多了,特别是keys和values甚至需要人为的将其对应关系配置好,当keys和values值很多时及其难用。
工程改动点:
新增EXCUTE、 SRC_VIEW、SHOW_VIEW参数
update_view.py执行不需要传入任何参数
代码修改点:
1、xml.etree.ElementTree模块替换为re模块;
2、增加EXCUTE参数,get_jobs_status模块和get_jobs_status方法;
3、参数改成由os模块获取环境变量的方式读取。
增强版资源:update_view.zip
扩展思考:
目前search只支持正向搜索,即将包含search里面关键字的工程保留下来,那能不能添加反向搜索功能,将包含search里面反向搜索的关键字的工程剔除,最终展示的工程列表 = 正向搜寻得到的工程列表 - 反向搜索工程列表。