1

We've a containerized Jenkins pipeline and for one of the stages, some part of stage, we want to be executed on container and some on Jenkins master(which is Windows in our case) -

pipeline {
    agent {
        docker {
            label "<node-name>"
            image "<docker-image-path>"
        }
    }
    stages {
        stage('Testing') {
            steps {
                script {
                    //This below part will be executed on container
                    println "This below part will be executed on container"
                    sh '''pwd
                        hostname -i     
                    '''

                    // Now want to execute below code on master which is Windows
                    println "Now want to execute below code on master which is Windows"
                    node('master') {
                        bat 'dir'
                    }
                }
            }
        }
    }
}

Part to be executed on container is executed successfully but code to execute on Windows Jenkins master fails with -

Cannot run program "docker" (in directory "C:\Jenkins\workspace\TestDocker"): CreateProcess error=2, The system cannot find the file specified

EDIT

And when I've docker installed on Windows machine, above error is not thrown but stucks there forever.

Could you please help me how I can execute code on node or container on demand?

Alpha
  • 13,320
  • 27
  • 96
  • 163
  • Your top level agent is defined as docker. Is this intentional? When using multiple agents, AFAIK you need to define top level agent as 'none' or Jenkins will still try to use docker agent on Windows master. There are multiple possibilities. A clean solution would be to create stages for each corresponding agent, like "Test on Docker", "Test on Windows" and define agent on stage level. – nulldroid Nov 01 '21 at 11:28
  • Yes top level agent is intentional. For problem explanation, I used simple example here. But top level agent defined is needed to mount some locations and set custom arguments, throughout all the stages of pipeline except part of one stage. – Alpha Nov 01 '21 at 13:02
  • I see. However, it seems the node override doesn't work properly. Usually you would wrap the execution inside a node('target') instead of inside the "script" block. `stage("Testing") { node('linux') { sh "make" } node('windows') { bat "dir" } }` – nulldroid Nov 01 '21 at 15:09
  • Related: https://stackoverflow.com/questions/57631440/how-do-i-run-all-jenkins-pipeline-steps-except-one-in-a-docker-container – jjmontes Jul 29 '22 at 10:57

1 Answers1

1

I have the same issue and the best what I could figure out so far to run it in a different stage. I know it's against the original question, but may help some people. It also makes the pipeline quite big and complicated.

pipeline {
    agent { label 'whatever' }

    stages {
        stage('Something directly on the node') {
            steps {
                sh '''
                    echo "I am running outside docker!"
                '''
            }
         }


        stage('Something in the container') {
            agent {
                docker {
                    image 'mycontainer:1.0.0'
                    reuseNode true
                }
            }
            steps {

                sh '''
                    echo "We are inside a docker container now!"
                '''
            }
         }
    }
}

The reuseNode option is important (jenkins doc):

When reuseNode set to true: no new workspace will be created, and current workspace from current agent will be mounted into container, and container will be started at the same node, so whole data will be synchronized.

ps: this pipeline has only 2 stages, but of course you can have as many you need, running in and out of the container again and again.

redseven
  • 849
  • 6
  • 11