简介
Jenkins是一个比较方便的一个脚本调度平台工具。
python中封装有Jenkins的API类库,用于处理Jenkins相关的操作。Jenkins对外提供的其实是一堆Restful接口,python-jenkins要做的实际上就是去请求这些接口,并在此基础上做了些包装来保证使用方便。
python中Jenkins包的安装:
pip install python-jenkins
python文件中引入Jenkins:
import jenkins
基于python-Jenkins,我们可以做什么呢?如:
- 创建新的job
- 复制已存在的job
- 删除、更新job
- 获取job的构建信息、版本信息等;
- 运行一个job;
- and many more;
简单看了一下,Jenkins界面上能做的操作,python-Jenkins基本也能干。
接下来,针对几个常用的功能,举几个例子(多数来自于官方示例)介绍下,如何通过python-Jenkins来实现。
功能介绍
连接Jenkins
如何连接Jenkins,并返回Jenkins的服务器信息。
import jenkins
server = jenkins.Jenkins('http://xxx:30030/', username='xx', password='xx')
user = server.get_whoami()
version = server.get_version()
print('Hello %s from Jenkins %s' % (user['fullName'], version))
# Hello xx from Jenkins 2.222.4
python-jenkins同样支持kerberos登录,这里就不介绍了,有兴趣可以去查看参考文献2里的Example 2。
操作Jenkins的jobs
核心功能,下面例子将展示如何创建、配置和删除Jenkins jobs。
首先需要连接上Jenkins后台,并拿到返回的server对象。
基本功能集锦
先来个基本功能集锦:
# 创建job
server.create_job('empty', jenkins.EMPTY_CONFIG_XML)
# 构建无参的job
server.build_job('empty')
# 设置job不可见
server.disable_job('empty')
# 复制job
server.copy_job('empty', 'empty_copy')
# 设置job可见
server.enable_job('empty_copy')
# 重新配置job
server.reconfig_job('empty_copy', jenkins.RECONFIG_XML)
# 删除job
server.delete_job('empty')
# 构建有参的job,比如说指定job有两个参数: 'param1' 和 'param2'
server.build_job('api-test', {'param1': 'test value 1', 'param2': 'test value 2'})
获取当前所有的job列表
获取当前所有的job列表:
jobs = server.get_jobs()
最终返回的是个大list,每个元素是一个dict,含有5个key,即_class、_name、url、color和fullname,举个例子:
{'_class': 'hudson.model.FreeStyleProject', 'name': 'rs_hc_jsc_sc_year', 'url': 'http://xxx:30030/job/rs_hc_jsc_sc_year/', 'color': 'disabled', 'fullname': 'rs_hc_jsc_sc_year'}, {'_class': 'hudson.model.FreeStyleProject', 'name': 'SEV_FIN_HL_INCOME_DAY_VIEW_oss', 'url': 'http://xxx:30030/job/SEV_FIN_HIEW_oss/', 'color': 'blue', 'fullname': 'SEV_FIN_HIEW_oss'},
其中,'fullname’的value等同于实际job的name。
另外,get_jobs()
里实际上有个view_name
参数,默认是None,如果指定的话,get_jobs(view_name=xxx)
将只返回绑定在视图xxx下的所有jobs。
获取指定job的基本配置
获取已存在的指定job的基本配置:
my_job = server.get_job_config('job_name')
print(my_job) # job configuration (XML format)
返回的XML里,包括了job所有的配置信息,如:
- 参数
- 运行时间
- 依赖的上游任务
- 待运行的脚本任务
- and more
截取xml部分内容,以作展示:
<triggers>
<jenkins.triggers.ReverseBuildTrigger>
<spec></spec>
<upstreamProjects>depend_consult_info_a_file</upstreamProjects>
<threshold>
<name>SUCCESS</name>
<ordinal>0</ordinal>
<color>BLUE</color>
<completeBuild>true</completeBuild>
</threshold>
</jenkins.triggers.ReverseBuildTrigger>
</triggers>
<concurrentBuild>false</concurrentBuild>
<builders>
<hudson.tasks.Shell>
<command>sh /home/bin/run-task.sh dws/consult_info ${time_hour}</command>
</hudson.tasks.Shell>
</builders>
需要注意,根据job创建时依赖的模板不同,不同类型job在这里返回的xml也是不同的。并不是说,针对所有job,我只要解析出hudson.tasks.Shell节点下的内容,就能知道这个job是干嘛的,因为有的不同类型的job,可能并没有hudson.tasks.Shell节点。
获取指定job的信息字典
拿到job的信息字典:
infors = server.get_job_info('job_name')
print(infors)
字典含有以下key:
- ‘_class’:应该是job依赖的模板类型;
- ‘actions’:似乎是job的参数
- ‘description’:job的描述
- ‘displayName’
- ‘displayNameOrNull’:暂时不明
- ‘fullDisplayName’:
- ‘fullName’:job的全name
- ‘name’:job的name
- ‘url’:job的url地址;
- ‘buildable’:暂时不明,如:
'buildable': True,
- ‘builds’:dict-list,存储了一堆构建记录的dict;
- ‘color’:暂时不明
- ‘firstBuild’:暂时不明
- ‘healthReport’:暂时不明
- ‘inQueue’:暂时不明,如
'inQueue': False
- ‘keepDependencies’:暂时不明,如
'keepDependencies': False
- ‘lastBuild’:最近一次构建的构建记录,如下;
- ‘lastCompletedBuild’:最近一次已完成??构建的构建记录,如下;
- ‘lastFailedBuild’:最近一次失败构建的构建记录,如下;
- ‘lastStableBuild’:最近一次稳定构建的构建记录,如下;
- ‘lastSuccessfulBuild’:最近一次成功构建的构建记录,如下;
- ‘lastUnstableBuild’:最近一次不稳定构建的构建记录,如下;
- ‘lastUnsuccessfulBuild’:最近一次不成功构建的构建记录,如:
'lastUnsuccessfulBuild': {'_class': 'hudson.model.FreeStyleBuild', 'number': 131, 'url': 'http://xxx:30030/job/dws_consult_info/131/'}
- ‘nextBuildNumber’:下次构建的序号(指代第多少次构建),如:
'nextBuildNumber': 145
- ‘property’:job依赖的参数,如:
'property': [{'_class': 'hudson.model.ParametersDefinitionProperty', 'parameterDefinitions': [{'_class': 'me.leejay.jenkins.dateparameter.DateParameterDefinition', 'defaultParameterValue': {'_class': 'me.leejay.jenkins.dateparameter.DateParameterValue', 'name': 'time_hour', 'value': '20230910'}, 'description': '当前日期的前一天', 'name': 'time_hour', 'type': 'DateParameterDefinition'}]}, {'_class': 'com.xxx.jenkins.ChargerJobProperty'}]
- ‘queueItem’:暂时不明
- ‘concurrentBuild’:暂时不明,如
'concurrentBuild': False
- ‘disabled’:该job是否不可见,如
'disabled': False
- ‘downstreamProjects’:dict-list,即与其直连的下游任务
- ‘labelExpression’:暂时不明
- ‘scm’:暂时不明
- ‘upstreamProjects’:dict-list,依赖的上游任务,举例:
'upstreamProjects': [{'_class': 'hudson.model.FreeStyleProject', 'name': 'depend_consult_info_a_file', 'url': 'http://xxx:3333/job/depend_consult_info_a_file/', 'color': 'blue'}]
以上,想获取什么信息就可以去取,比如我现在想获取一个job上次完成构建的构建序号:
last_build_number = server.get_job_info('api-test')['lastCompletedBuild']['number']
获取执行构建记录的完整信息
拿到指定构建记录的完整信息:
如:
last_build_number = server.get_job_info('api-test')['lastCompletedBuild']['number']
build_info = server.get_build_info('api-test', last_build_number)
print(build_info)
输出举个例子,如:
{
'_class': 'hudson.model.FreeStyleBuild',
'actions': [{
'_class': 'hudson.model.CauseAction',
'causes': [{
'_class': 'hudson.model.Cause$UpstreamCause',
'shortDescription': 'Started by upstream project "depend_consult_info_a_file" build number 126',
'upstreamBuild': 126,
'upstreamProject': 'depend_consult_info_a_file',
'upstreamUrl': 'job/depend_consult_info_a_file/'
}]
}, {
'_class': 'hudson.model.ParametersAction',
'parameters': [{
'_class': 'me.leejay.jenkins.dateparameter.DateParameterValue',
'name': 'time_hour',
'value': '20230907'
}]
}, {}],
'artifacts': [],
'building': False,
'description': None,
'displayName': '#20230907-Timer Trigger',
'duration': 1006379,
'estimatedDuration': 1050847,
'executor': None,
'fullDisplayName': 'dws_consult_info #20230907-Timer Trigger',
'id': '141',
'keepLog': False,
'number': 141,
'queueId': 625157,
'result': 'SUCCESS',
'timestamp': 1694128120063,
'url': 'http://xxx:30030/job/dws_consult_info/141/',
'builtOn': '',
'changeSet': {
'_class': 'hudson.scm.EmptyChangeLogSet',
'items': [],
'kind': None
},
'culprits': []
}
以上,如果想获取到以上构建记录里,参数time_hour的值,就可以层层解剖,使用以下代码:
build_info = server.get_build_info(job_name, last_build_number)
print(build_info['actions']['parameters'][0]['value'])
当前是否处于构建中:is_building=build_info['building']
指定构建的成功与否:build_result = build_info['result']