diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 514522d0..51d1fe06 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -128,6 +128,17 @@ jobs: if [ $? -ne 0 ]; then exit 1 fi + # test the EXIT trap on process crash + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_trap_exit.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep \ + -e DEBUG_ONLY=false \ + -e REPO_URL=https://github.com/fake/repo \ + -e RUNNER_TOKEN=faketoken \ + -e RUN_AS_ROOT=true \ + -e DISABLE_AUTOMATIC_DEREGISTRATION=false \ + ${GH_RUNNER_IMAGE} 10 + if [ $? -ne 0 ]; then + exit 1 + fi debian_tests: runs-on: ubuntu-latest strategy: @@ -233,3 +244,14 @@ jobs: -e EPHEMERAL=true \ -e DISABLE_AUTO_UPDATE=true \ ${GH_RUNNER_IMAGE} 10 + # test the EXIT trap on process crash + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_trap_exit.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep \ + -e DEBUG_ONLY=false \ + -e REPO_URL=https://github.com/fake/repo \ + -e RUNNER_TOKEN=faketoken \ + -e RUN_AS_ROOT=true \ + -e DISABLE_AUTOMATIC_DEREGISTRATION=false \ + ${GH_RUNNER_IMAGE} 10 + if [ $? -ne 0 ]; then + exit 1 + fi diff --git a/entrypoint.sh b/entrypoint.sh index 73b0ad3c..a1dc9e09 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -20,6 +20,7 @@ trap_with_arg() { } deregister_runner() { + COMMAND_EXIT_CODE=$? echo "Caught $1 - Deregistering runner" if [[ -n "${ACCESS_TOKEN}" ]]; then # If using GitHub App authentication, refresh the access token before deregistration @@ -40,7 +41,11 @@ deregister_runner() { fi ./config.sh remove --token "${RUNNER_TOKEN}" [[ -f "/actions-runner/.runner" ]] && rm -f /actions-runner/.runner - exit + + # Simply calling `exit` on different environments will either return the exit code of the passed-in $@ command, or + # the exit code of the last executed command in this function. To ensure that the behavior is consistent, we always + # return the exit code of the passed-in command, which is stored in COMMAND_EXIT_CODE. + exit ${COMMAND_EXIT_CODE} } _DEBUG_ONLY=${DEBUG_ONLY:-false} @@ -236,7 +241,7 @@ fi if [[ ${_DISABLE_AUTOMATIC_DEREGISTRATION} == "false" ]]; then if [[ ${_DEBUG_ONLY} == "false" ]]; then - trap_with_arg deregister_runner SIGINT SIGQUIT SIGTERM INT TERM QUIT + trap_with_arg deregister_runner SIGINT SIGQUIT SIGTERM INT TERM QUIT EXIT fi fi diff --git a/goss_trap_exit.yaml b/goss_trap_exit.yaml new file mode 100644 index 00000000..56f2ae19 --- /dev/null +++ b/goss_trap_exit.yaml @@ -0,0 +1,10 @@ +command: + /entrypoint.sh /bin/bash -c "exit 1": + exit-status: 1 + stdout: + - "Runner reusage is disabled" + - "Caught EXIT - Deregistering runner" + # We need to run this test with DEBUG_ONLY=false in order for entrypoint.sh to set up the trap. + # DEBUG_ONLY causes configure runner to run, which runs the .NET runtime. Running the .NET runtime + # is very slow when emulating arm64 on x86_64, so we need to use a longer timeout for this test to pass on arm64. + timeout: 120000