João Amaro
João Amaro

Reputation: 496

How to run all stages from jenkins job on same node when using agent docker?

I have a Jenkins pipeline that runs on docker agents and everytime it enters a stage with a different agent it changes Jenkins node. How can I force it to run always on the same node?

I have 3 nodes: master, slave-1 and slave-2. My pipeline sometimes, just an example, starts by using master, then when it calls agent image-docker-1 it uses slave-1 and then when it calls agent image-docker-2 it uses master again.

How can I force it to use always slave-1? I know that, if I weren't using docker as agent, I could use something like:

node (label: "slave-1") {
(...)

pipeline {
agent { label "slave-1 }
(...)

But I think this is not the case.

Here's my pipeline:

node {
properties([
          pipelineTriggers(
              [cron('H 00 * * 1-5') ]
          )]
  )
  workloadPipeline = load("ImagePull.groovy")
  workloadPipeline
}

pipeline {
  options {
    ansiColor('xterm')
    timestamps()
  }
  agent none    
  environment {
  TOKEN = credentials("token") 
  HOME = '.'
  }    
  stages {
    stage("initiating"){
      agent {
        docker {
          image 'image-docker-1'
          args '--entrypoint="" -u root -v /var/run/docker.sock:/var/run/docker.sock'
        }
      }
      stages {
        stage('docker 1 scanning') {     
          steps {
            script {
              workloadPipeline.loopImages(Images)
            }
          }             
        }
        stage ('docker 1 test'){
         (...)
        }
      }
    }
    stage('docker 2 scanning') {
      agent {         
        docker {          
          image 'image-docker-2'
          args '--entrypoint="" -u root -v /var/run/docker.sock:/var/run/docker.sock'         
        }
      }
      steps {
        script {
            workloadPipeline.Scanning()
        }
      }
    }
  }
}

Upvotes: 0

Views: 2979

Answers (4)

cannie
cannie

Reputation: 151

found an easy solution from this example by using reuseNode true

pipeline {

agent none

stages {

    stage("Fix the permission issue") {

        agent any

        steps {
            sh "sudo chown root:jenkins /run/docker.sock"
        }

    }

    stage('Step 1') {

        agent {
            docker {
                image 'nezarfadle/tools'
                reuseNode true
            }
        }

        steps {
            sh "ls /"
        }

    }

}

}

Upvotes: 4

cannie
cannie

Reputation: 151

-The following code works for me when i have multiple nodes labeled with 'slaves' 'init' stage will pick one node from 'slaves', following stages will use the same node with env.NODE_NAME( set by the init state)

pipeline {
 agent {
  node {
  labe 'slaves'
}
stages {
  stage ('init') {  steps  {echo "node is $NODE_NAME"} }
  stage ( 'test1') {
   agent {
     docker {
       label env.NODE_NAME
       image  nginx
     }
     steps {
       echo "test done"
     }
    }
   }
 }
}

Upvotes: 0

Washwater
Washwater

Reputation: 24

Use:

agent { 
    docker {
        image 'image-docker-1'
        args '--entrypoint="" -u root -v /var/run/docker.sock:/var/run/docker.sock'
        label 'slave-1'
    }
}

Put that or at the pipeline level, for having all your stages using it, or at each stage if you want to seperate by stage

Thanks João for the small correction :)

Upvotes: 0

João Amaro
João Amaro

Reputation: 496

Thanks for the answer @Washwater. In fact I needed to make a little change.

If I use what you suggested, it returns an error "No agent type specified. Must be one of [any, docker, dockerfile, label, none]"

agent { 
    node { label "slave-1" } 
    docker {
        image 'image-docker-1'
        args '--entrypoint="" -u root -v /var/run/docker.sock:/var/run/docker.sock'
    }
}

So, the correct syntax must be:

agent { 
    docker {
        image 'image-docker-1'
        args '--entrypoint="" -u root -v /var/run/docker.sock:/var/run/docker.sock'
        label "slave-1"
    }
}

Upvotes: 0

Related Questions