From 8584e65c6297d93709479988958f6ba717a4cd26 Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Sat, 17 Jun 2023 17:52:03 -0300 Subject: [PATCH] Fix container id discovery on environments like GitHub Actions (#4) And also creates a workflow for testing changes. --- .github/workflows/ci.yaml | 38 +++++++++++++++++ docker | 65 ++++++++++++++++++++--------- test.sh => scripts/test.sh | 59 ++++++++++++++------------ testfile => tests/fixtures/testfile | 0 4 files changed, 116 insertions(+), 46 deletions(-) create mode 100644 .github/workflows/ci.yaml rename test.sh => scripts/test.sh (67%) rename testfile => tests/fixtures/testfile (100%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..a70e724 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,38 @@ +name: ci + +on: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + test: + strategy: + fail-fast: false + matrix: + docker-version: ["18.09", "19.03", "20.10", "23", "24", latest] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Show host Docker information + run: | + docker version + docker info + - name: Run tests with Docker ${{ matrix.docker-version }} + run: | + if [[ '${{ runner.debug }}' == 1 ]]; then + export DEBUG=true + export DOND_SHIM_DEBUG=true + fi + scripts/test.sh '${{ matrix.docker-version }}' + result: + needs: test + runs-on: ubuntu-latest + steps: + - run: | + echo "All tests passed!" diff --git a/docker b/docker index 6af1a75..5353dc7 100755 --- a/docker +++ b/docker @@ -19,11 +19,18 @@ function echo_error() { function error() { echo_error "${@}" + uncaught_error=false exit 1 } # Ensure the user knows that the error was originated from the shim -trap 'echo_error "Uncaught error at line ${LINENO}"' ERR +function handle_error_trap() { + if [[ "${uncaught_error:-true}" == true ]]; then + echo_error "Uncaught error at line ${LINENO}" + fi +} + +trap handle_error_trap ERR # Finds all docker options that take a value from the --help output and # stores them in the docker_options_with_value array. @@ -59,29 +66,50 @@ function run_docker() { } # Gets the current/parent container id on the host. -function get_container_id() { - local cpuset_output - cpuset_output=$(head -1 /proc/self/cpuset) - basename "${cpuset_output}" +function set_container_id() { + local result + + local mount_info_lines=() + readarray -t mount_info_lines /dev/null 2>&1 - pwd -P -)" +script_path="$(realpath "$0")" readonly script_path # Parse supported environment variables diff --git a/test.sh b/scripts/test.sh similarity index 67% rename from test.sh rename to scripts/test.sh index ca92b32..d173fe3 100755 --- a/test.sh +++ b/scripts/test.sh @@ -18,7 +18,7 @@ trap "exit 130" INT # Set docker versions from args or use default if [[ $# -eq 0 ]]; then - docker_versions=("18.09" "19.03" "20.10" "23" "24" latest) + docker_versions=(latest) else docker_versions=("$@") fi @@ -26,53 +26,60 @@ readonly docker_versions readonly docker_args=(docker run --rm --env DOND_SHIM_DEBUG --volume /var/run/docker.sock:/var/run/docker.sock) +# Find fixtures directory +script_path=$(realpath "$0") +script_dir=$(dirname "${script_path}") +fixtures_dir="$(realpath "${script_dir}/../tests/fixtures")" +readonly fixtures_dir +unset script_path script_dir + for docker_version in "${docker_versions[@]}"; do echo "Testing with docker version: ${docker_version}" image_id="$(docker build --target test --build-arg "DOCKER_VERSION=${docker_version}" --quiet .)" echo "Do not change global options or after the image" - "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${PWD}:/wd" "${image_id}" \ + "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${fixtures_dir}:/wd" "${image_id}" \ docker --host test run --volume /wd:/wd alpine --volume /wd:/wd | - grep --quiet "^docker.orig --host test run --volume ${PWD}:/wd alpine --volume /wd:/wd$" + grep --quiet "^docker.orig --host test run --volume ${fixtures_dir}:/wd alpine --volume /wd:/wd$" echo "Same as above, but retaining read only mode" - "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${PWD}:/wd" "${image_id}" \ + "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${fixtures_dir}:/wd" "${image_id}" \ docker --host test run --volume /wd:/wd:ro alpine --volume /wd:/wd | - grep --quiet "^docker.orig --host test run --volume ${PWD}:/wd:ro alpine --volume /wd:/wd$" + grep --quiet "^docker.orig --host test run --volume ${fixtures_dir}:/wd:ro alpine --volume /wd:/wd$" echo "Same as above but with --mount" - "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${PWD}:/wd" "${image_id}" \ + "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${fixtures_dir}:/wd" "${image_id}" \ docker --host test run --volume /wd:/wd:ro --mount=type=bind,source=/wd,readonly,destination=/wd2 alpine --volume /wd:/wd | - grep --quiet "^docker.orig --host test run --volume ${PWD}:/wd:ro --mount=type=bind,source=${PWD},readonly,destination=/wd2 alpine --volume /wd:/wd$" + grep --quiet "^docker.orig --host test run --volume ${fixtures_dir}:/wd:ro --mount=type=bind,source=${fixtures_dir},readonly,destination=/wd2 alpine --volume /wd:/wd$" echo "Same as above (without --mount), but retaining read only mode on auto added volume" - "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --env DOND_SHIM_MOCK_CONTAINER_ROOT_ON_HOST=/container-root --volume "${PWD}:/wd" --volume "${PWD}/testfile:/test/testfile" "${image_id}" \ + "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --env DOND_SHIM_MOCK_CONTAINER_ROOT_ON_HOST=/container-root --volume "${fixtures_dir}:/wd" --volume "${fixtures_dir}/testfile:/test/testfile" "${image_id}" \ docker --host test run --volume /wd:/wd:ro --volume /test:/test:ro alpine --volume /wd:/wd | - grep --quiet "^docker.orig --host test run --volume ${PWD}:/wd:ro --volume /container-root/test:/test:ro --volume ${PWD}/testfile:/test/testfile:ro alpine --volume /wd:/wd$" + grep --quiet "^docker.orig --host test run --volume ${fixtures_dir}:/wd:ro --volume /container-root/test:/test:ro --volume ${fixtures_dir}/testfile:/test/testfile:ro alpine --volume /wd:/wd$" echo "Same as above (with --mount src and target, dst), but retaining read only mode on auto added volume" - "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --env DOND_SHIM_MOCK_CONTAINER_ROOT_ON_HOST=/container-root --volume "${PWD}:/wd" --volume "${PWD}/testfile:/test/testfile" "${image_id}" \ + "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --env DOND_SHIM_MOCK_CONTAINER_ROOT_ON_HOST=/container-root --volume "${fixtures_dir}:/wd" --volume "${fixtures_dir}/testfile:/test/testfile" "${image_id}" \ docker --host test run --mount type=bind,src=/wd,target=/wd,readonly --mount type=bind,source=/test,dst=/test,readonly alpine --mount type=bind,source=/wd,destination=/wd,readonly | - grep --quiet "^docker.orig --host test run --mount type=bind,src=${PWD},target=/wd,readonly --mount type=bind,source=/container-root/test,dst=/test,readonly --mount type=bind,source=${PWD}/testfile,dst=/test/testfile,readonly alpine --mount type=bind,source=/wd,destination=/wd,readonly$" + grep --quiet "^docker.orig --host test run --mount type=bind,src=${fixtures_dir},target=/wd,readonly --mount type=bind,source=/container-root/test,dst=/test,readonly --mount type=bind,source=${fixtures_dir}/testfile,dst=/test/testfile,readonly alpine --mount type=bind,source=/wd,destination=/wd,readonly$" echo "Same but for container run" - "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${PWD}:/wd" "${image_id}" \ + "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${fixtures_dir}:/wd" "${image_id}" \ docker --host test container run --volume /wd:/wd alpine --volume /wd:/wd | - grep --quiet "^docker.orig --host test container run --volume ${PWD}:/wd alpine --volume /wd:/wd$" + grep --quiet "^docker.orig --host test container run --volume ${fixtures_dir}:/wd alpine --volume /wd:/wd$" echo "Same but for create" - "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${PWD}:/wd" "${image_id}" \ + "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${fixtures_dir}:/wd" "${image_id}" \ docker --host test create --volume /wd:/wd alpine --volume /wd:/wd | - grep --quiet "^docker.orig --host test create --volume ${PWD}:/wd alpine --volume /wd:/wd$" + grep --quiet "^docker.orig --host test create --volume ${fixtures_dir}:/wd alpine --volume /wd:/wd$" echo "Same but container create" - "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${PWD}:/wd" "${image_id}" \ + "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${fixtures_dir}:/wd" "${image_id}" \ docker --host test container create --volume /wd:/wd alpine --volume /wd:/wd | - grep --quiet "^docker.orig --host test container create --volume ${PWD}:/wd alpine --volume /wd:/wd$" + grep --quiet "^docker.orig --host test container create --volume ${fixtures_dir}:/wd alpine --volume /wd:/wd$" echo "Do not do anything for other commands" - "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${PWD}:/wd" "${image_id}" \ + "${docker_args[@]}" --env DOND_SHIM_PRINT_COMMAND=true --volume "${fixtures_dir}:/wd" "${image_id}" \ docker --host test whatever --volume /wd:/wd alpine --volume /wd:/wd | grep --quiet "^docker.orig --host test whatever --volume /wd:/wd alpine --volume /wd:/wd$" @@ -89,34 +96,34 @@ for docker_version in "${docker_versions[@]}"; do docker run --rm --volume=/test/only-inside-container:/only-inside-container ubuntu:latest grep "^test$" /only-inside-container >/dev/null echo "Check if mounting a volume which is already a volume gets fixed" - "${docker_args[@]}" --volume "${PWD}:/wd" "${image_id}" \ + "${docker_args[@]}" --volume "${fixtures_dir}:/wd" "${image_id}" \ docker run --rm --volume /wd:/wd ubuntu:latest grep "^test$" /wd/testfile >/dev/null echo "Same as above but for a file within the volume" - "${docker_args[@]}" --volume "${PWD}:/wd" "${image_id}" \ + "${docker_args[@]}" --volume "${fixtures_dir}:/wd" "${image_id}" \ docker run --rm --volume /wd/testfile:/wd/testfile ubuntu:latest grep "^test$" /wd/testfile >/dev/null echo "Check if mounting a volume which contains another volume adds all proper volumes" - "${docker_args[@]}" --volume "${PWD}/testfile:/test/testfile" "${image_id}" \ + "${docker_args[@]}" --volume "${fixtures_dir}/testfile:/test/testfile" "${image_id}" \ docker run --rm --volume /test:/wd ubuntu:latest grep "^test$" /wd/testfile >/dev/null echo "With --mount" - "${docker_args[@]}" --volume "${PWD}/testfile:/test/testfile" "${image_id}" \ + "${docker_args[@]}" --volume "${fixtures_dir}/testfile:/test/testfile" "${image_id}" \ docker run --rm --mount type=bind,source=/test,destination=/wd ubuntu:latest grep "^test$" /wd/testfile >/dev/null echo "With --mount shuffling order" - "${docker_args[@]}" --volume "${PWD}/testfile:/test/testfile" "${image_id}" \ + "${docker_args[@]}" --volume "${fixtures_dir}/testfile:/test/testfile" "${image_id}" \ docker run --rm --mount destination=/wd,source=/test,type=bind ubuntu:latest grep "^test$" /wd/testfile >/dev/null echo "Same as above but for multiple files under different volumes" - "${docker_args[@]}" --volume "${PWD}/testfile:/test/testfile" --volume "${PWD}/testfile:/test/testfile2" "${image_id}" \ + "${docker_args[@]}" --volume "${fixtures_dir}/testfile:/test/testfile" --volume "${fixtures_dir}/testfile:/test/testfile2" "${image_id}" \ docker run --rm --volume /test:/wd ubuntu:latest bash -c 'grep "^test$" /wd/testfile && grep "^test$" /wd/testfile2 && grep "^test$" /wd/only-inside-container' >/dev/null echo "Same test as above but with a read only volume" - "${docker_args[@]}" --volume "${PWD}/testfile:/test/testfile" --volume "${PWD}/testfile:/test/testfile2" "${image_id}" \ + "${docker_args[@]}" --volume "${fixtures_dir}/testfile:/test/testfile" --volume "${fixtures_dir}/testfile:/test/testfile2" "${image_id}" \ docker run --rm --volume /test:/wd:ro ubuntu:latest bash -c 'grep "^test$" /wd/testfile && grep "^test$" /wd/testfile2 && grep "^test$" /wd/only-inside-container' >/dev/null echo "Same as above but with a volume that matches the parent first" - "${docker_args[@]}" --volume "${PWD}:/folder" --volume "${PWD}/testfile:/test/testfile" --volume "${PWD}/testfile:/test/testfile2" "${image_id}" \ + "${docker_args[@]}" --volume "${fixtures_dir}:/folder" --volume "${fixtures_dir}/testfile:/test/testfile" --volume "${fixtures_dir}/testfile:/test/testfile2" "${image_id}" \ docker run --rm --volume /folder:/test --volume /test:/wd:ro ubuntu:latest bash -c 'grep "^test$" /wd/testfile && grep "^test$" /wd/testfile2 && grep "^test$" /wd/only-inside-container' >/dev/null done diff --git a/testfile b/tests/fixtures/testfile similarity index 100% rename from testfile rename to tests/fixtures/testfile