现有 Bash 脚本的 Jenkins“找不到文件”错误

Kwh*_*ejr 9 bash jenkins docker docker-compose

我的目标是让 Jenkins 2 在 express js 应用程序和 postgres db 之间执行 alpha 集成测试。我将在本地启动容器化资源,并使用使用docker-compose. 相关的 bash 脚本是scripts/docker/dockerRunTest.sh.

但是,当我尝试通过 Jenkins 做同样的事情时,Jenkins 声称没有找到启动脚本。

詹金斯档案

stage('Alpha Integration Tests') {
  agent {
    docker {
      image 'tmaier/docker-compose'
      args '-u root -v /var/run/docker.sock:/var/run/docker.sock --network host'
    }
  }
  steps {
    sh 'ls -lah ./scripts/docker/'
    sh './scripts/docker/dockerRunTest.sh'
  }
}
Run Code Online (Sandbox Code Playgroud)

输出

+ ls -lah ./scripts/docker/
total 36
drwxr-xr-x    2 root     root        4.0K Jan 26 21:31 .
drwxr-xr-x    6 root     root        4.0K Jan 26 20:54 ..
-rwxr-xr-x    1 root     root        2.2K Jan 26 21:31 docker.lib.sh
-rwxr-xr-x    1 root     root         282 Jan 26 21:31 dockerBuildApp.sh
-rwxr-xr-x    1 root     root         289 Jan 26 21:31 dockerBuildTestRunner.sh
-rwxr-xr-x    1 root     root         322 Jan 26 21:31 dockerDown.sh
-rw-r--r--    1 root     root         288 Jan 26 21:31 dockerRestart.sh
-rwxr-xr-x    1 root     root         482 Jan 26 21:31 dockerRunTest.sh
-rwxr-xr-x    1 root     root         284 Jan 26 21:31 dockerUp.sh

+ ./scripts/docker/dockerRunTest.sh
/var/jenkins_home/workspace/project-name@2@tmp/durable-9ac0d23a/script.sh: line 1: ./scripts/docker/dockerRunTest.sh: not found
ERROR: script returned exit code 127
Run Code Online (Sandbox Code Playgroud)

根据ls输出,该文件显然存在。我有一些模糊的想法,即 shell 脚本和 bash 脚本的工作方式之间可能存在一些冲突,但我无法完全理解 Jenkins 无法执行明显存在的脚本的细微差别。

编辑(包括脚本内容):
dockerRunTest.sh

#!/bin/bash

MY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd -P )"
MY_DIR="${MY_DIR:?}"
SCRIPTS_DIR="$(realpath "${MY_DIR}/..")"
ROOT_DIR="$(realpath "${SCRIPTS_DIR}/..")"
TEST_DIR="${ROOT_DIR}/test/integration"
SRC_DIR="${ROOT_DIR}/src"
REPORTS_DIR="${ROOT_DIR}/reports"

. "${SCRIPTS_DIR}/docker/docker.lib.sh"

dockerComposeUp
dockerExecuteTestRunner
dockerComposeDown
Run Code Online (Sandbox Code Playgroud)

docker.lib.sh

#!/bin/bash

CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd -P )"
CURRENT_DIR="${CURRENT_DIR:?}"
SCRIPTS_DIR="$(realpath "${CURRENT_DIR}/..")"
ROOT_DIR="$(realpath "${SCRIPTS_DIR}/..")"

. "${SCRIPTS_DIR}/lib.sh"

dockerComposeUp() {
  docker-compose build --no-cache
  docker-compose up --detach --force-recreate
  DC_CODE=$?

  if [ ${DC_CODE} -ne 0 ]; then
    # Introspection
    docker-compose logs
    docker-compose ps

    exit ${DC_CODE}
  fi
}

dockerComposeDown() {
  # docker-compose rm: Removes stopped service containers.
  #   -f, --force - Don't ask to confirm removal.
  #   -s, --stop - Stop the containers, if required, before removing.
  #   -v - Remove any anonymous volumes attached to containers.
  docker-compose rm --force --stop -v
}

dockerComposeRestart() {
  dockerComposeDown
  dockerComposeUp
}

dockerBuildTestRunner() {
  docker build -f test/Dockerfile -t kwhitejr/botw-test-runner .
}

dockerExecuteTestRunner() {
  IMAGE_NAME="kwhitejr/botw-test-runner"

  echo "Build new ${IMAGE_NAME} image..."
  dockerBuildTestRunner

  echo "Run ${IMAGE_NAME} executable test container..."
  docker run -it --rm --network container:api_of_the_wild_app_1 kwhitejr/botw-test-runner
}
Run Code Online (Sandbox Code Playgroud)

Ble*_*ess 8

tmaier/docker-compose/bin/bash默认情况下,图像没有安装解释器,因为latest标签是alpine图像 [1, 2]。这可以通过运行来确认:

$ docker run -it --rm tmaier/docker-compose bash
/usr/local/bin/docker-entrypoint.sh: exec: line 35: bash: not found
Run Code Online (Sandbox Code Playgroud)

要使脚本正常工作,请使用在 docker 映像中安装 bashapk add bash或将 shebang 更改为#!/bin/sh是否可以使用ashshell(busybox 中的默认 shell)运行脚本。

[1] https://github.com/tmaier/docker-compose/blob/b740feb61fb25030101638800a609605cfd5e96a/Dockerfile#L2

[2] https://github.com/docker-library/docker/blob/d94b9832f55143f49e47d00de63589ed41f288e7/18.09/Dockerfile#L1

  • 啊,在给定的公共 docker 图像中进行调查 - 光荣。非常聪明。FWIW,“vanilla sh”并不是真的有效。不同的 shell 具有不同的语法和几个早于 bash(csh、ksh、bourne,这可能会密切模仿)。这个平台上的 _real_ `sh` 是 busybox(试试 `$ docker run -it --rm --entrypoint sh tmaier/docker-compose --help | head -n 1`) (2认同)