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

Fix: Build environments not activated #4665

Merged
merged 8 commits into from
Dec 5, 2022
Merged

Conversation

mbargull
Copy link
Member

@mbargull mbargull commented Dec 3, 2022

Description

In conda-forge/conda-feedstock#181 (comment) we encountered unexpected failures for PyPy variants of the builds with

D:/bld/conda_1669913819035/_h_env/python.exe: error while loading shared libraries: libpypy3.9-c.dll: cannot open shared object file: No such file or directory

It turned out, this happened because the build environments were not activated at all.
The correct Python interpreter was launched because the build script used $PYTHON.
The CPython variants built fine "by chance" only since our CPython builds carry library lookup patches to also function without an activated environment and other programs needed for the build were already on PATH from outside the build environment.

This happened due to a regression caused by cecb031 .
Previously, conda's memoized bailed out from caching anything because of the additionally passed non-hashable dict.
Memoizing with a MetaData instance as a key is problematic since that object/its members are highly mutable during conda-build's work.

The actual fix in commit 7f047c7 just removes the memoization.
I also added two guards to avoid regressions:

  1. Make MetaData non-hashable in 9fd7165.
  2. Add a test in 9fde4c1 + 060f10f to check if the prefixes are added to PATH as expected.

Note that the added test did not replicate the behavior from the conda-forge build entirely.
During the test runs, the prefixes were only added in a wrong order (possibly due to merged build/host at the time of memoization) but they were not completely omitted like in the conda-feedstock build.
These subtleties can be expected due to different setups and different times of memoization.
It is also likely that the early memoization changed other parts of the builds; changes to PATH were just most visible.


This PR also adds PREFIX/bin to PATH on Windows and removes PREFIX root from PATH on Unix.
Those were two bugs I noticed broke the added test case.
Fixing that should be non-controversial without any downsides, really (those are plain bugs anyway).

Checklist - did you ...

  • Add a file to the news directory (using the template) for the next release's release notes?
  • Add / update necessary tests?
  • Add / update outdated documentation?

@conda-bot conda-bot added the cla-signed [bot] added once the contributor has signed the CLA label Dec 3, 2022
Its members are very dynamic so it is problematic to use it for cached
calculations.
Needed to set .activate=True on the MetaData's own .config
@mbargull mbargull marked this pull request as ready for review December 3, 2022 23:36
@mbargull
Copy link
Member Author

mbargull commented Dec 3, 2022

I updated the OP with explanations for what happened and how this is mitigated.

cc @jezdez, @kenodegard
Another quick patch release would be highly appreciated since this is actually a severe issue with many unknowns in what parts under which build configurations it impacts.

@mbargull mbargull marked this pull request as draft December 4, 2022 09:28
- Prefix "bin" directory get added on all platforms
- Prefix root directory should only be added on Windows
@mbargull mbargull force-pushed the fix-activation-path branch from 36133a6 to 998597c Compare December 4, 2022 11:14
@mbargull mbargull marked this pull request as ready for review December 4, 2022 11:14
Comment on lines +2587 to +2591
# TODO: Prepending the prefixes here should probably be guarded by
# if not m.activate_build_script:
# Leaving it as is, for now, since we need a quick, non-disruptive patch release.
with utils.path_prepended(m.config.host_prefix, False):
with utils.path_prepended(m.config.build_prefix, False):
Copy link
Member Author

Choose a reason for hiding this comment

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

Before removing this in a future release, we should add more test cases.
The test added in this PR only checks for the case when there is build+host, activate=True and no outputs.
Other configurations that should be tested:

  • activate=False
  • build and host merged
    • with activate=True
    • with activate=False
  • recipes with outputs
    • and those for potential combinations of the aforementioned other cases.

I consider this out of scope for this PR since we should put out a patch release quickly and because those other cases touch other issues like #3993 -- that's another can of worms (one we should take care of, but not hastily in a small patch release).

@@ -950,11 +950,10 @@ def get_build_folders(croot):


def prepend_bin_path(env, prefix, prepend_prefix=False):
# bin_dirname takes care of bin on *nix, Scripts on win
env['PATH'] = join(prefix, bin_dirname) + os.pathsep + env['PATH']
env['PATH'] = join(prefix, "bin") + os.pathsep + env['PATH']
Copy link
Member Author

Choose a reason for hiding this comment

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

conda activate always adds "bin" to PATH. We have to have it here too. The addition of "Scripts" is taken care of a few lines below.

Comment on lines +987 to +990
def path_prepended(prefix, prepend_prefix=True):
# FIXME: Unclear why prepend_prefix=True for all platforms.
old_path = os.environ['PATH']
os.environ['PATH'] = prepend_bin_path(os.environ.copy(), prefix, True)['PATH']
os.environ['PATH'] = prepend_bin_path(os.environ.copy(), prefix, prepend_prefix)['PATH']
Copy link
Member Author

Choose a reason for hiding this comment

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

