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

Declarative pipeline: post section doesn't play nice with agent none

      Hi, so using the declarative pipeline it appears if you have agent none set at the top of the pipeline and agents defined per stage, you are unable to have a post section that executes certain steps (that require a node context). The following will result in an error::

      pipeline {
          agent none
          stages {
              stage('Example') {
                  steps {
                      echo 'Hello World'
                  }
              }
          }
          post { 
              always { 
                  deleteDir()
              }
          }
      }
      
      Required context class hudson.FilePath is missing
      Perhaps you forgot to surround the code with a step that provides this, such as: node
      
      ERROR: Attempted to execute a step that requires a node context while agent none was specified. Be sure to specify your own node { ... } blocks when using agent none.

      I'm guessing its expected behavior but would it be possible to associate an agent with the post section as we do with stages?

      Thanks, David

       

          [JENKINS-43578] Declarative pipeline: post section doesn't play nice with agent none

          Andrew Bayer added a comment -

          So post is associated with an agent, sort of - post in a stage will run on whatever agent the steps for the stage are run on, while post at the top-level will run on whatever agent is defined at the top level. That obviously is thrown off by top-level agent none, but I think it's the right way to do this. If you've got something that needs to run on a specific agent, chances are you've got a stage on that agent, so add the post to that stage maybe?

          Andrew Bayer added a comment - So post is associated with an agent , sort of - post in a stage will run on whatever agent the steps for the stage are run on, while post at the top-level will run on whatever agent is defined at the top level. That obviously is thrown off by top-level agent none , but I think it's the right way to do this. If you've got something that needs to run on a specific agent , chances are you've got a stage on that agent , so add the post to that stage maybe?

          Per Östman added a comment -

          abayer What about the case when you have parallel steps in a stage?

          In that case, one is not allowed to have an agent statement at the top, and if I e g have a writeFile statement in a post statement for the entire stage, it fails with this message.

          Example (only the parallel stage):

           

          stage('FuBar') {
            parallel {
              stage('stage1') {
                agent { label 'agent1' }
                steps {
                  echo "In stage1"
                }
                post {
                  always {
                    echo "Post: Always - stage1"
                  }
                }
              }
              stage('stage2') {
                agent { label 'agent2' }
                steps {
                  echo "In stage2"
                }
                post {
                  always {
                    echo "Post: Always: - stage2"
                  }
                }
              }
            }
            post {
              always {
                echo "Post: Always - Parallel"
                writeFile file: 'FOO.txt', text: "Foo"
              }
            }
          }

          In this case, the last post statemnt won't work...

           

          Per Östman added a comment - abayer What about the case when you have parallel steps in a stage? In that case, one is not allowed to have an agent statement at the top, and if I e g have a writeFile statement in a post statement for the entire stage, it fails with this message. Example (only the parallel stage):   stage('FuBar') { parallel { stage('stage1') { agent { label 'agent1' } steps { echo "In stage1" } post { always { echo "Post: Always - stage1" } } } stage('stage2') { agent { label 'agent2' } steps { echo "In stage2" } post { always { echo "Post: Always: - stage2" } } } } post { always { echo "Post: Always - Parallel" writeFile file: 'FOO.txt', text: "Foo" } } } In this case, the last post statemnt won't work...  

          "so add the post to that stage maybe?"

          And what if parallel stage failed with:
          Stage 'Test build' skipped due to earlier failure(s)
          And your post is in the Test build stage?

          If i have 6 parallel stages should i add 6 posts to handle this?

          Filip Stefanov added a comment - "so add the post to that stage maybe?" And what if parallel stage failed with: Stage 'Test build' skipped due to earlier failure(s) And your post is in the Test build stage? If i have 6 parallel stages should i add 6 posts to handle this?

          Kevin Fox added a comment -

          Has there been a solution for this found yet? I want to run agent none so I can run different docker containers per test. But I want to have a post always job that runs in a kubernetes client docker image that cleans out the cluster of anything created by any of the stages. I haven't been able to figure out a way to do this.

          Kevin Fox added a comment - Has there been a solution for this found yet? I want to run agent none so I can run different docker containers per test. But I want to have a post always job that runs in a kubernetes client docker image that cleans out the cluster of anything created by any of the stages. I haven't been able to figure out a way to do this.

          Sean Talts added a comment -

          Kevin,
           
          The `node` function appears to work in the `post` section, so this is what we do for now: https://github.com/stan-dev/math/blob/18755752b563221cadeb39d4ce092c4c226e26ae/Jenkinsfile#L252
           

          Sean Talts added a comment - Kevin,   The `node` function appears to work in the `post` section, so this is what we do for now:  https://github.com/stan-dev/math/blob/18755752b563221cadeb39d4ce092c4c226e26ae/Jenkinsfile#L252  

          Kevin Fox added a comment -

          Interesting. How do you specify an agent section so that you can run it within a container on the node?

          Kevin Fox added a comment - Interesting. How do you specify an agent section so that you can run it within a container on the node?

          Sean Talts added a comment - - edited

          Maybe the scripted pipeline version would work, something like

           
          node {
              /* Requires the Docker Pipeline plugin to be installed */
              docker.image('node:7-alpine').inside {
                  stage('Test') {
                      sh 'node --version'
                  }
              }
          }

           
          from pressing "Toggle scripted pipeline (Advanced)" on this page: https://jenkins.io/doc/book/pipeline/docker/

          Sean Talts added a comment - - edited Maybe the scripted pipeline version would work, something like   node { /* Requires the Docker Pipeline plugin to be installed */ docker.image( 'node:7-alpine' ).inside { stage( 'Test' ) { sh 'node --version' } } }   from pressing "Toggle scripted pipeline (Advanced)" on this page:  https://jenkins.io/doc/book/pipeline/docker/

          Kevin Fox added a comment -

          tried with step and without. something like:

          post {
          always {
          node('docker') {
          docker.image("kfox1111/kubeclient:2018-08-29-1").inside {
          sh 'ls /'

           

          WorkflowScript: 62: Expected a symbol @ line 62, column 17.
          docker.image("kfox1111/kubeclient:2018-08-29-1").inside {

          Not liking something there.

           

          Kevin Fox added a comment - tried with step and without. something like: post { always { node('docker') { docker.image("kfox1111/kubeclient:2018-08-29-1").inside { sh 'ls /'   WorkflowScript: 62: Expected a symbol @ line 62, column 17. docker.image("kfox1111/kubeclient:2018-08-29-1").inside { Not liking something there.  

          Kevin Fox added a comment -

          This looks like it does the trick:

          post {
          always {
          node('docker') {
          script {
          docker.image("kfox1111/kubeclient:2018-08-29-1").inside {

          Kevin Fox added a comment - This looks like it does the trick: post { always { node('docker') { script { docker.image("kfox1111/kubeclient:2018-08-29-1").inside {

          Liam Newman added a comment -

          Bulk closing resolved issues.

          Liam Newman added a comment - Bulk closing resolved issues.

            abayer Andrew Bayer
            davidshepard77 david shepard
            Votes:
            0 Vote for this issue
            Watchers:
            10 Start watching this issue

              Created:
              Updated:
              Resolved: