由于缺少 Slack baseUrl,Jenkins JobDSL 种子作业突然失败

Jenkins JobDSL seed jobs failing suddenly due to lack of Slack baseUrl

我是 运行 Jenkins 2.155,在 Ubuntu 16.04 上,使用 docker。

我有大约 20 个 Jenkins JobDSL 种子工作,这些工作已经 运行 几年没有问题了。

大约三天前,这些都失败了。我最终将问题缩小到缺少 Slack baseUrl 参数。

最初失败输出是不同的,但后来我们尝试更新 Jenkins 以及所有插件,因为无论如何这是到期的,并且错误发生了变化。但无论如何,我们在初始错误之前没有进行任何更改。

这是 DSL 脚本中的代码示例,尽管有许多类似的代码已经开始失败。

    /**
     * Job Config
     * Each job should provide
     *    id - unique id of the job
     *    serverName - The Jenkins name of the server which needs to be connected snapshotted

    **/
    def webservers = [
        [id: 'server1-automated-snapshot', serverName: 'Server 1'],
        [id: 'server2-automated-snapshot', serverName: 'Server 2'],
        [id: 'server3', serverName: 'Server 3'],
        [id: 'server 4', serverName: 'Server 4'],
    ]

    /**
     * Job Template
     *     The job template for automated snapshot jobs. Changing this will update all the snapshot jobs.
     */
    for(webserver in webservers) {
        def jobName = webserver.id
        jobDisplayName = webserver.serverName+' automated volume snapshot'
        def jobDescription = """This job automatically runs the automated snapshot script located on the $webserver.serverName once a day."""
        job(jobName) {
            description(jobDescription)
            displayName(jobDisplayName)
            logRotator {
                numToKeep(5)
            }
            configure {
                it / 'properties' << 'hudson.plugins.disk__usage.DiskUsageProperty' {}
            }
            wrappers {
                timestamps()
            }
            triggers {
                cron('H 2 * * 1')
            }
            steps {
                publishOverSsh {
                    server(webserver.serverName) {
                        transferSet {
                            execCommand('sudo /usr/local/sbin/snapshot.sh')
                        }
                    }
                }
            }
            publishers {
                mailer('techadmin@ibboost.com', true, false)
                retryBuild {
                    rerunIfUnstable()
                    retryLimit(1)
                    fixedDelay(600)
                }
                slackNotifier {
                    room('#channel')
                    notifyAborted(true)
                    notifyFailure(true)
                    notifyNotBuilt(false)
                    notifyBackToNormal(true)
                    notifySuccess(false)
                    notifyRepeatedFailure(false)
                    notifyUnstable(true)
                    startNotification(false)
                    includeTestSummary(false)
                    includeCustomMessage(false)
                    customMessage(null)
                    sendAs(null)
                    commitInfoChoice('NONE')
                    teamDomain(null)
                    authToken(null)
                }
                wsCleanup {
                    cleanWhenAborted(true)
                    cleanWhenNotBuilt(true)
                    cleanWhenFailure(true)
                    cleanWhenSuccess(true)
                    cleanWhenUnstable(true)
                }
            }
       }
}

最初的错误是这样的(使用 Jenkins 2.140 时):

[EnvInject] - Loading node environment variables.
Building remotely on master-host (docker master) in workspace /home/jenkins/master-host/workspace/seed-job
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url https://github.com/myrepo # timeout=10
Fetching upstream changes from https://github.com/myrepo/jenkins-config
 > git --version # timeout=10
using GIT_ASKPASS to set credentials Github
 > git fetch --tags --progress https://github.com/myrepo/jenkins-config +refs/heads/*:refs/remotes/origin/*
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision ceb7869d4c6f3c68966e2078afc238bc179cf485 (refs/remotes/origin/master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f ceb7869d4c6f3c68966e2078afc238bc179cf485
Commit message: "Appending seperator to workspace path to fix groovy.util.ResourceException"
 > git rev-list --no-walk c584afcbfed911d5b965208d78ee04504ffd5ea5 # timeout=10
Processing DSL script jobBuilder.groovy
Processing DSL script jobBuilder.groovy
Processing DSL script jobBuilder.groovy
Processing DSL script jobBuilder.groovy
Processing DSL script jobBuilder.groovy
FATAL: Unable to run script
groovy.util.ResourceException: Cannot open URL: file:/home/jenkins/master-host/workspace/seed-job/jenkins.mydomain.com/config/global_config.groovy
    at groovy.util.GroovyScriptEngine.getResourceConnection(GroovyScriptEngine.java:414)
    at groovy.util.GroovyScriptEngine.loadScriptByName(GroovyScriptEngine.java:558)
    at sun.reflect.GeneratedMethodAccessor3616.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
    at jobBuilder$_run_closure1.doCall(jobBuilder.groovy:4)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at groovy.lang.Closure.call(Closure.java:414)
    at groovy.lang.Closure.call(Closure.java:430)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.with(DefaultGroovyMethods.java:242)
    at org.codehaus.groovy.runtime.dgm7.invoke(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:274)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at jobBuilder.run(jobBuilder.groovy:3)
    at jobBuilder$run.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at jobBuilder$run.call(Unknown Source)
    at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScript(AbstractDslScriptLoader.groovy:132)
    at sun.reflect.GeneratedMethodAccessor3088.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:64)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
    at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScriptEngine(AbstractDslScriptLoader.groovy:106)
