Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment variables #289

Merged
merged 12 commits into from
Jun 21, 2023
Merged

Environment variables #289

merged 12 commits into from
Jun 21, 2023

Conversation

tsibley
Copy link
Member

@tsibley tsibley commented Jun 12, 2023

See commit messages.

Other context in my notes:

Testing

  • Checks pass

@tsibley tsibley force-pushed the trs/env branch 4 times, most recently from 6c0b676 to 908a985 Compare June 16, 2023 21:51
@tsibley tsibley requested a review from a team June 16, 2023 21:52
@tsibley tsibley marked this pull request as ready for review June 16, 2023 21:52
@tsibley
Copy link
Member Author

tsibley commented Jun 16, 2023

Looks like CI caught an issue on Python 3.8 and up in some new doctests that don't explicitly cleanup a temp dir (c.f.):

ResourceWarning: Implicitly cleaning up <TemporaryDirectory '/tmp/tmpc8f2f210'>

This warning is turned into an error by our pytest config, and only happens because of some doctest code anyway, so it's a CI-specific failure. I'll address it nevertheless.

Hilariously, the warning-turned-error can't be raised, presumably because the warning is emitted during global destruction, and this causes another warning, pytest.PytestUnraisableExceptionWarning.

@tsibley
Copy link
Member Author

tsibley commented Jun 16, 2023

A couple other CI issues cropping up. Not sure why they're happening now, but I'll dig. Seem unrelated to this PR.

  • macOS with Python 3.7 failed (and only that one!) because of missing bz2 support in Python, which is optional but assumed to be present by fsspec, which is in the import chain of most/all of our code here, so everything falls to pieces. I think the missing bz2 support is some transient/temporary issue with the Python we're getting or the runner or something (update: it is) and we should fix/workaround that, but fsspec should also not assume bz2 support, so I filed a fix for that.
  • All of the test-source jobs on Windows failed (e.g.) because Windows lets you read a directory like a file (it appears empty) and thus a doctest in the envdir reading code failed because it expects a IsADirectoryError instead. TIL!

@tsibley
Copy link
Member Author

tsibley commented Jun 16, 2023

CI now passes! I addressed the Windows issue by checking for directories explicitly so it's compat across platforms, and the macOS bz2 issue was apparently indeed transient.

@tsibley
Copy link
Member Author

tsibley commented Jun 20, 2023

One thing I want to consider (and think we should do) to help deprecate and remove the automatic hostenv forwarding is to disable it when these new --env or --envdir options are used. Since they're new, their use is a good time/indicator to push folks to spell out what they need without hostenv. Thoughts?

@tsibley
Copy link
Member Author

tsibley commented Jun 20, 2023

I've done that now in fa2633d.

@tsibley
Copy link
Member Author

tsibley commented Jun 20, 2023

CI failures appear unrelated: one of the Markdown image inlining tests is failing and started failing with yesterday's scheduled CI. I assume some new release of a dep broke something.

tsibley added 10 commits June 21, 2023 09:46
For compat on systems that don't have GNU coreutils, like macOS by
default.  Motivated by noticing in macOS CI jobs that devel/pytest was
reporting "command not found: realpath" which results in `cd ""`, which
results in no change of directory.  But that's ok in the CI context so
tests still worked.

Anyhow, the usage in devel/pytest was copypasta (from me, two weeks
ago!) that never warranted realpath.
…menting it

The use of hostenv.forwarded_names was because that's what the Docker
runner does and this Singularity runner was based on that.  But the
reasons Docker does so don't apply here to Singularity.
Most usages weren't annotated, and so weren't type checked.  Type
checking adds confidence in the correctness of future changes to how
extra_env is handled.

Such changes are something I'm about to do, and so using an alias makes
it easier to make those changes.
Caught by the type checker now that extra_env is consistently annotated
with a type.
This will be used to support the semantics of 0 byte files in envdirs
when I add envdir support next.
These fix the lack of easy, supported ways to pass thru, set, and
otherwise manage the variables present in the runtime environments.

