# 一种通用方式扩展Jenkins构建能力 之前分享过一篇基于 **Apache Ant** 设计的插件机制,通过将一个完整的 **build.xml** 构建逻辑拆分到不同的 **Ant** 脚本包中,以此实现构建能力扩展。这种方式看起来巧妙,但是没有一个工具或者平台作为其载体是很难使用的。今天就分享一个将这种机制融入 **Jenkins** 中的方法。 ## 背景说明 **Jenkins** 平台这么吸引大家的原因,主要是其优秀的插件机制和现存庞大的插件库。通常在做构建配置中,经常需要扩展的区域就是 **Build** 这里,如下图: ![](https://files.mdnice.com/user/23272/b737417c-d6e8-4f39-9424-7b20c4343b03.png) 为了实现各种工具对接和构建逻辑需要自己开发插件或者使用现存插件,又或者通过 **Shell** 编写大量脚本(很不易读,也难维护)。 新增工具通过 Jenkins 的插件机制来管理,每个插件的配置方法会不一样,而且 Jenkins 插件安装的越多,会出现内存消耗越高,运行允许越慢等问题。 ## 解决方案 将上面介绍的 **Ant** 插件机制,融入 **Jenkins** 中可以很好的解决这些问题,做出来的样子如下: ![](https://files.mdnice.com/user/23272/89d210b7-90dd-43db-b7f2-80613bd2f418.png) 这种方案有以下几方面好处: 第一,配置方式统一。所有的功能都通过 **Ant** 脚本包装,输入参数就是键值对,采用配置即构建比采用编程即构建使用起来简单的多,复杂的构建逻辑都可以装入插件包。 第二,所有的 **Jenkins** 实例都共享这一套插件机制,一个插件包更新所有实例都生效,也不用重启 **Jenkins**,即便插件包出现 **bug** 也可以快速修复,并且多 **Jenkins** 实例共享一套插件模型,很适合大规模和高并发构建场景。 ![](https://files.mdnice.com/user/23272/cadaa658-9d26-4095-b3b9-ab0ef47a9972.png) 第三,在 **Jenkins Pipeline** 中也可以直接使用,不采用 **Jenkins Shared Library** 进行二次包装也可以。 ```groovy pipeline { agent any stages { stage('Hello') { steps { echo '--//INFO: this is a test pipeline' oesStep stepId: "sample", stepProps: [ stepProp(key: "arg1", value:"hi, jenkins oes-step") ] oesPipeline environs: """ HELLO_v1=hi, oes-pipeline RUN_STAGES=build """.stripIndent(), provider: oesPipelineConfigFromJenkins(content: ''' environment: HELLO: ${HELLO_v1} pipeline: - name: build steps: - step.id: sample arg1: 'hi, oes-jenkins' '''.stripIndent() ) } } } } ``` ## 使用方法 第一,安装插件,将插件包上传到 **Jenkins** 中就可以了。 ![](https://files.mdnice.com/user/23272/386ea25f-b936-42cc-81ac-7416136077fc.png) 第二,搭建 Minio 服务,通过 **docker-compose** 搭建,并配置一个管理账号和创建一个 **bucket**,用于存放 **oes-steps** 脚本包。 ```yaml version: '3' services: minio: image: registry.cn-hangzhou.aliyuncs.com/k8ops/minio:RELEASE.2021-08-05T22-01-19Z restart: unless-stopped volumes: - ./data:/data ports: - "14090:9000" - "14091:9001" environment: MINIO_ROOT_USER: rootroot MINIO_ROOT_PASSWORD: rootroot123 command: server /data --console-address ":9001" ``` 插件包按照归档规范进行归档 ![](https://files.mdnice.com/user/23272/3efeae40-67be-452f-9edd-b8b55f7ddd2f.png) 第三,配置 **Jenkins**,按照下图方式进行配置 ![](https://files.mdnice.com/user/23272/64a7cc8b-c62e-48af-9dd8-6b483de07896.png) 第四,测试配置是否正确,通过创建一个测试任务,配置任务的 **Build** 区域添加一个 **OES Step**,在 **Step Name** 下拉列表中出现任务列表,说明配置正常的,否则需要查看日志和分析错误信息。 ![](https://files.mdnice.com/user/23272/fa17bd8b-331a-449d-9290-4fe33cd9ee8e.png) 第五,触发测试任务,查看运行结果是否正常,如下图就算正常 ![](https://files.mdnice.com/user/23272/3b487b5c-d74e-40d6-be86-b9116b26f077.png) ## 实现流程 结合上面的使用流程,分析 **OES Step** 这个构建步骤的实现过程, 第一,创建一个 **OesStepBuilder** 设计配置界面和相关实现代码, ![](https://files.mdnice.com/user/23272/0ed1297d-c9df-4d4c-8912-d248dc777cb4.png) 第二,当触发构建时,会触发 **perform** 函数 ![](https://files.mdnice.com/user/23272/12d98ddc-0c26-43fd-8691-b481c89c183f.png) 第三,执行 **runStep** 函数,这里会去 minio 中下载两个包,**asl** 包和 对应 **step** 包 ![](https://files.mdnice.com/user/23272/b1cd0768-6229-4d4a-8d64-2e422c98f8bb.png) 第四,组装 **ant** 命令并执行 ![](https://files.mdnice.com/user/23272/5b2e7254-0ba4-4cba-ad70-9a98ab6b89b6.png) 执行过程中可以看到实际执行的命令 ![](https://files.mdnice.com/user/23272/c18e745a-0811-4d38-a342-4eaa06045563.png) ## 最后 此插件代码已经开源 **[oes-pipeline-plugin](https://github.com/opsbox-ecosystem/oes-pipeline-plugin "oes-pipeline-plugin")** 和 **[oes-step-asl](https://github.com/opsbox-ecosystem/oes-step-asl "oes-step-asl")**,对此感兴趣的可以分析一下 **OES Pipeline** 的实现代码,以及里面针对 **Credential** 转化成环境变量的处理。