1、今天工作发现了一个很有意思的错误,困扰了我一天多时间。
pipeline工程脚本中有这么一个步骤(主要目的是对比a 和b两个文件差异,将只出现在b中的差异内容输出到diff.sql中):
stage('Compare SQL Files') {
steps {
sh '''
mkdir -p output
diff --unchanged-line-format= --old-line-format= --new-line-format='%L' a b > output/diff.sql
'''
}
}
每次执行时都到这显示错误,但是控制台日志却又没有显示error,我远程到工作节点上去看,发现该创建的output/diff.sql也创建了,该输出的差异内容也写入了diff.sql中,也就是这一步骤明明正确执行了但却报错,我在远程终端输入diff这行命令也没有报错,一开始以为是'%L'单引号原因,但是测试发现没有影响,然后查资料有看到pipeline报错有一种原因是:pipeline执行sh命令时,当返回的状态码是非零
值,则触发pipeline运行失败。
我猜想我这步显示失败很有可能就是这个原因,我在终端上执行了diff命令后,再执行echo $?查看上个命令的返回状态码,果然是1,我不太理解,既然不正确为什么不报错呢?查看了diff --help ,在后面看到一行文字“如果输入相同,则退出状态为 0;1 表示输入不同;2 表示有错误产生。”,我才明白,原来因为a b两个文件内容不相同,所以退出状态码为1,而这也正是导致了pipeline执行失败,我测试将两个文件内容换成相同的,果然构建成功了。
已经确定了diff这条命令没问题,我需要忽视产生的错误,在命令后面加上|| :就好了
diff --unchanged-line-format= --old-line-format= --new-line-format='%L' sql-update/old.sql sql-update/new.sql > sql-update/diff.sql || :
2、在使用script块将Groovy代码包装在单个步骤中时,总是报错:
java.lang.NoSuchMethodError: ‘boolean org.kohsuke.groovy.sandbox.SandboxTransformer.mightBePositionalArgumentConstructor(org.codehaus.groovy.ast.expr.VariableExpression)’
原因以及解决办法有:
这个错误可能是因为使用了不兼容的Groovy版本或与Jenkins的兼容性问题。
要解决此问题,可以尝试以下几个步骤:
-
确认Groovy版本:Jenkins对Groovy版本有一些限制。例如,如果使用Jenkins 2.222.1或更早的版本,需要使用Groovy 2.46.0或更早版本。因此,请确保使用了Jenkins推荐的Groovy版本。
-
更新Jenkins版本:有些Jenkins错误可能是由于使用旧版本造成的。尝试更新Jenkins到最新版本,看看能否解决问题。
-
禁用Sandbox:这种错误可能是由于使用Sandbox造成的。Sandbox对一些Groovy方法进行了限制,以防止Jenkins中的恶意代码。在某些情况下,这可能会影响一些合法的Groovy代码。可以尝试禁用Sandbox,并观察是否仍然会报错。
-
检查插件:有些插件可能不与当前Jenkins和Groovy版本兼容。请检查你使用的插件,并确保它们是最新的。
-
尝试更新Jenkins的Java环境:当Jenkins安装在与其他Java应用程序共享的环境中时,可能会发生类似的错误。尝试升级你的Java环境并重新启动Jenkins,然后观察问题是否仍然存在。
最后通过升级jenkins版本和Groovy版本,使其兼容解决了该报错问题。
3、语法报错
stage('copy diff.sql File') {
steps {
sh '''
database=$(kubectl get pods -n bm-system | grep -e "^metadata" | awk '{print $1}' | uniq)
echo ${database}
kubectl -n bm-system exec -i $database -- /bin/bash -c \'if [ ! -f "./diff.sql" ]; then touch diff.sql; fi\'
kubectl cp -n bm-system sql-update/diff.sql ${database}:diff.sql
'''
}
}
代码使用了单引号将命令 'if [ ! -f "./diff.sql" ]; then touch diff.sql; fi'
包含起来,并使用反斜杠对其中的引号进行转义,以确保在命令传递给 /bin/bash -c
参数时正确解析。