Jenkins:将插件 DSL 函数添加到共享库函数时没有此类 DSL 方法
Jenkins: No Such DSL Method when adding a plugin DSL function to a shared library function
我们正在使用 JCasC 定义如下的 jenkins 共享库:
controller:
JCasC:
configScripts:
jenkins-casc-unclassified: |
unclassified:
globalLibraries:
libraries:
- defaultVersion: "master"
implicit: true
name: "com.company.jenkins"
retriever:
modernSCM:
scm:
github:
configuredByUrl: true
credentialsId: "..."
id: "..."
repoOwner: "Company"
repository: "Company_CICD"
repositoryUrl: "https://github.com/company/Company_CICD.git"
traits:
- gitHubBranchDiscovery:
strategyId: 1
- gitHubPullRequestDiscovery:
strategyId: 1
- gitHubForkDiscovery:
strategyId: 1
trust: "gitHubTrustPermissions"
我们为 Kubernetes Plugin 制作了一个方便的功能,使我们能够大大缩短代码。然而,在尝试消除 2 行时,我们遇到了一个我们想澄清的奇怪错误:
java.lang.NoSuchMethodError: No such DSL method 'getPodTemplate'
奇怪的是,在不更改导入或函数名称的情况下,它就出现了。
例如,这个有效:
// src/com/company/jenkins/Util.groovy
package com.onscale.jenkins
def getPodTemplate(String label, List<String> containers, List<String> volumes, String yaml) {
containers = containers.collect {
value -> return getContainerTemplate(value)
}
volumes = volumes.collect {
value -> return getVolume(value)
}
return [
label: label,
yaml: yaml,
containers: containers,
volumes: volumes
]
}
// Jenkinsfile
def util = new com.onscale.jenkins.Util()
podTemplate (
util.getPodTemplate(
'jenkinsbuild', // Label
['jnlp', 'docker', 'kubectl'], // Containers
['host-path'], // Volumes
podSpec
)
)
但事实并非如此:
// src/com/company/jenkins/Util.groovy
package com.onscale.jenkins
def getPodTemplate(String label, List<String> containers, List<String> volumes, String yaml) {
containers = containers.collect {
value -> return getContainerTemplate(value)
}
volumes = volumes.collect {
value -> return getVolume(value)
}
return podTemplate(
label: label,
yaml: yaml,
containers: containers,
volumes: volumes
)
}
// Jenkinsfile
def util = new com.onscale.jenkins.Util()
util.getPodTemplate(
'jenkinsbuild', // Label
['jnlp', 'docker', 'kubectl'], // Containers
['host-path'], // Volumes
podSpec
)
两者之间的变化是if getPodTemplate returns podTemplate.
我们四处寻找。 堆栈溢出让我们感到困惑,因为我们没有使用 var/function.groovy
制作共享库的方法(我不太确定每种“种类”的共享库被称为什么),我们正在导入使用“ new" 和一个 globalLibrary.
有什么想法吗?
此作业 DSL 错误似乎是在函数未编译时发生的。在这种情况下,该函数不会编译,因为 groovy 执行此操作,您可以在不带括号的情况下调用函数。
示例:
def foo(name, closure) {println name; println closure()}
可以通过以下方式调用。
foo(“asdf”,{return “asdf”})
foo “asdf” {return “asdf”}
foo(“asdf”) {return “asdf”}
带括号和不带括号
但是这样:
foo(“asdf”)
将抛出错误 MissingMethodException
因为 foo 需要 2 个参数。而我最初认为它会 return 部分。
所以当我们 return podTemplate 没有闭包作为最后一个参数时,我们实际上破坏了该方法的编译,因此我们得到一个 DSL 错误,因为共享库无法编译。
解决方案是添加一个闭包最终参数,并将其作为最后一个参数传递给 podTemplate
我们正在使用 JCasC 定义如下的 jenkins 共享库:
controller:
JCasC:
configScripts:
jenkins-casc-unclassified: |
unclassified:
globalLibraries:
libraries:
- defaultVersion: "master"
implicit: true
name: "com.company.jenkins"
retriever:
modernSCM:
scm:
github:
configuredByUrl: true
credentialsId: "..."
id: "..."
repoOwner: "Company"
repository: "Company_CICD"
repositoryUrl: "https://github.com/company/Company_CICD.git"
traits:
- gitHubBranchDiscovery:
strategyId: 1
- gitHubPullRequestDiscovery:
strategyId: 1
- gitHubForkDiscovery:
strategyId: 1
trust: "gitHubTrustPermissions"
我们为 Kubernetes Plugin 制作了一个方便的功能,使我们能够大大缩短代码。然而,在尝试消除 2 行时,我们遇到了一个我们想澄清的奇怪错误:
java.lang.NoSuchMethodError: No such DSL method 'getPodTemplate'
奇怪的是,在不更改导入或函数名称的情况下,它就出现了。
例如,这个有效:
// src/com/company/jenkins/Util.groovy
package com.onscale.jenkins
def getPodTemplate(String label, List<String> containers, List<String> volumes, String yaml) {
containers = containers.collect {
value -> return getContainerTemplate(value)
}
volumes = volumes.collect {
value -> return getVolume(value)
}
return [
label: label,
yaml: yaml,
containers: containers,
volumes: volumes
]
}
// Jenkinsfile
def util = new com.onscale.jenkins.Util()
podTemplate (
util.getPodTemplate(
'jenkinsbuild', // Label
['jnlp', 'docker', 'kubectl'], // Containers
['host-path'], // Volumes
podSpec
)
)
但事实并非如此:
// src/com/company/jenkins/Util.groovy
package com.onscale.jenkins
def getPodTemplate(String label, List<String> containers, List<String> volumes, String yaml) {
containers = containers.collect {
value -> return getContainerTemplate(value)
}
volumes = volumes.collect {
value -> return getVolume(value)
}
return podTemplate(
label: label,
yaml: yaml,
containers: containers,
volumes: volumes
)
}
// Jenkinsfile
def util = new com.onscale.jenkins.Util()
util.getPodTemplate(
'jenkinsbuild', // Label
['jnlp', 'docker', 'kubectl'], // Containers
['host-path'], // Volumes
podSpec
)
两者之间的变化是if getPodTemplate returns podTemplate.
我们四处寻找。 var/function.groovy
制作共享库的方法(我不太确定每种“种类”的共享库被称为什么),我们正在导入使用“ new" 和一个 globalLibrary.
有什么想法吗?
此作业 DSL 错误似乎是在函数未编译时发生的。在这种情况下,该函数不会编译,因为 groovy 执行此操作,您可以在不带括号的情况下调用函数。
示例:
def foo(name, closure) {println name; println closure()}
可以通过以下方式调用。
foo(“asdf”,{return “asdf”})
foo “asdf” {return “asdf”}
foo(“asdf”) {return “asdf”}
带括号和不带括号
但是这样:
foo(“asdf”)
将抛出错误 MissingMethodException
因为 foo 需要 2 个参数。而我最初认为它会 return 部分。
所以当我们 return podTemplate 没有闭包作为最后一个参数时,我们实际上破坏了该方法的编译,因此我们得到一个 DSL 错误,因为共享库无法编译。
解决方案是添加一个闭包最终参数,并将其作为最后一个参数传递给 podTemplate