代码之家  ›  专栏  ›  技术社区  ›  Christian Bongiorno

Jenkins文件在Jenkins上返回布尔值,但在实际groovy中返回ArrayList。为什么?

  •  3
  • Christian Bongiorno  · 技术社区  · 6 年前

    所以,我在一个 Jenkinsfile 还有 takeWhile 函数在jenkins中运行时返回布尔值,但返回列表(如预期!)在实际的groovy执行中。整个脚本在局部运行以得出结论,但在jenkins中失败,因为我使用了 花些时间 作为一个 List 尽管詹金斯的版本是 Boolean

    我的同事推断插件安全管理器正在干预。这是我唯一能想象的。

    本地groovy版本:

    $ groovy -version
    Groovy Version: 2.4.14 JVM: 1.8.0_131 Vendor: Oracle Corporation OS: Mac OS X
    

    詹金斯版本:

    Jenkins ver. 2.107.3
    

    代码:

    #!/usr/bin/env groovy
    
    try {
        def deployTo = [
                'pre' : ['us-east-1'],
                'int' : ['us-east-1'],
                's1'  : ['ca-central-1', 'us-east-1'],
                'demo': ['us-east-1'],
        ].collectMany { k, v -> v.collect { r -> [k, r] } }
    
        def failure = deployTo.findResult { entry ->
            def result = 0
            stage("Deploying to:\n${entry[0]}\n(${entry[1]})") {
                println("stage deploy")
    
            }
            return new Random().nextBoolean() ? entry : null
        }
        println("deployto is a : ${deployTo.class}")
        println("deploy to: ${deployTo}")
        def takeWhile = deployTo.takeWhile { it != failure }
        println("takeWhile is a : ${takeWhile.class}")
        println("takeWhile to: ${takeWhile}")
        takeWhile.each { toRollback ->
            println("torollback is a ${toRollback.class}")
            stage("Rolling back to:\n${toRollback[0]}\n(${toRollback[1]})") {
                println("stage rollback")
            }
        }
    } catch (e) {
        println(e.getStackTrace().join('\n'))
        println(e.class)
        println(e.message)
        throw e
    }
    

    本地groovy输出:

    Deploying to:
    pre
    (us-east-1)
    stage deploy
    Deploying to:
    int
    (us-east-1)
    stage deploy
    deployto is a : class java.util.ArrayList
    deploy to: [[pre, us-east-1], [int, us-east-1], [s1, ca-central-1], [s1, us-east-1], [demo, us-east-1]]
    takeWhile is a : class java.util.ArrayList
    takeWhile to: [[pre, us-east-1]]
    torollback is a class java.util.ArrayList
    Rolling back to:
    pre
    (us-east-1)
    stage rollback
    

    詹金斯输出:

    Running in Durability level: MAX_SURVIVABILITY
    [Pipeline] stage
    [Pipeline] { (Deploying to:
    pre
    (us-east-1))
    [Pipeline] echo
    stage deploy
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] echo
    deployto is a : class java.util.ArrayList
    [Pipeline] echo
    deploy to: [[pre, us-east-1], [int, us-east-1], [s1, ca-central-1], [s1, us-east-1], [demo, us-east-1]]
    [Pipeline] echo
    takeWhile is a : class java.lang.Boolean
    [Pipeline] echo
    takeWhile to: false
    No such getAt method found: method java.lang.Boolean[java.lang.Integer]. Administrators can decide whether to approve or reject this signature.
    [Pipeline] echo
    torollback is a class java.lang.Boolean
    [Pipeline] echo
    org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetArray(SandboxInterceptor.java:451)
    org.kohsuke.groovy.sandbox.impl.Checker$10.call(Checker.java:419)
    org.kohsuke.groovy.sandbox.impl.Checker.checkedGetArray(Checker.java:424)
    com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getArray(SandboxInvoker.java:45)
    com.cloudbees.groovy.cps.impl.ArrayAccessBlock.rawGet(ArrayAccessBlock.java:21)
    WorkflowScript.run(WorkflowScript:29)
    com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2030)
    com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:1890)
    WorkflowScript.run(WorkflowScript:27)
    ___cps.transform___(Native Method)
    com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74)
    com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
    com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
    sun.reflect.GeneratedMethodAccessor703.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
    com.cloudbees.groovy.cps.Next.step(Next.java:83)
    com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
    com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
    org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
    org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
    com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
    org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$101(SandboxContinuable.java:34)
    org.jenkinsci.plugins.workflow.cps.SandboxContinuable.lambda$run0$0(SandboxContinuable.java:59)
    org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
    org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:58)
    org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174)
    org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332)
    org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83)
    org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244)
    org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232)
    org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
    java.util.concurrent.FutureTask.run(FutureTask.java:266)
    hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131)
    jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
    java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    java.util.concurrent.FutureTask.run(FutureTask.java:266)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    java.lang.Thread.run(Thread.java:748)
    [Pipeline] echo
    class org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException
    [Pipeline] echo
    No such getAt method found: method java.lang.Boolean[java.lang.Integer]
    [Pipeline] End of Pipeline
    org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such getAt method found: method java.lang.Boolean[java.lang.Integer]
        at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetArray(SandboxInterceptor.java:451)
        at org.kohsuke.groovy.sandbox.impl.Checker$10.call(Checker.java:419)
        at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetArray(Checker.java:424)
        at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getArray(SandboxInvoker.java:45)
        at com.cloudbees.groovy.cps.impl.ArrayAccessBlock.rawGet(ArrayAccessBlock.java:21)
        at WorkflowScript.run(WorkflowScript:29)
        at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2030)
        at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:1890)
        at WorkflowScript.run(WorkflowScript:27)
        at ___cps.transform___(Native Method)
        at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74)
        at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
        at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
        at sun.reflect.GeneratedMethodAccessor703.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
        at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
        at com.cloudbees.groovy.cps.Next.step(Next.java:83)
        at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
        at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
        at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
        at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
        at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
        at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$101(SandboxContinuable.java:34)
        at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.lambda$run0$0(SandboxContinuable.java:59)
        at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
        at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:58)
        at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174)
        at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332)
        at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83)
        at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244)
        at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232)
        at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131)
        at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
    Finished: FAILURE
    
    1 回复  |  直到 6 年前
        1
  •  4
  •   mkobit    6 年前

    这类似于我提交的一个问题( JENKINS-49826 ).这是詹金斯管道中的CPS编译问题。我会针对 workflow-cps-plugin 因为这绝对不是故意的行为。

    同时,我会把你的 takeWhile 打电话给 @NonCPS 注释方法,并将所有内容作为参数传入。看见 this question and answer for some information on @NonCPS .

    下面是一个简化为小型复制机的示例,以及一种将逻辑转换为 @非现金 :

    final deployTo = [
      'pre' : ['us-east-1'],
      'int' : ['us-east-1'],
      's1'  : ['ca-central-1', 'us-east-1'],
      'demo': ['us-east-1'],
    ].collectMany { k, v -> v.collect { r -> [k, r] } }
    final failure = [pre: 'us-east-1']
    
    echo "${deployTo}"
    echo "${deployTo.getClass()}"
    
    def takeWhile = deployTo.takeWhile { it != failure }
    println("takeWhile is a : ${takeWhile.class}")
    println("takeWhile to: ${takeWhile}")
    
    def nonCpsUsage = nonCpsTakeWhile(deployTo, failure)
    println("nonCpsTakeWhile is a : ${nonCpsUsage.class}")
    println("nonCpsTakeWhile to: ${nonCpsUsage}")
    
    @NonCPS
    def nonCpsTakeWhile(final d, final f) {
      return d.takeWhile { it != f }
    }
    

    以及输出:

    Started
    Running in Durability level: MAX_SURVIVABILITY
    [Pipeline] echo
    [[pre, us-east-1], [int, us-east-1], [s1, ca-central-1], [s1, us-east-1], [demo, us-east-1]]
    [Pipeline] echo
    class java.util.ArrayList
    [Pipeline] echo
    takeWhile is a : class java.lang.Boolean
    [Pipeline] echo
    takeWhile to: true
    [Pipeline] echo
    nonCpsTakeWhile is a : class java.util.ArrayList
    [Pipeline] echo
    nonCpsTakeWhile to: [[pre, us-east-1], [int, us-east-1], [s1, ca-central-1], [s1, us-east-1], [demo, us-east-1]]
    [Pipeline] End of Pipeline
    Finished: SUCCESS
    

    请注意,返回的类型来自不同的类型 @非现金 java.util.ArrayList 与…相比 java.lang.Boolean .