Previous workarounds for these missing features include a) hardcoding a
list of often-crucial variables from the host that are always passed
thru (nextstrain.cli.hostenv) and b) manually overriding --exec to
`envdir` thru a provided directory.  The new env support should let us
eliminate or reduce the scope of those workarounds over time.  For now
the "hostenv" concept sticks around for compatibility reasons.
Passing an additional --env=HOST=0.0.0.0 arg to `docker run` is a hacky
implementation encapsulation break.  It only works to override the
HOST=127.0.0.1 value provided via extra_env because the Docker runner
translates extra_env to --env options that come before the additional
args.  The implementation of extra_env is about to change, however, and
the hacky --env=HOST=0.0.0.0 arg here would no longer override it.

All this would be simpler if the container shared the host's network
interfaces (i.e. --network=host) instead of using separate interfaces
and bridging to the host, but doing so assumes the container (i.e.
dockerd) is running on the same host as we are.  True most of the time,
but not guaranteed.  This is the more minimal change anyway.
…n/env.d…

…when the image is new enough to support that.

This ensures the env values aren't visible in the container's config
(e.g. `docker inspect`, `aws batch describe-jobs`, the AWS web console).

Temporary env.d directories (or ZIP archives of such) are written, given
to the container, and then removed by the container's entrypoint after
use.  This minimizes the amount of time values exist outside of memory,
persisted to storage (disk, S3).

Other runners/runtimes don't have visibility or persistence issues
because they directly exec the runtime process and thus can directly
manipulate its environment without any intermediary.
The hostenv concept in the runner code predates the extra_env concept,
and, unlike extra_env which is centralized thru the runner dispatcher,
hostenv was handled independently by each runner.¹

By centralizing hostenv handling in the runner dispatcher and making it
just another (automatic) part of extra_env, we simplify the runners,
improve the security/visibility of the values in hostenv thru the recent
improvements to extra_env handling, and make it easier to eventually
deprecate/remove hostenv entirely.

¹ The reasoning at the time was that hostenv forwarding was only needed
  for containerized runners, and so the ambient (née native) runner
  didn't need to use it.
These new options are a good place to attach this related backwards
incompatible change, since their usage acts as an opt-in.  Eliminating
automatic forwarding also makes it clearer what's getting passed when
combined with explicit forwarding.

We can (and should) still fully remove automatic hostenv in the future.
@tsibley
Copy link
Member Author

tsibley commented Jun 21, 2023

Rebased onto latest master after merge of #294.

Copy link
Member

@victorlin victorlin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I browsed through the commits and did a basic test using nextstrain shell --env and nextstrain shell --envdir. Good changes!

nextstrain/cli/env.py Show resolved Hide resolved
nextstrain/cli/runner/docker.py Show resolved Hide resolved
LICENSE.id3c Outdated Show resolved Hide resolved
Comment on lines +25 to +29
When either of these options are given, the default behaviour of
automatically passing thru several "well-known" environment variables is
disabled. That is, the following "well-known" environment variables are only
automatically passed thru when the new `--env` and `--envdir` options are
_not_ used:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I want to consider (and think we should do) to help deprecate and remove the automatic hostenv forwarding is to disable it when these new --env or --envdir options are used. Since they're new, their use is a good time/indicator to push folks to spell out what they need without hostenv. Thoughts?

Makes sense to me!

tsibley added 2 commits June 21, 2023 16:08
…-env

Lists formatted as if they're for computers not humans are a pet peeve
of mine, so address it here.  This copy of prose_list() will also make
it quick to improve other lists in this codebase in the future.
@tsibley tsibley merged commit d742d3e into master Jun 21, 2023
@tsibley tsibley deleted the trs/env branch June 21, 2023 23:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

2 participants