-
Bug
-
Resolution: Unresolved
-
Minor
-
None
-
Jenkins 2.133
Pipeline 2.5
Pipeline: Basic Steps 2.9
Pipeline: Groovy 2.54
Pipeline: Stage Step 2.3
Docker Pipeline 1.17
Consider the following pipeline used in a Go project:
node { def goPackage = 'myrepo.com/myproject' def goPath = "${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}" // Jenkins binds WORKSPACE:WORKSPACE (host:container) when executing steps inside a Docker container, therefore the workspace path must be GOPATH-compatible. ws("${goPath}/src/${goPackage}") { withEnv(["GOPATH=${goPath}", 'GOCACHE=/tmp/.gocache']) { stage('Checkout'){ checkout(scm) } // Default GOPATH is owned by root, so we mount our custom GOPATH from the host. docker.image('golang:1.10').inside('-v $GOPATH:$GOPATH -e PATH=$GOPATH/bin:/usr/local/go/bin:/usr/sbin:/usr/bin:/sbin:/bin') { stage('Static checks'){ // places 'golint' inside $GOPATH/bin sh 'go get -u golang.org/x/lint/golint' sh 'golint ./...' sh 'golint ./... | grep -v "some text"' } } } } }
While the first call to golint works, the second one fails with:
/bin/sh: 1: golint: not found
I can reproduce the behaviour in any subshell (regular parenthesis, command substitution, pipe). The only way around it is to use the full path to the executable.
[JENKINS-52640] executable not found in subshells
Description |
Original:
Consider the following pipeline used in a Go project: {code:groovy} node { def goPackage = 'stash.hybris.com/model-t/ingress-apache2' def goPath = "${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}" // Jenkins binds WORKSPACE:WORKSPACE (host:container) when executing steps inside a Docker container, therefore the workspace path must be GOPATH-compatible. ws("${goPath}/src/${goPackage}") { withEnv(["GOPATH=${goPath}", 'GOCACHE=/tmp/.gocache']) { stage('Checkout'){ checkout(scm) } // Default GOPATH is owned by root, so we mount our custom GOPATH from the host. docker.image('golang:1.10').inside('-v $GOPATH:$GOPATH -e PATH=$GOPATH/bin:/usr/local/go/bin:/usr/sbin:/usr/bin:/sbin:/bin') { stage('Static checks'){ // places 'golint' inside $GOPATH/bin sh 'go get -u golang.org/x/lint/golint' sh 'golint ./...' sh 'golint ./... | grep -v "some text"' } } } } } {code} While the first call to {{golint}} works, the second one fails with: {code} /bin/sh: 1: golint: not found {code} I can reproduce the behaviour in any subshell (regular parenthesis, command substitution, pipe). |
New:
Consider the following pipeline used in a Go project: {code:groovy} node { def goPackage = 'myrepo.com/myproject' def goPath = "${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}" // Jenkins binds WORKSPACE:WORKSPACE (host:container) when executing steps inside a Docker container, therefore the workspace path must be GOPATH-compatible. ws("${goPath}/src/${goPackage}") { withEnv(["GOPATH=${goPath}", 'GOCACHE=/tmp/.gocache']) { stage('Checkout'){ checkout(scm) } // Default GOPATH is owned by root, so we mount our custom GOPATH from the host. docker.image('golang:1.10').inside('-v $GOPATH:$GOPATH -e PATH=$GOPATH/bin:/usr/local/go/bin:/usr/sbin:/usr/bin:/sbin:/bin') { stage('Static checks'){ // places 'golint' inside $GOPATH/bin sh 'go get -u golang.org/x/lint/golint' sh 'golint ./...' sh 'golint ./... | grep -v "some text"' } } } } } {code} While the first call to {{golint}} works, the second one fails with: {code} /bin/sh: 1: golint: not found {code} I can reproduce the behaviour in any subshell (regular parenthesis, command substitution, pipe). |
Description |
Original:
Consider the following pipeline used in a Go project: {code:groovy} node { def goPackage = 'myrepo.com/myproject' def goPath = "${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}" // Jenkins binds WORKSPACE:WORKSPACE (host:container) when executing steps inside a Docker container, therefore the workspace path must be GOPATH-compatible. ws("${goPath}/src/${goPackage}") { withEnv(["GOPATH=${goPath}", 'GOCACHE=/tmp/.gocache']) { stage('Checkout'){ checkout(scm) } // Default GOPATH is owned by root, so we mount our custom GOPATH from the host. docker.image('golang:1.10').inside('-v $GOPATH:$GOPATH -e PATH=$GOPATH/bin:/usr/local/go/bin:/usr/sbin:/usr/bin:/sbin:/bin') { stage('Static checks'){ // places 'golint' inside $GOPATH/bin sh 'go get -u golang.org/x/lint/golint' sh 'golint ./...' sh 'golint ./... | grep -v "some text"' } } } } } {code} While the first call to {{golint}} works, the second one fails with: {code} /bin/sh: 1: golint: not found {code} I can reproduce the behaviour in any subshell (regular parenthesis, command substitution, pipe). |
New:
Consider the following pipeline used in a Go project: {code:groovy} node { def goPackage = 'myrepo.com/myproject' def goPath = "${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}" // Jenkins binds WORKSPACE:WORKSPACE (host:container) when executing steps inside a Docker container, therefore the workspace path must be GOPATH-compatible. ws("${goPath}/src/${goPackage}") { withEnv(["GOPATH=${goPath}", 'GOCACHE=/tmp/.gocache']) { stage('Checkout'){ checkout(scm) } // Default GOPATH is owned by root, so we mount our custom GOPATH from the host. docker.image('golang:1.10').inside('-v $GOPATH:$GOPATH -e PATH=$GOPATH/bin:/usr/local/go/bin:/usr/sbin:/usr/bin:/sbin:/bin') { stage('Static checks'){ // places 'golint' inside $GOPATH/bin sh 'go get -u golang.org/x/lint/golint' sh 'golint ./...' sh 'golint ./... | grep -v "some text"' } } } } } {code} While the first call to {{golint}} works, the second one fails with: {code} /bin/sh: 1: golint: not found {code} I can reproduce the behaviour in any subshell (regular parenthesis, command substitution, pipe). The only way around it is to use the full path to the executable. |
Environment |
Original:
Jenkins ver. 2.121.1 Pipeline: Basic Steps 2.8 Pipeline: Groovy 2.45 Pipeline: Stage Step 2.3 |
New:
Jenkins 2.133 Pipeline 2.5 Pipeline: Basic Steps 2.9 Pipeline: Groovy 2.54 Pipeline: Stage Step 2.3 Docker Pipeline 1.17 |
Component/s | New: docker-workflow-plugin [ 20625 ] | |
Component/s | Original: core [ 15593 ] |