Jenkins 使用 docker.image.withRun 通过 sh 执行第二条命令
我目前有一个 Jenkins 脚本,它启动一个 Docker 容器,其中使用 Maven 运行 Selenium 测试。 Selenium 测试执行成功,Maven 返回“构建成功”。
问题如下:Jenkins 不仅执行 Jenkinsfile 中指定的 sh 命令,还执行了未知的第二个 sh 命令。
如图所示,突出显示的部分作为命令执行,这显然不是命令,这意味着 Docker 容器返回错误代码 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
}
}
}
控制台输出(某些部分由于不相关而被隐藏):
+ 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
这是一个常见问题,很容易解决,还是我的 Jenkinsfile 有问题,我该如何修复?
谢谢
看来
/wd/hub
部分来自您执行的代码行,这让我相信您的问题是由于您添加引号的方式造成的。
您的代码行是:
sh "mvn clean test -Denvironment=${env.Profile} -Dselenide.headless=true -Dselenide.remote=http://" + c.port(4444) + "/wd/hub"
具体来说,您使用
"
打开命令,然后在
http://
之后使用另一个
"
关闭它。我猜詹金斯认为这不可接受。尝试单独创建网址
def url = "http://" + c.port(4444) + "/wd/hub"
并在执行行中使用此变量
sh "mvn clean test -Denvironment=${env.Profile} -Dselenide.headless=true -Dselenide.remote=${url}"
我以前没有使用过
docker.image
,所以您可能需要尝试一下才能使其正常工作。
在进一步研究文档并尝试不同的东西之后,这是对我有用的:
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
}
}
}
所以我用
.withRun(-v /dev/shm:/dev/shm -p 4444:4444')
替换
.withRun('-v /dev/shm:/dev/shm -P')
,并用
selenideRemote
变量替换
c.port(4444)
。
删除
c.port(4444)
会停止执行有问题的第二个命令。将
-P
替换为
-p 4444:4444
可防止将容器内部的端口 4444 分配给主机上的随机端口,这也防止使用
c.port(4444)
。