Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-53804

In declarative pipeline, environment credentials causes context path error in deleteDir

    Details

    • Similar Issues:

      Description

      When using declarative pipelines, the credentials() function within an environment appears to incorrectly change the context path for the deleteDir() function when run in post. The error reads:

       
      Error when executing always post condition:
      org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing
      at org.jenkinsci.plugins.workflow.steps.StepDescriptor.checkContextAvailability(StepDescriptor.java:260)
      at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:247)
      at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:180)
      at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
      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 groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
      at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
      at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
      at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
      at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:157)
      at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
      at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:155)
      at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:155)
      at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:159)
      at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:129)
      at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
      at WorkflowScript.run(WorkflowScript:16)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.delegateAndExecute(jar:file:/opt/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:133)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.runPostConditions(jar:file:/opt/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:757)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.catchRequiredContextForNode(jar:file:/opt/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:402)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.catchRequiredContextForNode(jar:file:/opt/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:400)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.runPostConditions(jar:file:/opt/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:756)
      at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2030)
      at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2015)
      at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2056)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.runPostConditions(jar:file:/opt/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:751)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.executePostBuild(jar:file:/opt/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:728)
      at __cps.transform__(Native Method)
      at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
      at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
      at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixName(FunctionCallBlock.java:77)
      at sun.reflect.GeneratedMethodAccessor165.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:129)
      at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:268)
      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 jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)
      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)
      ...

      When a global credential "test" is created and this simple pipeline is executed.

       

      pipeline { 
          agent any 
          environment { 
              FOO = "bar" 
              CAUSES_ERROR = credentials("test") 
          } 
          stages { 
              stage('No-op') { 
                  steps { 
                      sh 'ls' 
                  } 
              } 
          } 
          post { 
              always { 
                  echo 'One way or another, I have finished' 
                  deleteDir() /* clean up our workspace */ 
              } 
          } 

        Attachments

          Issue Links

            Activity

            Hide
            dnusbaum Devin Nusbaum added a comment -

            I think what is happening here is that the credentials function is failing (maybe the id is invalid), but the post step still runs even though no agent has been allocated, so you see a MissingContextVariableException. Do you see a different error at the very end of the build log? When I run your pipeline I get the following error after the MissingContextVariableException:

            org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException: test
            	at org.jenkinsci.plugins.pipeline.modeldefinition.model.CredentialsBindingHandler.forId(CredentialsBindingHandler.java:107)
            	at org.jenkinsci.plugins.pipeline.modeldefinition.model.CredentialsBindingHandler$forId.call(Unknown Source)
            	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
            	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
            	at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
                    ...
            

            CC Andrew Bayer: I'm not sure if we could do anything to make this a little more ergonomic for users. Maybe something like a try/catch around post conditions internally that adds any exceptions thrown during the post condition as a suppressed exception on the original exception to make it clear what the original issue was?

            Show
            dnusbaum Devin Nusbaum added a comment - I think what is happening here is that the credentials function is failing (maybe the id is invalid), but the post step still runs even though no agent has been allocated, so you see a MissingContextVariableException. Do you see a different error at the very end of the build log? When I run your pipeline I get the following error after the MissingContextVariableException: org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException: test at org.jenkinsci.plugins.pipeline.modeldefinition.model.CredentialsBindingHandler.forId(CredentialsBindingHandler.java:107) at org.jenkinsci.plugins.pipeline.modeldefinition.model.CredentialsBindingHandler$forId.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20) ... CC Andrew Bayer : I'm not sure if we could do anything to make this a little more ergonomic for users. Maybe something like a try/catch around post conditions internally that adds any exceptions thrown during the post condition as a suppressed exception on the original exception to make it clear what the original issue was?
            Hide
            abayer Andrew Bayer added a comment -

            Interesting - I think I can probably do something to make this a better experience. Lemme think on it.

            Show
            abayer Andrew Bayer added a comment - Interesting - I think I can probably do something to make this a better experience. Lemme think on it.
            Hide
            abayer Andrew Bayer added a comment -

            Ok, I've got a path for making this cleaner, but along the way, I've discovered that if you use a non-existent credential ID in environment in a stage, that stage's post never gets called at all. Trying to figure out how I want to handle that.

            Show
            abayer Andrew Bayer added a comment - Ok, I've got a path for making this cleaner, but along the way, I've discovered that if you use a non-existent credential ID in environment in a stage , that stage 's post never gets called at all. Trying to figure out how I want to handle that.
            Hide
            abayer Andrew Bayer added a comment -

            Ok, got a PR up at https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/291 that handles both top-level and per-stage post conditions being executed earlier (i.e., after we hit the credentials error and before we leave the agent in the example in the issue description), as well as cleans up directive-error-condition post execution for a stage to actually, y'know, execute.

            Show
            abayer Andrew Bayer added a comment - Ok, got a PR up at https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/291  that handles both top-level and per-stage post conditions being executed earlier (i.e., after we hit the credentials error and before we leave the agent in the example in the issue description), as well as cleans up directive-error-condition post execution for a stage to actually, y'know, execute.

              People

              • Assignee:
                Unassigned
                Reporter:
                jay_sen Jay Sen
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated: