Skip to content

Reduce the number of env vars exposed to subprocess#1011

Merged
edmorley merged 1 commit intomasterfrom
cleanup-subprocess-env-vars
Jul 28, 2020
Merged

Reduce the number of env vars exposed to subprocess#1011
edmorley merged 1 commit intomasterfrom
cleanup-subprocess-env-vars

Conversation

@edmorley
Copy link
Copy Markdown
Member

@edmorley edmorley commented Jul 24, 2020

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.

@edmorley edmorley added the bug label Jul 24, 2020
@edmorley edmorley requested a review from a team as a code owner July 24, 2020 14:11
@edmorley edmorley self-assigned this Jul 24, 2020
@edmorley edmorley force-pushed the cleanup-subprocess-env-vars branch from ba95603 to 0e5b8cc Compare July 24, 2020 15:04
@edmorley
Copy link
Copy Markdown
Member Author

@Malax I've updated the PR to fix the test runner (by adding run_in_clean_env) to make the tests pass. Previously env vars from outside the test runner were leaking into the tests. This was an issue since the way tests run locally and on Travis differs even though they both use Docker (something else to fix at some point) so the test was reporting different env vars for each.

edmorley added a commit that referenced this pull request Jul 24, 2020
To prevent external environment variables from leaking into the tests,
which otherwise causes problems trying to write tests for #1011.

Several tests which were relying on this leak had to be fixed, so that
the env vars they were using are set using `ENV_DIR`, as happens in
production.

Fixes #1014.
Fixes #1015.
edmorley added a commit that referenced this pull request Jul 24, 2020
To prevent external environment variables from leaking into the tests,
which otherwise causes problems trying to write tests for #1011.

Several tests which were relying on this leak had to be fixed, so that
the env vars they were using are set using `ENV_DIR`, as happens in
production.

Fixes #1014.
Fixes #1015.
@edmorley edmorley force-pushed the cleanup-subprocess-env-vars branch from 0e5b8cc to 7de388a Compare July 24, 2020 17:17
@edmorley
Copy link
Copy Markdown
Member Author

I've updated the PR to fix the test runner

This fix required several broken tests to be fixed too, so I split those changes out to #1016, and have now rebased on that.

@edmorley
Copy link
Copy Markdown
Member Author

edmorley commented Jul 28, 2020

Even after the test harness fixes in #1016 the newly added test here was failing -- and seemingly only on Travis (it passed locally).

After two hours of digging into the differences between the way the tests run locally and on Travis (something that's now resolved in #1021), I noticed that actually the failures seen were not Travis-specific but stack-specific, and locally I happened to be using the one stack out of three on which the test passed (Heroku-18) 🤦

The fact that the tests failed on only 2 out of 3 stacks on Travis was hard to spot, since the test matrix was configured to split jobs by test suite and not stack, and Heroku-18 was the last stack to run in each job so the passing test was hidden right at the end of the log. I've now split the stacks out into their own jobs as part of #1022 to prevent this in the future.

The test failure itself was due to OLDPWD being present in the environment of bin/{pre,post}_compile on Heroku-18, but not for Cedar-14 or Heroku-16.

I managed to create a repro outside the tests, which shows it only affects subshells:

Ubuntu 16.04:

$ docker run --rm -it ubuntu:16.04 bash -c 'cd /tmp; echo "OLDPWD=$OLDPWD"; bash -c "echo \"OLDPWD=\$OLDPWD\""'
OLDPWD=/
OLDPWD=

Ubuntu 18.04:

$ docker run --rm -it ubuntu:18.04 bash -c 'cd /tmp; echo "OLDPWD=$OLDPWD"; bash -c "echo \"OLDPWD=\$OLDPWD\""'
OLDPWD=/
OLDPWD=/

The version of bash in Ubuntu 16.04 is 4.3.48, and in 18.04 is 4.4.20.

As such I believe it's due to this change:
OLDPWD can be inherited from the environment if it names a directory.
(https://git.savannah.gnu.org/cgit/bash.git/tree/NEWS)

Which is referenced also here:
https://unix.stackexchange.com/questions/242909/why-does-bash-clear-oldpwd-when-a-child-script-is-started
https://groups.google.com/d/msg/gnu.bash.bug/k7o0xnVyUzI/MJz9SfMXAQAJ

As such we should just exclude that env var from the test on the older stacks.

@edmorley edmorley force-pushed the cleanup-subprocess-env-vars branch from 7de388a to 9ad20d9 Compare July 28, 2020 16:41
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.
@edmorley edmorley force-pushed the cleanup-subprocess-env-vars branch from 9ad20d9 to bef82ec Compare July 28, 2020 16:43
@edmorley edmorley merged commit e7c7dfd into master Jul 28, 2020
@edmorley edmorley deleted the cleanup-subprocess-env-vars branch July 28, 2020 17:12
edmorley added a commit that referenced this pull request Oct 15, 2020
In #1011 the number of buildpack variables that are exported (and so
exposed to subprocesses) was reduced, since in general we don't want
to leak buildpack internals into end-user steps such as the pre/post
compile hooks.

However since this change, any buildpack metric emitted from within
a `sub_env` wrapper (which is a buildpack-stdlib utility function)
is missing its `buildpack.python` prefix.

This is because buildpack-stdlib:
* lazy-loads `BPLOG_PREFIX` (rather than doing so when initially
  sourced, which is the approach used for `BUILDPACK_LOG_FILE`)
* doesn't check whether `BPLOG_PREFIX` is set before emitting metrics

See:
https://github.com/heroku/buildpack-stdlib/blob/v8/stdlib.sh

As a stop-gap until we either fix this in buildpack-stdlib (W-8095466),
or remove usages of the `sub_env` wrapper (since I think they are
counter-productive in this buildpack), I've added back the export
for `BPLOG_PREFIX`.

Fixes @W-8095436@.
edmorley added a commit that referenced this pull request Oct 15, 2020
In #1011 the number of buildpack variables that are exported (and so
exposed to subprocesses) was reduced, since in general we don't want
to leak buildpack internals into end-user steps such as the pre/post
compile hooks.

