dockerjenkins-pipelineaccurev

Executing Jenkins Pipeline on a single agent with docker


What I'm trying to achieve:

I'm trying to execute a pipeline script where SCM (AccuRev) is checked out on 'any' agent and then the stages are executed on that same agent per the local workspace. The build stage specifically is expecting the code checkout to just be available in the workspace that is mapped into the container.

The problem:

When I have more than one agent added to the Jenkins configuration, the SCM step will checkout the code on one agent and then start the build step starting the container on the other agent, which is a problem because the code was checked out on the other agent.

What works:

pipeline {
   agent none    
   stages {
      stage('Checkout') {
         agent any
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

What I have tried, but doesn't work:

pipeline {
   agent {
      docker {
         image 'ubuntu'
      }
   }
   stages {
      stage('Checkout') {
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

The above doesn't work because it is expecting AccuRev to be installed in the container. I could go this route, but it is not really scalable and will cause issues on containers that are based on an older OS. There are also permission issues within the container.

I also tried adding 'reuseNode true' to the docker agent, as in the below:

pipeline {
   agent none    
   stages {
      stage('Checkout') {
         agent any
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
               reuseNode true
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

I'm somewhat aware or have read about 'automatic checkout scm' as with the following, but this is odd as there is no place to define the target stream/branch to checkout. This is why I'm declaring a specific stage to handle scm checkout. It is possible this would handle the checkout without needing to specify the agent, but I don't get how to do this.

pipeline {
    agent any
    stages {
        stage ('Build') {
            steps {
                sh 'cat Jenkinsfile'
            }
        }
    }
}

Edit: adding a solution that seems to work, but need more testing before confirming.

The following seems to do what I want, executing the checkout stage on 'any' agent and then reusing the same agent to execute the build state in a container.

pipeline {
   agent any    
   stages {
      stage('Checkout') {
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
               reuseNode true
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

Solution

  • The below appears to have given me the functionality that I needed. The pipeline starts on "any" agent allowing the host level to handle the Checkout stage, and the "reuseNode" informs the pipeline to start the container on the same node, where the workspace is located.

    pipeline {
       agent any    
       stages {
          stage('Checkout') {
             steps {
                checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
             }
          }
          stage('Compile') {
             agent {
                docker {
                   image 'ubuntu'
                   reuseNode true
                }
             }
             steps {
                sh '''#!/bin/bash
                      make -j16
                '''
             }
          }
       }
    }