环境说明:
我在 master-jenkins 配置了 2 个节点, 分别是 mac_10.1.5.94 和 mac_10.1.71.51
关于 jenkins 集群管理 (节点管理), 参照:[Jenkins] 集群 节点管理 | | 分布式打包
python-jenkins 官方文档
下面是几个 python-jenkins 提供的有关节点的方法, 代码示例 及 返回值:
- get_nodes(depth=0)
- Get a list of nodes connected to the Master
- Each node is a dict with keys 'name' and 'offline'
Returns: | List of nodes, [ { str: str, str: bool} ] |
---|
代码示例:
aa= server.get_nodes()
返回值:
- [
- {
- "name": "master",
- "offline": false
- },
- {
- "name": "mac_10.1.5.94",
- "offline": false
- },
- {
- "name": "mac_10.1.71.51",
- "offline": false
- }
- ]
- get_node_info(name, depth=0)
- Get node information dictionary
Parameters: |
|
---|---|
Returns: | Dictionary of node info, dict |
代码示例:
aa= server.get_node_info("mac_10.1.5.94")
返回值:
- {
- "_class": "hudson.slaves.SlaveComputer",
- "actions": [],
- "assignedLabels": [
- {
- "name": "mac_10.1.5.94"
- },
- {
- "name": "mac_imac_slave"
- }
- ],
- "description": "IMAC",
- "displayName": "mac_10.1.5.94",
- "executors": [
- {},
- {}
- ],
- "icon": "computer.png",
- "iconClassName": "icon-computer",
- "idle": true,
- "jnlpAgent": true,
- "launchSupported": false,
- "loadStatistics": {
- "_class": "hudson.model.Label$1"
- },
- "manualLaunchAllowed": true,
- "monitorData": {
- "hudson.node_monitors.SwapSpaceMonitor": {
- "_class": "hudson.node_monitors.SwapSpaceMonitor$MemoryUsage2",
- "availablePhysicalMemory": -1,
- "availableSwapSpace": 1010827264,
- "totalPhysicalMemory": -1,
- "totalSwapSpace": 1073741824
- },
- "hudson.node_monitors.TemporarySpaceMonitor": {
- "_class": "hudson.node_monitors.DiskSpaceMonitorDescriptor$DiskSpace",
- "timestamp": 1577348794553,
- "path": "/private/var/folders/m2/8_kj4c7s1jbdcc1brnnjs44c0000gn/T",
- "size": 79254544384
- },
- "hudson.node_monitors.DiskSpaceMonitor": {
- "_class": "hudson.node_monitors.DiskSpaceMonitorDescriptor$DiskSpace",
- "timestamp": 1577348794517,
- "path": "/Users/chenpeisong/agent_jenkins",
- "size": 79254544384
- },
- "hudson.node_monitors.ArchitectureMonitor": "Mac OS X (x86_64)",
- "hudson.node_monitors.ResponseTimeMonitor": {
- "_class": "hudson.node_monitors.ResponseTimeMonitor$Data",
- "timestamp": 1577348794517,
- "average": 376
- },
- "hudson.node_monitors.ClockMonitor": {
- "_class": "hudson.util.ClockDifference",
- "diff": -1
- }
- },
- "numExecutors": 2,
- "offline": false,
- "offlineCause": null,
- "offlineCauseReason": "",
- "oneOffExecutors": [],
- "temporarilyOffline": false,
- "absoluteRemotePath": "/Users/chenpeisong/agent_jenkins"
- }
这里注意一下这 "idle"(空闲)这个元素, 当前 slave 机器 配置了同时构建 2 个 job, 只要 slave 已经在构建 job 了(无论正在构建 1 个还是 2 个),idle=flase
只有当 slave 没有正在构建的 job 时, idle=true
- node_exists(name)
- Check whether a node exists
Parameters: | name – Name of Jenkins node, str |
---|---|
Returns: | True if Jenkins node exists |
代码示例:
aa= server.node_exists("mac_10.1.5.94")
返回值:
- true
- assert_node_exists(name, exception_message='node[%s] does not exist')
- Raise an exception if a node does not exist
Parameters: |
|
---|---|
Throws: | JenkinsException whenever the node does not exist |
代码示例:
- aa= server.assert_node_exists("mac_10.1.5.1",exception_message='node[%s] does not exist')
- print(JSON.dumps(aa,ensure_ascii=False,indent=4))
当节点不存在时, 报出指定的错误, 如果节点存在, 则返回 null
返回值:
- Traceback (most recent call last):
- File "/home/wangju/PycharmProjects/wjTest/jenkinsTest/start_slave_job.py", line 16, in <module>
- aa= server.assert_node_exists("mac_10.1.5.1",exception_message='node[%s] does not exist')
- File "/home/wangju/.virtualenvs/wjTest-c3XANhw-/lib/python3.6/site-packages/jenkins/__init__.py", line 1539, in assert_node_exists
- raise JenkinsException(exception_message % name)
- jenkins.JenkinsException: node[mac_10.1.5.1] does not exist
- get_node_config(name)
- Get the configuration for a node.
Parameters: | name – Jenkins node name, str |
---|
代码示例:
aa= server.get_node_config("mac_10.1.5.94")
返回值:
是一个 xml 格式的配置文件
"<?xml version=\"1.1\"encoding=\"UTF-8\"?>\n<slave>\n <name>mac_10.1.5.94</name>\n <description>IMAC</description>\n <remoteFS>/Users/chenpeisong/agent_jenkins</remoteFS>\n <numExecutors>2</numExecutors>\n <mode>EXCLUSIVE</mode>\n <retentionStrategy class=\"hudson.slaves.RetentionStrategy$Always\"/>\n <launcher class=\"hudson.slaves.JNLPLauncher\">\n <workDirSettings>\n <disabled>false</disabled>\n <internalDir>remoting</internalDir>\n <failIfWorkDirIsMissing>false</failIfWorkDirIsMissing>\n </workDirSettings>\n </launcher>\n <label>mac_imac_slave</label>\n <nodeProperties>\n <hudson.slaves.EnvironmentVariablesNodeProperty>\n <envVars serialization=\"custom\">\n <unserializable-parents/>\n <tree-map>\n <default>\n <comparator class=\"hudson.util.CaseInsensitiveComparator\"/>\n </default>\n <int>2</int>\n <string></string>\n <string></string>\n <string>PATH</string>\n <string>/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/rvm/bin:.:/Users/chenpeisong/Library/Android/sdk/platform-tools:/Users/chenpeisong/Library/Android/sdk/tools</string>\n </tree-map>\n </envVars>\n </hudson.slaves.EnvironmentVariablesNodeProperty>\n </nodeProperties>\n</slave>"
我的应用:
我的需求: 实现 iOS 分布式打包. 因 iOS 打包时间较长, 且为了不影响打包性能, jenkins 最多能支持构建 2 个 job, 这样在发版周, 就需要经常排队打包.
为了提升打包的效率, 现在使用 2 台 Mac 打包.
为了更减轻测试打包的负担, 现在为自动化打包做了接口支持, 如何通过接口实现选择不同的 slave 打包呢? 这就是我需要解决的问题.
我的配置:
- slave1:
- node_name:mac_10.1.71.51
配置在该 slave 的 job 名: ios_official_51
- slave2:
- node_name:mac_10.1.5.94
配置在该 slave 的 job 名: ios_official_94
slave1 的配置高于 slave2, 所以我的策略是: 只有当 slave1 有构建任务时, 才使用 slave2 打包
无论要构建的 job 是不是位于 slave, 通过接口操作 jenkins 构建 job, 分为 3 步:
1. 获取打包 job 名称
2. 启动打包, 并获得 build_number
3. 根据 build_number 获取打包结果
我的思考:
如果要启动的 job 位于 slave, 与启动普通的 job 相比, 只是会增加 1 个步骤, 判断 slave 是否在线.
如果 slave 都在线, 选择哪个 slave? 如果 slave 有的在线, 有的不在线, 如何选择? 解决了这个问题, 其它的操作步骤与构建普通的 job 一样.
我使用的策略:
因为目前我一共配置了 2 台 slave, 所以
分 3 种情况:
2 台 slave 都在线 返回 True
2 台 slave 都不在线 返回 False
1 台 salve 在线, 1 台 slave 不在线 : 返回在线的 salve 名称
这个函数中的核心是使用 python-jenkins 提供的方法 server.get_nodes()获取 salve 机器的在线状态:
如果 slave 是离线状态, 则 offline 的值为 true
代码实现:
首先创建 jenkins server 实例:
创建 jenkins 实例(先通过 pip 下载 python-jenkins):
- # 导入依赖
- import jenkins
- import time
- import JSON #从文件中读取 JSON 格式的测试结果
- # 定义远程的 jenkins master server 的 url 以及 Port
- jenkins_server_url = 'http://10.2.1.92:8080/jenkins/'
- # 定义用户的 userid 和 apitoken(在 jenkins 中生成)
- user_id = 'admin'
- api_token = '11d8c79994b1e6d554c857b1d96fcf4dfe' #测试服务器
- # 实例化 jenkins 对象, 连接远程的 jenkins master server
- server = jenkins.Jenkins(jenkins_server_url,username=user_id,password=api_token)
- aa= server.get_nodes()
- print(JSON.dumps(aa,ensure_ascii=False,indent=4))
如果只有 1 个 slave 在线, 返回其名称, 都在线 true, 都不在线 flase
- def get_node_offline_state_or_line_node_name(server):
- '''
- 获取 node 在线状态
- :param:jenkins_server
- :return: 都在线 true, 都不在线 flase,1 个在线: 在线 node 名称
- '''
- node_offline_list = server.get_nodes()[1:]
- node_imac_offline_state = node_offline_list[0]['offline']
- node_mini_offline_state = node_offline_list[1]['offline']
- if node_mini_offline_state and node_imac_offline_state:
- # 都不在线
- return False
- elif not node_mini_offline_state and not node_imac_offline_state:
- # 都在线
- return True
- elif not node_mini_offline_state or not node_imac_offline_state:
- # 1 台机器在线, 返回在线的 node 名
- if not node_mini_offline_state == True:
- return 'mac_10.1.71.51'
- else:
- return 'mac_10.1.5.94'
根据在线的 slave, 选择要构建的 job 名字
下面的函数中使用到了 python-jenkins 提供的方法 get_node_info(node_name), 它的返回值中有一个 idle 字段, 可以判断 slave 是否有正在构建的 job
注意一下: 只要 slave 有 1 个 job 是正在构建的状态, idle 的状态就是 false
- node_offline_state_or_line_node_name = get_node_offline_state_or_line_node_name(server)
- if not node_offline_state_or_line_node_name:
- # 都不在线
- job_name = None
- code = 204
- msg = 'slave 离线, 请联系管理员!'
- elif node_offline_state_or_line_node_name is True:
- # 都在线
- mini_idle_state = server.get_node_info('mac_10.1.71.51')['idle']
- imac_idle_state = server.get_node_info('mac_10.1.5.94')['idle']
- if not mini_idle_state and imac_idle_state:
- # 只有 mini 不空闲时, 选择 iMac 打包
- job_name = 'ios_official_94'
- else:
- # mini 空闲, imace 空闲, 选择 nimi 打包
- # mini 和 iMac 都不空闲, 选择 mini 打包
- job_name = 'ios_official_51'
- elif node_offline_state_or_line_node_name == 'mac_10.1.71.51':
- # nini 在线
- # return 'mac_10.1.71.51'
- job_name = 'ios_official_51'
- elif node_offline_state_or_line_node_name == 'mac_10.1.5.94':
- # iMac 在线
- # return 'mac_10.1.5.94'
- job_name = 'ios_official_94'
[Python]通过 python-jenkins 操作 jenkins slave 启动 job | 通过 python-jenkins 实现 iOS 自动化打包接口
来源: http://www.bubuko.com/infodetail-3357348.html