No idea why this is prepend_prefix=True for all platforms.
For now, I left it that way and only changed it to False in build.write_build_scripts where I needed it.
I did not look at the other places where path_prepended is used. For me, this is also out of scope for this PR, but I'd like us to fix it, hence the added FIXME-note.

Comment on lines +1673 to +1674
# And apparently here the previously added build env gets deactivated
# from the activation hook, hence only host is on PATH twice.
Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe CONDA_SHLVL is not reset for Windows builds? IDK. I didn't check since debugging for Windows is rather time-consuming on my end.
This can be investigated later; not something we have to do in this PR.

@mbargull
Copy link
Member Author

mbargull commented Dec 4, 2022

This PR also adds PREFIX/bin to PATH on Windows and removes PREFIX root from PATH on Unix.
Those were two bugs I noticed broke the added test case.
Fixing that should be non-controversial without any downsides, really (those are plain bugs anyway).

Copy link
Contributor

@travishathaway travishathaway left a comment

Choose a reason for hiding this comment

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

Hi @mbargull

Thanks for this pull request. So far everything looks okay with this pull request, and I will be happy to approve, but I would really appreciate it if you could add a descriptive doc string to your test explaining exactly why it exists and perhaps its shortcomings as you mentioned.

We are trying hard to make sure the tests in conda-build are more maintainable and these simple descriptions are very helpful for future maintainers.

Thank you! ✌️

@mbargull
Copy link
Member Author

mbargull commented Dec 5, 2022

@travishathaway, thanks for the review! Addressed in 1ebe72c .

We are trying hard to make sure the tests in conda-build are more maintainable and these simple descriptions are very helpful for future maintainers.

Glad to hear that process started! 😸

Copy link
Contributor

@dholth dholth left a comment

Choose a reason for hiding this comment

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

LGTM

@dbast
Copy link
Member

dbast commented Dec 5, 2022

@travishathaway I don't mind doc strings in test cases... more important for me: test cases follow a given/when/then or setup/run-subject-under-test/compare-outcome structure (which is given here), which often makes the code self explanatory beyond to what can described in english via doctsrings.

@dbast dbast closed this Dec 5, 2022
@dbast dbast reopened this Dec 5, 2022
@mbargull
Copy link
Member Author

mbargull commented Dec 5, 2022

Failure in Tests / linux (3.9, canary, parallel) is unrelated...

... but it's still odd, since after
1053650#diff-e52e4ddd58b7ef887ab03c04116e676f6280b824ab7469d5d3080e5cba4f2128R126-R144
we shouldn't see /usr/share/miniconda/envs/test/conda-bld/work used in these kinds of tests anymore...
Something about the fixture/its "autouse" doesn't seem to work properly sigh...

=================================== FAILURES ===================================
__________________ test_no_satisfiable_variants_raises_error ___________________
[gw0] linux -- Python 3.9.15 /usr/share/miniconda/envs/test/bin/python
Traceback (most recent call last):
  File "/usr/share/miniconda/envs/test/lib/python3.9/shutil.py", line 825, in move
    os.rename(src, real_dst)
FileNotFoundError: [Errno 2] No such file or directory: '/usr/share/miniconda/envs/test/conda-bld/work' -> '/usr/share/miniconda/envs/test/conda-bld/abc_1670250124813/work'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/runner/work/conda-build/conda-build/tests/test_variants.py", line 106, in test_no_satisfiable_variants_raises_error
    api.render(recipe, permit_unsatisfiable_variants=True)
  File "/home/runner/work/conda-build/conda-build/conda_build/api.py", line 38, in render
    metadata_tuples = render_recipe(recipe_path, bypass_env_check=bypass_env_check,
  File "/home/runner/work/conda-build/conda-build/conda_build/render.py", line 827, in render_recipe
    m.config.compute_build_id(m.name(), m.version(), reset=reset_build_id)
  File "/home/runner/work/conda-build/conda-build/conda_build/config.py", line 615, in compute_build_id
    shutil.move(old_dir, work_dir)
  File "/usr/share/miniconda/envs/test/lib/python3.9/shutil.py", line 845, in move
    copy_function(src, real_dst)
  File "/usr/share/miniconda/envs/test/lib/python3.9/shutil.py", line 444, in copy2
    copyfile(src, dst, follow_symlinks=follow_symlinks)
  File "/usr/share/miniconda/envs/test/lib/python3.9/shutil.py", line 264, in copyfile
    with open(src, 'rb') as fsrc:
FileNotFoundError: [Errno 2] No such file or directory: '/usr/share/miniconda/envs/test/conda-bld/work'

@mbargull mbargull mentioned this pull request Dec 5, 2022
3 tasks
@dbast dbast merged commit 7e9d123 into conda:main Dec 5, 2022
@jakirkham
Copy link
Member

It sounds like we would like to capture this in a patch release of conda-build (like 3.23.3). Is that something that could be started?

@jezdez
Copy link
Member

jezdez commented Dec 6, 2022

Yes

@github-actions github-actions bot added the locked [bot] locked due to inactivity label Dec 7, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla-signed [bot] added once the contributor has signed the CLA locked [bot] locked due to inactivity
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

7 participants