-
Notifications
You must be signed in to change notification settings - Fork 165
Document environment variable precedence #4364
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,272 @@ | ||
| .. _environment-variable-precedence: | ||
|
|
||
| :tocdepth: 2 | ||
|
|
||
| Environment precedence | ||
| ~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. warning:: | ||
|
|
||
| Just a draft, adding my notes, moving sections around, etc. very | ||
| fluid. | ||
|
|
||
| .. todo:: | ||
|
|
||
| AFAICT, the rough order of precedence, as of now, is something like the following: | ||
|
|
||
| * ``provision[].environment`` | ||
| * ``test[].environment`` | ||
| * "plan environment" | ||
| * ``$TMT_PLAN_ENVIRONMENT_FILE`` | ||
| * plan ``environment-file`` key | ||
| * plan ``environment`` key | ||
| * importing plan "native" environment | ||
| * importing plan ``environment-file`` key | ||
| * importing plan ``environment`` key | ||
| * importing plan importing plan ... | ||
| * run environment saved in the workdir (``--environment`` and ``--environment-file`` from previous invocations) | ||
| * ``tmt run --environment`` | ||
| * ``tmt run --environment-file`` | ||
| * plan intrinsic variables: ``TMT_VERSION``, ``TMT_TREE``, ... | ||
| * plugin intrinsic variables | ||
| * abort context | ||
| * reboot context | ||
| * restart context | ||
| * pidfile context | ||
| * restraint context | ||
| * test framework | ||
| * ... | ||
|
|
||
| .. todo:: | ||
|
|
||
| This should be the desired order of precedence: | ||
|
|
||
| * ``test[].environment`` | ||
| * plan ``environment-file`` key | ||
| * plan ``environment`` key | ||
| * importing plan "native" environment | ||
| * importing plan ``environment-file`` key | ||
| * importing plan ``environment`` key | ||
| * importing plan importing plan ... | ||
| * ``provision[].environment`` | ||
| * ``$TMT_PLAN_ENVIRONMENT_FILE`` | ||
| * command-line input: | ||
| * ``tmt run`` | ||
| * run environment saved in the workdir (``--environment-file`` and ``--environment`` from previous invocations) | ||
| * ``tmt run --environment-file`` | ||
| * ``tmt run --environment`` | ||
| * ``tmt * export`` | ||
| * ``tmt * export --environment-file`` | ||
| * ``tmt * export --environment`` | ||
| * ``tmt try`` | ||
| * ``tmt try --environment-file`` | ||
| * ``tmt try --environment`` | ||
| * plugin intrinsic variables | ||
| * abort context | ||
| * reboot context | ||
| * restart context | ||
| * pidfile context | ||
| * restraint context | ||
| * test framework | ||
| * plan intrinsic variables: ``TMT_VERSION``, ``TMT_TREE``, ... | ||
| * ... | ||
|
|
||
| .. todo:: | ||
|
|
||
| .. code-block:: | ||
|
|
||
| # Asorted list of environment sources | ||
|
|
||
| External sources | ||
| run: --environment and --environment-file CLI options | ||
| plan: environment and environment-file fmf keys | ||
| importing plan: environment fmf key of the importing plan | ||
| provision phases ("per-guest environment"): environment fmf key, --environment CLI option | ||
| test: environment fmf key | ||
|
|
||
| Internal sources | ||
| ~~plugin action itself - test name, test data, plan data, ...~~ | ||
| ~~test framework~~ | ||
| ~~invocation contexts - reboot, restart, abort, pidfile, restraint, ...~~ | ||
|
|
||
| .. todo:: | ||
|
|
||
| Plan environment is actually dumped into test environment, so | ||
| it apparently overrides the test environment. In any case, it should | ||
| be added explicitly into the final environment, not sneaked into via | ||
| test. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # (tmt/steps/discover/__init__.py) | ||
|
|
||
| # Update test environment with plan environment | ||
| test.environment.update(self.plan.environment) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should just drop this and do the expansion at the caller or property to see the exact order being used. This being done at the discover level? would indicate that the later step environments are not updated? I believe that's not the case since
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In any case, it's much harder to control and follow. A plan environment being injected into test environment so early means it's there, forever, and from this moment there is no "plan environment" but only "test environment". I believe this needs to go, "plan environment" needs to be added in the correct order where the command environment is composed from components ( |
||
|
|
||
| "Plan environment" consistst of multiple sources, in this order: | ||
|
|
||
| * plan environment file, ``$TMT_PLAN_ENVIRONMENT_FILE`` | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is a rather special case because it is being written on the guest. Let me verify the logic, after a PrepareShell step the plan data is synced back so any changes to But then what happens in the multi guest case? Isn't the plan data still shared between all guests?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The puzzlement comes from the fact you speak about "plan data", I'm afraid we need to be more precise as there is so many of different inputs, and "plan environment" can mean a lot of them. Yes, a test invoked on multiple guests shares some portion of environment: from run, from plan's keys, from test keys, from the importing plan. They also share the intrinsic bits -
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
By plan data there, I mean the
So when doing
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Hmmm, good point - I don't know the answer. In theory, a plan may put different content into this file on different guests, but do they share the same path on the runner when fetched from guests? This might be a bug.
Indeed, I'm no longer sure they do not share plan environment file content. Maybe they do, and maybe they should not. Added a TODO item to the PR description. |
||
| * plan ``environment-file`` key (```plan: environment and environment-file fmf keys`` source) | ||
| * plan ``environment`` key (```plan: environment and environment-file fmf keys`` source) | ||
| * importing plan "native" environment (``importing plan: environment fmf key of the importing plan`` source) | ||
| * ``environment-file`` key | ||
| * ``environment`` key | ||
| * importing plan's "native" environment | ||
| * run ``--environment`` option (``run: --environment and --environment-file CLI options`` source) | ||
| * run ``--environment-file`` option (``run: --environment and --environment-file CLI options`` source) | ||
| * run ``environment`` property (seems to be the duplication of the previous two inputs) | ||
| * plan intrinsic variables: ``TMT_VERSION``, ``TMT_TREE``, ... | ||
|
|
||
| .. todo:: | ||
|
|
||
| ``TMT_SOURCE_DIR`` is added to test environment: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # (tmt/steps/discover/fmf.py) | ||
|
|
||
| for test in self._tests: | ||
| test.environment['TMT_SOURCE_DIR'] = EnvVarValue(sourcedir) | ||
|
|
||
| # (tmt/steps/discover/shell.py) | ||
|
|
||
| if self.data.dist_git_source: | ||
| test.environment['TMT_SOURCE_DIR'] = EnvVarValue(sourcedir) | ||
|
|
||
| .. todo:: | ||
|
|
||
| Document order of precedence for ``environment`` key and | ||
| ``environment`` CLI option in case of ``provision`` phases | ||
|
|
||
| .. todo:: | ||
|
|
||
| Send out an announcement. | ||
|
|
||
| .. important:: | ||
|
|
||
| The following is the draft of how things should be. It is incomplete, | ||
| and it does contain several notes, but this is what would document | ||
| the precedence. | ||
|
|
||
| Listing environment variable sources in their order of precedence, from | ||
| the least preferred to the strongest ones. | ||
|
|
||
| 1. User-provided guest-specific environment | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| As set via :ref:`environment </plugins/provision/common-keys>` key of | ||
| individual ``provision`` phases. Applies to user commands executed on | ||
| the given guest. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about when used in ansible plugin? That one does not include these right? And similarly for all guestless step/plugins right?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct, to reflect the current state it should be rather "Should apply to user commands executed on the given guest". |
||
|
|
||
| .. todo:: | ||
|
|
||
| "Applies" is a strong word, we need to fix plugins that do not do | ||
| this but should, like ``shell`` - and document those that will not | ||
| expose the environment, like ``ansible``. | ||
|
|
||
| 2. User-provided test-specific environment | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| As set via :ref:`environment </spec/tests/environment>` key of individual | ||
| tests. | ||
|
|
||
| X. User-provided plan-specific environment | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| .. todo:: | ||
|
|
||
| Plan environment consists of several inputs, and it is injected into | ||
| individual test environment mappings, efefctively placing all of them | ||
| there with on this level. | ||
|
|
||
| Last. Variables set by tmt, run, plan, steps, and plugins | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| These are the strongest sources, always overriding any preexisting | ||
| variables. | ||
|
|
||
| .. note:: | ||
|
|
||
| The variables here are not ordered by their order of precedence, as | ||
| they do appear sharing the same level to the user code. Individual | ||
| sources contribute their distinct subsets of variables. | ||
|
|
||
| * For all steps | ||
| * ``TMT_TREE`` | ||
| * ``TMT_PLAN_DATA`` | ||
| * ``TMT_PLAN_ENVIRONMENT_FILE`` | ||
| * ``TMT_VERSION`` | ||
|
|
||
| * For the ``discover`` step | ||
| * ``TMT_SOURCE_DIR`` (note: very fishy way of setting it by injecting into ``Test.environment``) | ||
|
|
||
| * For the ``execute`` step | ||
| * ``TMT_TEST_NAME`` | ||
| * ``TMT_TEST_INVOCATION_PATH`` | ||
| * ``TMT_TEST_SUBMITTED_FILES`` | ||
| * ``TMT_TEST_DATA`` | ||
| * ``TMT_TEST_SERIAL_NUMBER`` | ||
| * ``TMT_TEST_ITERATION_ID`` | ||
| * ``TMT_TEST_METADATA`` | ||
| * ``TMT_RESTRAINT_COMPATIBLE`` (note: extend scope to ``prepare|execute|finish``) | ||
| * ``RSTRNT_TASKNAME`` (note: extend scope to ``prepare|execute|finish``) | ||
|
|
||
| * For the ``execute`` step with the ``beakerlib`` framework | ||
| * ``BEAKERLIB_DIR`` | ||
| * ``BEAKERLIB_COMMAND_SUBMIT_LOG`` | ||
| * ``BEAKERLIB_COMMAND_REPORT_RESULT`` | ||
| * ``TESTID`` | ||
|
|
||
| * For the ``execute/upgrade`` phase | ||
| * ``IN_PLACE_UPGRADE`` | ||
|
|
||
| * For the ``prepare``, ``execute``, and ``finish`` step | ||
| * ``TMT_REBOOT_REQUEST`` | ||
| * ``TMT_REBOOT_COUNT`` | ||
| * ``REBOOTCOUNT`` | ||
| * ``RSTRNT_REBOOTCOUNT`` | ||
| * ``TMT_TEST_RESTART_COUNT`` | ||
| * ``TMT_TOPOLOGY_BASH`` | ||
| * ``TMT_TOPOLOGY_YAML`` | ||
| * ``TMT_TEST_PIDFILE`` | ||
| * ``TMT_TEST_PIDFILE_LOCK`` | ||
| * ``TMT_TEST_PIDFILE_ROOT`` | ||
|
|
||
| * For the ``prepare/shell`` and ``finish/shell`` phases | ||
| * ``TMT_PREPARE_SHELL_URL_REPOSITORY`` | ||
| * ``TMT_FINISH_SHELL_URL_REPOSITORY`` | ||
|
|
||
|
|
||
| Consumed by tmt itself | ||
| ~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. note:: | ||
|
|
||
| The following environment variables are set for and consumed by tmt | ||
| process itself, and never propagated to user environment. | ||
|
|
||
| * ``TMT_DEBUG`` | ||
| * ``TMT_PLUGINS`` | ||
| * ``TMT_FEELING_SAFE`` | ||
| * ``TMT_CONFIG_DIR`` | ||
| * ``TMT_WORKDIR_ROOT`` | ||
| * ``NO_COLOR`` | ||
| * ``TMT_NO_COLOR`` | ||
| * ``TMT_FORCE_COLOR`` | ||
| * ``TMT_SHOW_TRACEBACK`` | ||
| * ``TMT_OUTPUT_WIDTH`` | ||
| * ``TMT_GIT_CREDENTIALS_URL_<suffix>`` | ||
| * ``TMT_GIT_CREDENTIALS_VALUE_<suffix>`` | ||
| * ``TMT_GIT_CLONE_ATTEMPTS`` | ||
| * ``TMT_GIT_CLONE_INTERVAL`` | ||
| * ``TMT_GIT_CLONE_TIMEOUT`` | ||
| * ``TMT_BOOT_TIMEOUT`` | ||
| * ``TMT_CONNECT_TIMEOUT`` | ||
| * ``TMT_REBOOT_TIMEOUT`` | ||
| * ``TMT_SCRIPTS_DIR`` | ||
| * ``TMT_SSH_*`` | ||
| * ``TMT_REPORT_ARTIFACTS_URL`` | ||
| * ``TMT_POLICY_FILE`` | ||
| * ``TMT_POLICY_NAME`` | ||
| * ``TMT_POLICY_ROOT`` | ||
| * ``TMT_PLUGIN_${STEP}_${PLUGIN}_${OPTION}`` | ||
|
LecrisUT marked this conversation as resolved.
|
||
Uh oh!
There was an error while loading. Please reload this page.