上周五我在Jenkinsfile管道中尝试使用load时遇到错误,并且无法理解为什么它无法正常工作。
在我的设置中有一个詹金斯大师和一些奴隶。我有一个外部Groovy脚本,根据某些条件处理JSON文件。检查文档,过程是在将作业提交给代理之前,同时在master中加载Groovy脚本。
更新了到期请求
我在这里提供更现实的测试。我针对单个本地Jenkins服务器版本2.107.2进行了测试。
要加载的代码:
class Foobar {
private name = 'foobar'
private now
Foobar() {
this.now = new Date()
}
String say() {
"My name is $name and I was created at $now"
}
}
def build_foobar() {
new Foobar()
}
return this
管道:
def foobar
node() {
foobar = load '/tmp/foobar.groovy'
println "After load: $foobar"
}
node() {
stage('checkout') {
println 'checkout from scm'
}
stage('build') {
println "at build: $foobar"
testing()
}
}
def testing() {
println "at testing: $foobar"
def foo = foobar.build_foobar()
println foobar.say()
}
当我尝试执行它时,foobar
生成一个绑定异常,就像之前我没有声明管道一样,即使我将return this
应用到了foobar的末尾.groovy作为':
[Pipeline] End of Pipeline
groovy.lang.MissingPropertyException: No such property: foobar for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:242)
at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:288)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
at WorkflowScript.testing(WorkflowScript:22)
at WorkflowScript.run(WorkflowScript:16)
为了进行一些调试,我在代码上启用了println
,并且能够获得Script1@XXXXX
,这意味着代码被按预期读取,解析和编译。如果我将foobar
作为参数传递给testing()
,则按预期方式工作:
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/teste
[Pipeline] {
[Pipeline] load
[Pipeline] { (/tmp/foobar.groovy)
[Pipeline] }
[Pipeline] // load
[Pipeline] echo
Script1@150cc39b
[Pipeline] }
[Pipeline] // node
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/teste
[Pipeline] {
[Pipeline] stage
[Pipeline] { (checkout scm)
[Pipeline] echo
checkout
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (build)
[Pipeline] echo
at build: Script1@150cc39b
[Pipeline] echo
at testing: Script1@150cc39b
[Pipeline] echo
My name is foobar and I was created at Mon May 07 09:15:15 BRT 2018
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
现在,当我拥有主节点和从节点时,这是一种不同的行为。让这个代码在slave中运行的唯一方法(在master load
之后)是忘记foobar()
并执行从节点内的管道方法,所有这些都按预期工作。当然,这是不受欢迎的,因为我只是复制n'粘贴代码而不是重复使用它。
我在那边失踪了什么?