网站首页 > 博客文章 正文
问题描述
在 Jenkins Pipeline 中,使用 Groovy 语言进行共享库的开发。从理论上讲,我们可以按照需求,开发我们想要的任何功能。但是,现实中总会遇到一些棘手的问题。比如这次遇到的 Dependency hell - 我们在共享库中,通过 Grape 引入我们需要的模块,这些模块又依赖于其他模块,然而这些模块与 Jenkins 正在使用的模块冲突。
比如,我们需要使用 [[https://github.com/ThStock/docker-java-parser|ThStock/docker-java-parser]] 模块解析 Dockerfile 文件,以检查其是否符合我们的规范。但是 [[https://github.com/ThStock/docker-java-parser|ThStock/docker-java-parser]] 模块需要 commons-lang 3.5 模块,而 Jenkins 使用 commons-lang 2.6 版本。这便是冲突。
该笔记将记录:如何解决 Jenkins Pipeline 共享库的依赖问题,以及相关问题处理。
注意事项
在多数 常规的 自动化场景中,不会遇到该问题,只是我们的需求太特殊了,需要解决这个问题。
解决方案
方案一、通过脚本实现
既然存在冲突,导致部分任务我们无法通过 Pipeline 共享库实现,那么我们可以编写自定义脚本来实现(比如通过 python 脚本实现某个极度复杂的统计功能),然后在 Pipeline 中执行该脚本。
现在,我们还需要将该脚本保存到 Pipeline 共享库中,作为共享库的组件,与其他用户分享,毕竟这个脚本也是共享库的一部分。根据目前(02/20/2021)的共享库的要求,只能保存在 resources/ 目录中。现在的问题就是:我们如何执行 resources/ 目录中的脚本
在 Jenkins Pipeline 中,可以在共享库的 resources/ 目录中保存资源文件,然后通过 def text = libraryResource 'data.yaml' 的方式读取资源文件。
整个过程就是这样:1)通过 libraryResource 读取脚本内容,2)然后使用 writeFile 写入外部文件,2)再执行该外部文件
程序示例:
def functionsContent = libraryResource 'com/mycorp/pipeline/somelib/functions.sh'
writeFile file: '/tmp/functions.sh', text: functionsContent
sh "sh /tmp/function.sh"
方案二、计算路径(方案一的改进)
方案一有个问题:如果我们有很多脚本,那么这些脚本只能独立执行,不能相互引用。这是因为脚本是被先读取出来,然后再执行,我们不知道正在读取的脚本中引用的文件,因此就无法同时读取相关的文件。这就导致不同脚本中,会出现大量重复代码。(也不是没有可能,我们可以自己实现解析器,以注释的形式定义脚本依赖关系,然后在加载时进行解析,以加载相关依赖)
但是,办法总是有的,我们通过获取当前源码文件的路径,然后计算出脚本文件路径。这成为解决这个问题的关键。
下面的三种方法都可以获取源码文件的路径:
// 方法一
def filePath = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()
println filePath
// 方法二
import groovy.transform.SourceURI
import java.nio.file.Path
import java.nio.file.Paths
@SourceURI URI sourceUri
Path scriptLocation = Paths.get(sourceUri)
println scriptLocation.toString()
// 方法三
def filePath = this.class.classLoader.getResourceLoader().loadGroovySource(this.class.name).toURI()
println filePath
// 这些方法都将输出如下内容:
/var/jenkins_home/jobs/pipeline-example/builds/22/libs/TOOLBOX/vars/fileLocation.groovy
因此我们使用如下方法,适用于全局变量(vars/)与类库(src/):
import java.nio.file.Path;
import java.nio.file.Paths;
def sourceFile = "/var/jenkins_home/jobs/pipeline-example/builds/22/libs/TOOLBOX/vars/fileLocation.groovy"
Path path = Paths.get(sourceFile)
while (dirname = path.getFileName().toString()) {
if ("vars".equals(dirname) || "src".equals(dirname))
break
path = path.getParent()
}
def resourcesFolder = path.getParent().resolve('resources').toString()
println resourcesFolder // /var/jenkins_home/jobs/pipeline-example/builds/22/libs/TOOLBOX/resources
但是,该方法也有局限性:当 Jenkins 存在多个共享库,那么通过该方法定位的 resources 目录可能不是我们期望的目录。zheasdfasdf
方案三、另外一种思路
自定义类加载器,来加载 Jar 包,以使用不同的类:
ClassLoader cl = new URLClassLoader(new URL[] {new File("v1.jar").toURL()}, Thread.currentThread().getContextClassLoader());
Class<?> clazz1 = cl.loadClass("com.abc.Hello")
ClassLoader c2 = new URLClassLoader(new URL[] {new File("v2.jar").toURL()}, Thread.currentThread().getContextClassLoader());
Class<?> clazz2 = cl.loadClass("com.abc.Hello");
# 02/20/2021 目前,该方案并不适用于此问题,因为 Jar 包的管理与定位又成为另外一个问题。我们在此记录此方法,为后面提供一种思路,也许那一天就用到了。
参考文献
How to invoke bash functions defined in a resource file from a Jenkins pipeline Groovy script?
Java - how to load different versions of the same class? - Stack Overflow
android - Java: How to import older version of class - Stack Overflow
How do you get the path of the running script in groovy? - Stack Overflow
groovyshell - How to use \@SourceURI annotation to retrieve the full path of the script file in Groovy 2.3?
jenkins - How to load files from resources folder in Shared library without knowing their names (or number)?
猜你喜欢
- 2024-09-20 Pipeline+Jenkins流水线构建(jenkins工作流)
- 2024-09-20 用代码描述流水线-Jenkins Pipeline 详解
- 2024-09-20 「博文精选」Jenkins pipeline控制并行执行job个数
- 2024-09-20 微服务从代码到k8s部署应有尽有大结局(k8s部署)
- 2024-09-20 持续集成工具 Jenkins 的使用(jenkins持续集成自动化测试)
- 2024-09-20 测试开发丨从零开始,手把手教你在Jenkins中创建Pipeline Job!
- 2024-09-20 Jenkins Pipeline 部署 Kubernetes 应用
- 2024-09-20 Jenkins Pipeline 结合 Gitlab 实现 Node 项目自动构建
- 2024-09-20 别再用jenkins freestyle了,教你快速编写jenksinfile,离线调试
- 2024-09-20 Jenkins 持续集成企业实战示例(jenkins持续集成原理)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)