Caused: java.io.IOException: Unable to run script
    at sun.reflect.GeneratedConstructorAccessor711.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
    at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:255)
    at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScriptEngine(AbstractDslScriptLoader.groovy:114)
    at sun.reflect.GeneratedMethodAccessor3077.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:174)
    at javaposse.jobdsl.dsl.AbstractDslScriptLoader$_runScripts_closure1.doCall(AbstractDslScriptLoader.groovy:59)
    at sun.reflect.GeneratedMethodAccessor3074.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at groovy.lang.Closure.call(Closure.java:414)
    at groovy.lang.Closure.call(Closure.java:430)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2040)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2025)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2078)
    at org.codehaus.groovy.runtime.dgm4.invoke(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:274)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScripts(AbstractDslScriptLoader.groovy:46)
    at javaposse.jobdsl.plugin.ExecuteDslScripts.perform(ExecuteDslScripts.java:341)
    at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:81)
    at hudson.tasks.BuildStepMonitor.perform(BuildStepMonitor.java:20)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:744)
    at hudson.model.Build$BuildExecution.build(Build.java:206)
    at hudson.model.Build$BuildExecution.doRun(Build.java:163)
    at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:504)
    at hudson.model.Run.execute(Run.java:1815)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:97)
    at hudson.model.Executor.run(Executor.java:429)
[BFA] Scanning build for known causes...
[BFA] No failure causes found
[BFA] Done. 0s
Started calculate disk usage of build
Finished Calculation of disk usage of build in 0 seconds
Started calculate disk usage of workspace
Finished Calculation of disk usage of workspace in 0 seconds
Finished: FAILURE

然后在更新 Jenkins 和插件后更改为:

[EnvInject] - Loading node environment variables.
Building on master in workspace /var/jenkins_home/workspace/seed-job
Cloning the remote Git repository
Cloning repository https://github.com/myrepo/jenkins-config
 > git init /var/jenkins_home/workspace/seed-job # timeout=10
Fetching upstream changes from https://github.com/myrepo/jenkins-config
 > git --version # timeout=10
using GIT_ASKPASS to set credentials Github
 > git fetch --tags --progress https://github.com/myrepo/jenkins-config +refs/heads/*:refs/remotes/origin/*
 > git config remote.origin.url https://github.com/myrepo/jenkins-config # timeout=10
 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git config remote.origin.url https://github.com/myrepo/jenkins-config # timeout=10
Fetching upstream changes from https://github.com/myrepo/jenkins-config
using GIT_ASKPASS to set credentials Github
 > git fetch --tags --progress https://github.com/myrepo/jenkins-config +refs/heads/*:refs/remotes/origin/*
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision asdasdf3c68966e2078afcgth6579cf485 (refs/remotes/origin/master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f asdasdf3c68966e2078afcgth6579cf485
Commit message: "Appending seperator to workspace path to fix groovy.util.ResourceException"
 > git rev-list --no-walk asdasdf3c68966e2078afcgth6579cf485 # timeout=10
Processing DSL script jobBuilder.groovy
ERROR: (jobBuilder.groovy, line 67) the following options are required and must be specified: baseUrl
[BFA] Scanning build for known causes...
[BFA] No failure causes found
[BFA] Done. 0s
Started calculate disk usage of build
Finished Calculation of disk usage of build in 0 seconds
Started calculate disk usage of workspace
Finished Calculation of disk usage of workspace in 0 seconds
Finished: FAILURE

因此,从逻辑上讲,这表明我们需要将 baseUrl 添加到 DSL 脚本中。但是有人知道为什么吗?而且,有谁知道为什么这突然改变而我们没有改变任何东西?

编辑

我在脚本中添加了以下参数(在 slackNotifier 下),这解决了这个问题;但它仍然没有回答问题。

baseUrl(null)

这是 Jenkins 插件“Slack Notifier”v2.2 中引入的新参数。

https://github.com/jenkinsci/slack-plugin/blob/master/CHANGELOG.md#22-release-notes

Slack 插件 v2.4 中的这个提交打破了与 Job DSL 脚本的兼容性,使很多选项成为强制性的(再次):

https://github.com/jenkinsci/slack-plugin/commit/4015f8388c4fbb54acda42e41bd4b8e52afe1e17#diff-f2606fe35028acac90e7e466dc4f5d4c

兼容性已在 v2.11 中恢复:

https://github.com/jenkinsci/slack-plugin/commit/129db5947201ca1730c02d7c42e5f7c6b352868a#diff-f2606fe35028acac90e7e466dc4f5d4c