书籍名称:[Python3 自动化软件发布系统-Django2 实战]
一般来说,直接使用原生的 Jenkins API 是一个比较繁琐的过程,因为原生的 API,都是以操作原语的方式提供的。而我们在发布系统的开发过程中,会使用包装好的第三方 Python 库(Python-jenkins)来操作 Jenkins API.
Jenkin 原生 API 的获取
一般系统的 API,会在一个专门的文档里,列出冗长而沉闷的 API,然后一个一个地标明其用法,并列举几个示例。
Jenkins 的官方文档里,也有这方面的内容,可以通过 https://pythonhosted.org/jenkinsapi/ 查看。但同时。Jenkins 还在自己真正的应用中,为每个网页提供了实际 API 的输出。比如,进入自己部署好的 Jenkins 首页(https://192.168.200.15:8080/jenkins/
),会在首页下面看到 REST API 的链接(http://192.168.200.15:8080/jenkins/api/
),在这个页面里,会对 Jenkins 常用的任务创建,状态获取等 API 的使用做介绍,并在开始时列出 XML,JSON,Python 的 API。如果点击其中的 Python API,那么我们看到的就是通过 API 访问首页返回的内容。
1 | { |
如果对比一下首页的内容就会发现,这样的 API 学习,给我们一个很直观的对应关系。
再比如,我们进入具体的任务网页(http://192.168.200.15:8080/jenkins/job/ZEP-BACKEND-JAVA/
),这个job 对应的 API 网址为 http://192.168.200.15:8080/jenkins/job/ZEP-BACKEND-JAVA/api/python?pretty=true
(请注意API 网页和 HTML 网页的 URL 对应关系)。
API 页面内容如下:
1 | { |
相信通过这个 API 和网页对照的方式,可以很快了解各个 API 提供的内容。
Python-Jenkins 库的安装
在了解了 Jenkins 能提供的 API 后,我们再学习一下如何使用第三方库快速的开发基于 Jenkins API 的脚本。首先进行 python-api 库的安装。python-api 库官方文档地址为:https://python-jenkins.readthedocs.io/en/latest/api.html;
使用 pip 安装 python-Jenkins:
1
pip install python-jenkins
验证安装
1
python -c "import jenkins"
如果没有任何报错信息输出,则表示 python-jenkins 库安装成功。
Python-Jenkins 的常用方式
在安装完 Python-Jenkins 之后,我们来操作几个 Jenkins 的 API,看看这个库的使用方法。以下几个示例都在 Python IDEL 里输入代码来测试:
获取登录用户及服务器版本
1
2
3
4
5
6
7
8
9
10
11
12In [1]: import jenkins
In [2]: server = jenkins.Jenkins('http://192.168.200.15:8080/jenkins',
...: username='wanwu',
...: password='shkzc123!@#')
In [3]: user = server.get_whoami()
In [4]: version = server.get_version()
In [5]: print('Hello %s from Jenkins %s' % (user['fullName'], version))
Hello wanwu from Jenkins 2.266创建一个视图 View,并获取它的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32In [1]: import jenkins
In [2]: server = jenkins.Jenkins('http://192.168.200.15:8080/jenkins',
...: username='wanwu',
...: password='123456')
In [3]: server.create_view('Manabe', jenkins.EMPTY_VIEW_CONFIG_XML)
In [4]: view_config = server.get_view_config('Manabe')
In [5]: print(view_config)
<?xml version="1.1" encoding="UTF-8"?>
<hudson.model.ListView>
<name>Manabe</name>
<filterExecutors>false</filterExecutors>
<filterQueue>false</filterQueue>
<properties class="hudson.model.View$PropertyList"/>
<jobNames>
<comparator class="hudson.util.CaseInsensitiveComparator"/>
</jobNames>
<jobFilters/>
<columns>
<hudson.views.StatusColumn/>
<hudson.views.WeatherColumn/>
<hudson.views.JobColumn/>
<hudson.views.LastSuccessColumn/>
<hudson.views.LastFailureColumn/>
<hudson.views.LastDurationColumn/>
<hudson.views.BuildButtonColumn/>
</columns>
<recurse>false</recurse>
</hudson.model.ListView>同时我们查看 Jenkins 主页时,会发现多了一个名为 Manabe 的视图。Jenkins 里的视图,可以让我们更方便的组织同类任务,有点类似于操作系统的文件目录功能。如下所示:
发布一次
Demo-Go
任务构建,并且返回当前编译的次数及编译信息1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36In [1]: import json
In [2]: import jenkins
In [3]: from time import sleep
In [4]: server = jenkins.Jenkins('http://192.168.200.15:8080/jenkins',
...: username='wanwu',
...: password='shkzc123!@#',
...: timeout=5)
In [5]: jenkins_job = 'Demo-Go'
In [6]: arg_dic = {
...: 'branch_build': 'master',
...: 'git_url': 'http://192.168.200.16/ZEP-BACKEND/ZEP-BACKEND-GO.git',
...: 'dir_build_file': 'go_demo',
...: 'package_name': 'go_demo',
...: 'zip_package_name': 'go_demo.tar.gz',
...: 'app_name': 'ZEP-BACKEND-GO',
...: 'deploy_version': 'deploy_version'
...: }
In [7]: next_build_number = server.get_job_info(jenkins_job)['nextBuildNumber']
In [8]: server.build_job(jenkins_job, arg_dic)
Out[8]: 82
In [9]: print(next_build_number)
50
In [10]: sleep(10)
In [11]: build_info = server.get_build_info(jenkins_job, next_build_number)
In [12]: print(json.dumps(build_info, sort_keys=True, indent=4, separators=(',', ':')))输出如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142{
"_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun",
"actions":[
{
"_class":"hudson.model.ParametersAction",
"parameters":[
{
"_class":"hudson.model.StringParameterValue",
"name":"branch_build",
"value":"master"
},
{
"_class":"hudson.model.StringParameterValue",
"name":"git_url",
"value":"http://192.168.200.16/ZEP-BACKEND/ZEP-BACKEND-GO.git"
},
{
"_class":"hudson.model.StringParameterValue",
"name":"dir_build_file",
"value":"go_demo"
},
{
"_class":"hudson.model.StringParameterValue",
"name":"package_name",
"value":"go_demo"
},
{
"_class":"hudson.model.StringParameterValue",
"name":"zip_package_name",
"value":"go_demo.tar.gz"
},
{
"_class":"hudson.model.StringParameterValue",
"name":"app_name",
"value":"ZEP-BACKEND-GO"
},
{
"_class":"hudson.model.StringParameterValue",
"name":"deploy_version",
"value":"deploy_version"
}
]
},
{
"_class":"hudson.model.CauseAction",
"causes":[
{
"_class":"hudson.model.Cause$UserIdCause",
"shortDescription":"Started by user wanwu",
"userId":"wanwu",
"userName":"wanwu"
}
]
},
{},
{},
{
"_class":"org.jenkinsci.plugins.workflow.cps.EnvActionImpl"
},
{
"_class":"hudson.plugins.git.util.BuildData",
"buildsByBranchName":{
"refs/remotes/origin/master":{
"_class":"hudson.plugins.git.util.Build",
"buildNumber":50,
"buildResult":null,
"marked":{
"SHA1":"3cac3e33c9d14ea7cb65201b8d135c7f1b462733",
"branch":[
{
"SHA1":"3cac3e33c9d14ea7cb65201b8d135c7f1b462733",
"name":"refs/remotes/origin/master"
}
]
},
"revision":{
"SHA1":"3cac3e33c9d14ea7cb65201b8d135c7f1b462733",
"branch":[
{
"SHA1":"3cac3e33c9d14ea7cb65201b8d135c7f1b462733",
"name":"refs/remotes/origin/master"
}
]
}
}
},
"lastBuiltRevision":{
"SHA1":"3cac3e33c9d14ea7cb65201b8d135c7f1b462733",
"branch":[
{
"SHA1":"3cac3e33c9d14ea7cb65201b8d135c7f1b462733",
"name":"refs/remotes/origin/master"
}
]
},
"remoteUrls":[
"http://192.168.200.16/ZEP-BACKEND/ZEP-BACKEND-GO.git"
],
"scmName":""
},
{
"_class":"hudson.plugins.git.GitTagAction"
},
{},
{},
{},
{},
{},
{
"_class":"org.jenkinsci.plugins.pipeline.modeldefinition.actions.RestartDeclarativePipelineAction"
},
{},
{
"_class":"org.jenkinsci.plugins.workflow.job.views.FlowGraphAction"
},
{},
{},
{}
],
"artifacts":[],
"building":false,
"changeSets":[],
"culprits":[],
"description":null,
"displayName":"#50",
"duration":2682,
"estimatedDuration":3024,
"executor":null,
"fullDisplayName":"Demo-Go #50",
"id":"50",
"keepLog":false,
"nextBuild":null,
"number":50,
"previousBuild":{
"number":49,
"url":"http://192.168.200.15:8080/jenkins/job/Demo-Go/49/"
},
"queueId":82,
"result":"SUCCESS",
"timestamp":1606545618713,
"url":"http://192.168.200.15:8080/jenkins/job/Demo-Go/50/"
}
同时我们看到 Jenkins 的网页版里,相关任务的编译已经出发且完成。由此可见,使用 API 操作 Jenkins,可以很好的与第三方平台进行集成。
封装 Python 脚本
在了解了 python-jenkins 库的简单操作之后,我们来设计一个小脚本,让这个脚本可以自动触发我们前面在Jenkins里定义好的 ZEP-BACKEND-JAVA 任务。
1 | import json |
可以看到,我们手工定义了 ZEP-BACKEND-JAVA 所需的参数。执行脚本,输出信息如下:
1 | 40 |
这些输出,在必要时,都可以将需要的信息入库,为我们提供代码及编译的追溯。
上面的操作完成之后,如果进入 NGINX 服务器,就会在相关目录下,看到已自动生成的软件包了。