However since this change, any buildpack metric emitted from within
a `sub_env` wrapper (which is a buildpack-stdlib utility function)
is missing its `buildpack.python` prefix.

This is because buildpack-stdlib:
* lazy-loads `BPLOG_PREFIX` (rather than doing so when initially
  sourced, which is the approach used for `BUILDPACK_LOG_FILE`)
* doesn't check whether `BPLOG_PREFIX` is set before emitting metrics

See:
https://github.com/heroku/buildpack-stdlib/blob/v8/stdlib.sh

As a stop-gap until we either fix this in buildpack-stdlib (W-8095466),
or remove usages of the `sub_env` wrapper (since I think they are
counter-productive in this buildpack), I've added back the export
for `BPLOG_PREFIX`.

Fixes @W-8095436@.
dryan pushed a commit to dryan/heroku-buildpack-python that referenced this pull request Nov 19, 2020
To prevent external environment variables from leaking into the tests,
which otherwise causes problems trying to write tests for heroku#1011.

Several tests which were relying on this leak had to be fixed, so that
the env vars they were using are set using `ENV_DIR`, as happens in
production.

Fixes heroku#1014.
Fixes heroku#1015.
dryan pushed a commit to dryan/heroku-buildpack-python that referenced this pull request Nov 19, 2020
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 heroku#1010.
dryan pushed a commit to dryan/heroku-buildpack-python that referenced this pull request Nov 19, 2020
In heroku#1011 the number of buildpack variables that are exported (and so
exposed to subprocesses) was reduced, since in general we don't want
to leak buildpack internals into end-user steps such as the pre/post
compile hooks.

However since this change, any buildpack metric emitted from within
a `sub_env` wrapper (which is a buildpack-stdlib utility function)
is missing its `buildpack.python` prefix.

This is because buildpack-stdlib:
* lazy-loads `BPLOG_PREFIX` (rather than doing so when initially
  sourced, which is the approach used for `BUILDPACK_LOG_FILE`)
* doesn't check whether `BPLOG_PREFIX` is set before emitting metrics

See:
https://github.com/heroku/buildpack-stdlib/blob/v8/stdlib.sh

As a stop-gap until we either fix this in buildpack-stdlib (W-8095466),
or remove usages of the `sub_env` wrapper (since I think they are
counter-productive in this buildpack), I've added back the export
for `BPLOG_PREFIX`.

Fixes @W-8095436@.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Several buildpack script variables are leaked into the environment of subprocesses

2 participants