From e7c7dfdb260c721ffdcb57c561f5ff369975cc90 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:12:08 +0100 Subject: [PATCH] Reduce the number of env vars exposed to subprocess (#1011) The following env vars are no longer exposed to subprocesses run by the buildpack (such as the `bin/pre_compile` and `bin/post_compile` hooks): * `BPLOG_PREFIX` * `CACHED_PYTHON_STACK` * `DEFAULT_PYTHON_STACK` * `DEFAULT_PYTHON_VERSION` * `LATEST_27` * `LATEST_34` * `LATEST_35` * `LATEST_36` * `LATEST_37` * `LATEST_38` * `PIP_UPDATE` * `PY27` * `PY34` * `PY35` * `PY36` * `PY37` * `PYPY_27` * `PYPY_36` * `RECOMMENDED_PYTHON_VERSION` * `WARNINGS_LOG` There were previously no tests at all for the pre/post-compile hooks, so I've added some now. Fixes #1010. --- CHANGELOG.md | 1 + bin/compile | 12 +++----- bin/default_pythons | 15 ++++------ test/fixtures/hooks/bin/post_compile | 4 +++ test/fixtures/hooks/bin/pre_compile | 4 +++ test/fixtures/hooks/requirements.txt | 0 test/run-features | 43 ++++++++++++++++++++++++++++ 7 files changed, 61 insertions(+), 18 deletions(-) create mode 100644 test/fixtures/hooks/bin/post_compile create mode 100644 test/fixtures/hooks/bin/pre_compile create mode 100644 test/fixtures/hooks/requirements.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index a32fb0a..6275cba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ # Master +- Reduce the number of environment variables exposed to `bin/{pre,post}_compile` and other subprocesses (#1011) # 173 (2020-07-21) diff --git a/bin/compile b/bin/compile index 89c4051..dd270d8 100755 --- a/bin/compile +++ b/bin/compile @@ -16,7 +16,9 @@ set -eo pipefail # Boostrap the Buildpack Standard Library. -export BPLOG_PREFIX="buildpack.python" +# Disable unused env var warning since shellcheck doesn't know about the stdlib. +# shellcheck disable=2034 +BPLOG_PREFIX="buildpack.python" export BUILDPACK_LOG_FILE=${BUILDPACK_LOG_FILE:-/dev/null} [ "$BUILDPACK_XTRACE" ] && set -o xtrace @@ -84,16 +86,12 @@ if [[ -f "$BUILD_DIR/Pipfile" ]]; then PIP_UPDATE="9.0.2" fi -export DEFAULT_PYTHON_STACK PIP_UPDATE -export PY37 PY36 PY35 PY27 PY34 - # Common Problem Warnings: # This section creates a temporary file in which to stick the output of `pip install`. # The `warnings` subscript then greps through this for common problems and guides # the user towards resolution of known issues. WARNINGS_LOG=$(mktemp) -export WARNINGS_LOG -export RECOMMENDED_PYTHON_VERSION=$DEFAULT_PYTHON_VERSION +RECOMMENDED_PYTHON_VERSION=$DEFAULT_PYTHON_VERSION # The buildpack ships with a few executable tools (e.g. pip-grep, etc). # This installs them into the path, so we can execute them directly. @@ -217,8 +215,6 @@ else CACHED_PYTHON_STACK=$STACK fi -export CACHED_PYTHON_STACK - # Pipenv Python version support. # Detect the version of Python requested from a Pipfile (e.g. python_version or python_full_version). # Convert it to a runtime.txt file. diff --git a/bin/default_pythons b/bin/default_pythons index 4dc00ff..2fe4e10 100755 --- a/bin/default_pythons +++ b/bin/default_pythons @@ -1,5 +1,10 @@ #!/usr/bin/env bash +# Disable unused env var warning, since shellcheck doesn't take into account +# that this file is sourced. We don't want to use export since it exposes +# the env vars to subprocesses. +# shellcheck disable=2034 + DEFAULT_PYTHON_VERSION="python-3.6.11" LATEST_38="python-3.8.5" LATEST_37="python-3.7.8" @@ -9,13 +14,3 @@ LATEST_34="python-3.4.10" LATEST_27="python-2.7.18" PYPY_36="pypy3.6-7.3.1" PYPY_27="pypy2.7-7.3.1" - -export DEFAULT_PYTHON_VERSION \ - LATEST_38 \ - LATEST_37 \ - LATEST_36 \ - LATEST_35 \ - LATEST_34 \ - LATEST_27 \ - PYPY_36 \ - PYPY_27 diff --git a/test/fixtures/hooks/bin/post_compile b/test/fixtures/hooks/bin/post_compile new file mode 100644 index 0000000..0281f03 --- /dev/null +++ b/test/fixtures/hooks/bin/post_compile @@ -0,0 +1,4 @@ +set -euo pipefail + +echo "post_compile ran!" +echo "post_compile env: $(printenv | cut -d '=' -f 1 | sort | xargs)." diff --git a/test/fixtures/hooks/bin/pre_compile b/test/fixtures/hooks/bin/pre_compile new file mode 100644 index 0000000..e9adbc2 --- /dev/null +++ b/test/fixtures/hooks/bin/pre_compile @@ -0,0 +1,4 @@ +set -euo pipefail + +echo "pre_compile ran!" +echo "pre_compile env: $(printenv | cut -d '=' -f 1 | sort | xargs)." diff --git a/test/fixtures/hooks/requirements.txt b/test/fixtures/hooks/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/run-features b/test/run-features index 8982eb0..c50a8c3 100755 --- a/test/run-features +++ b/test/run-features @@ -86,6 +86,49 @@ testDontWarnOldDjango() { assertCapturedSuccess } +testHooks() { + # Test that the hooks are called correctly, and that the environment contains + # the app's config vars but no unexpected env vars from the buildpack. + local env_dir="$(mktmpdir)" + echo 'test' > "${env_dir}/SOME_APP_CONFIG_VAR" + local expected_env_vars=( + _ + BIN_DIR + BUILD_DIR + BUILDPACK_LOG_FILE + CACHE_DIR + C_INCLUDE_PATH + CPLUS_INCLUDE_PATH + ENV_DIR + EXPORT_PATH + HOME + LANG + LD_LIBRARY_PATH + LIBRARY_PATH + OLDPWD + PATH + PKG_CONFIG_PATH + PROFILE_PATH + PWD + PYTHONUNBUFFERED + SHLVL + SOME_APP_CONFIG_VAR + STACK + VENDOR_URL + ) + if [[ "${STACK}" == "cedar-14" || "${STACK}" == "heroku-16" ]]; then + # Remove "OLDPWD" from expected_env_vars since for bash <4.4 it's not exported to subshells: + # https://github.com/heroku/heroku-buildpack-python/pull/1011#issuecomment-665117835 + read -ra expected_env_vars <<< "${expected_env_vars[@]/OLDPWD/}" + fi + compile 'hooks' '' "${env_dir}" + assertCaptured "pre_compile ran!" + assertCaptured "pre_compile env: ${expected_env_vars[*]}." + assertCaptured "post_compile ran!" + assertCaptured "post_compile env: ${expected_env_vars[*]}." + assertCapturedSuccess +} + pushd $(dirname 0) >/dev/null popd >/dev/null