Home > Net >  Jenkins executes second command with sh using docker.image.withRun
Jenkins executes second command with sh using docker.image.withRun

Time:04-19

I currently have a Jenkins script which starts a Docker container in which the Selenium tests are run using Maven. The Selenium tests are executed successfully, and Maven returns "Build Success".

The problem is as following: Instead of only executing the sh command specified in the Jenkinsfile, Jenkins also executes an unknown second sh command.

Jenkins Pipeline Step

As shown in the image, the highlighted part is executed as command, which obviously is not a command, meaning that the Docker container returns error code 127.

Jenkinsfile:

node {
    stage('Checkout Code') {
        checkout scm
    }
    try {
        withEnv(["JAVA_HOME=${tool 'JDK 11.0'}", "PATH MAVEN=${tool 'apache-maven-3.x'}/bin", "PATH JAVA=${env.JAVA_HOME}/bin"]) {
            stage('Run Selenide Tests') {
                docker.image('selenium/standalone-chrome').withRun('-v /dev/shm:/dev/shm -P') { c->
                    sh "mvn clean test -Denvironment=${env.Profile} -Dselenide.headless=true -Dselenide.remote=http://"   c.port(4444)   "/wd/hub"
                }
            }
        }
    }catch(e){
        currentBuild.result = "FAILURE"
        throw e
    } finally {
        stage('Notify Slack Channel of Tests status') {
            // Hidden
        }
    }
}

Console Output (some parts hidden because not relevant):

  docker run -d -v /dev/shm:/dev/shm -P selenium/standalone-chrome
  docker port a15967ce0efbda908f6ba9bb7c8c633bb64e54a6557e5c23097ea47ed0540ff9 4444
  mvn clean test -Denvironment=jenkins -Dselenide.headless=true -Dselenide.remote=http://0.0.0.0:49827
// Maven tests
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  02:14 min
[INFO] Finished at: 2022-04-14T15:36:38 02:00
[INFO] ------------------------------------------------------------------------
  :::49821/wd/hub
/var/lib/jenkins/workspace/selenide-tests/test@tmp/durable-58ae7b8f/script.sh: 2: 
/var/lib/jenkins/workspace/selenide-tests/test@tmp/durable-58ae7b8f/script.sh: :::49821/wd/hub: not found
  docker stop a15967ce0efbda908f6ba9bb7c8c633bb64e54a6557e5c23097ea47ed0540ff9
a15967ce0efbda908f6ba9bb7c8c633bb64e54a6557e5c23097ea47ed0540ff9
  docker rm -f a15967ce0efbda908f6ba9bb7c8c633bb64e54a6557e5c23097ea47ed0540ff9
a15967ce0efbda908f6ba9bb7c8c633bb64e54a6557e5c23097ea47ed0540ff9
ERROR: script returned exit code 127
Finished: FAILURE

Is this a common issue which is easily solvable, or is something wrong with my Jenkinsfile and how can I fix this?

Thanks

CodePudding user response:

It seems the /wd/hub part comes from you executed line of code, which leads me to believe that your problem is due to the way you have added quotes. Your line of code is:

sh "mvn clean test -Denvironment=${env.Profile} -Dselenide.headless=true -Dselenide.remote=http://"   c.port(4444)   "/wd/hub"

Specifically, you open you command with ", then close it after http:// with another ". I'm guessing Jenkins doesn't find this acceptable. Try creating the url separately

def url = "http://"   c.port(4444)   "/wd/hub"

and simply using this variable in your executing line

sh "mvn clean test -Denvironment=${env.Profile} -Dselenide.headless=true -Dselenide.remote=${url}"

I haven't used docker.image before so you might have to play around a bit to get this working.

CodePudding user response:

After some more digging around the documentation and trying different stuff out, this is what worked for me:

node {
    stage('Checkout Code') {
        checkout scm
    }
    try {
        withEnv(["JAVA_HOME=${tool 'JDK 11.0'}", "PATH MAVEN=${tool 'apache-maven-3.x'}/bin", "PATH JAVA=${env.JAVA_HOME}/bin"]) {
            stage('Run Selenide Tests') {
                docker.image('selenium/standalone-chrome').withRun('-v /dev/shm:/dev/shm -p 4444:4444') { 
                    def selenideRemote = "http://0.0.0.0:4444/wd/hub"
                    sh "mvn clean test -Denvironment=${env.Profile} -Dselenide.headless=true -Dselenide.remote=${selenideRemote}
                }
            }
        }
    }catch(e){
        currentBuild.result = "FAILURE"
        throw e
    } finally {
        stage('Notify Slack Channel of Tests status') {
            // Hidden
        }
    }
}

So I replaced .withRun('-v /dev/shm:/dev/shm -P') with .withRun(-v /dev/shm:/dev/shm -p 4444:4444') and replaced c.port(4444) with the selenideRemote variable.

Removing c.port(4444) stopped executing the second command in question. Replacing -P with -p 4444:4444 prevented port 4444 from inside the container to be assigned to a random port on the host, which also prevented the usage of c.port(4444).

  • Related