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

refactor generation of required environment variables in module files + deprecate make_module_req_guess method in EasyBlock class #4653

Open
wants to merge 38 commits into
base: 5.0.x
Choose a base branch
from

Conversation

lexming
Copy link
Contributor

@lexming lexming commented Sep 23, 2024

Goal is to lay groundwork to be able to fix #3331 and add new option to control which search path variables are added in modules by simplifying the code injecting environment variables to module files.

This PR should not alter the resulting module files to what is currently generated by EB. If it changes the list of environment variables it should have no effect (e.g. because those paths are empty).

Simplification of logic handling environment variables for module files:

  1. replace obscure rules defining which search paths require populated dirs with:
  2. replace obscure rules defining which search paths require files in their top level directory with:
    • by default all search paths to directories can be populated at any level (recursive check)
    • this setting is now controlled by top_level_file attribute of ModuleEnvironmentVariable
  3. replace convoluted rules to handle symlinked lib64 that generate duplicate paths and need explicit exceptions with:
    • paths to lib64 are always ignored if lib64 is a symlink to lib
    • paths to lib are always ignored if lib is a symlink to lib64
    • remove lib32 from list of library search paths
  4. allow simple updates of environment variables in child EasyBlocks, replacing the clunky:
    def make_module_req_guess(self):
        guesses = super(EB_Clang, self).make_module_req_guess()
        guesses.update({'SOME_VAR': ['some/path]})
        return guesses
    
    with an elegant:
    self.module_load_environment.SOME_VAR = ['some/path']
    

Changelog:

  • add ModuleEnvironmentVariable pseudo-dataclass to easybuild.tools.modules to hold definitions of environment variables for modules
  • add ModuleLoadEnvironment singleton class to easybuild.tools.modules to hold environment definition for modules on load
  • deprecate EasyBlock.make_module_req_guess in favor of ModuleLoadEnvironment
  • add LibSymlink enum to easybuild.framework.easyblock to define possible linkage states of lib directories
  • add install_lib_symlink attribute to EasyBlcok to keep track of symlink status between lib dirs
  • add globals to easybuild.tools.config that define known directories for binaries, libraries and headers
  • avoid changing the current working directory of the main process in easyblock.make_module_req by working with absolute paths instead

@lexming lexming added the EasyBuild-5.0 EasyBuild 5.0 label Sep 23, 2024
@lexming lexming marked this pull request as draft September 23, 2024 14:46
@lexming lexming marked this pull request as ready for review September 24, 2024 06:15
@lexming
Copy link
Contributor Author

lexming commented Sep 24, 2024

@boegel look all the beautiful green tests!

Compared to what I showed on the meeting yesterday, I have undone all changes to make_module_req_guess. So existing easyblocks continue to work without any further changes.

This seems ready on my side. I tested it with several easyblocks that add custom stuff to make_module_req_guess and I have hit no issues so far. Even things like root.py easyblock that set PYTHONPATH in make_module_req_guess instead of the more common make_module_extra do work. If you have anything in mind that I should test in particular let me know.



# singleton metaclass: only one instance is created
BaseModuleEnvironment = create_base_metaclass('BaseModuleEnvironment', Singleton, object)
Copy link
Member

Choose a reason for hiding this comment

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

@lexming Using a singleton here (so a single instance that is shared across all EasyBlock instances) seems like a bad idea to me...

If EasyBuild installs two things in the same session (via --robot, or by being fed multiple easyconfigs on the command line), you'll end up with incorrect stuff in the generated module file due to this, no?

Copy link
Member

Choose a reason for hiding this comment

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

@lexming I've implemented a test that shows that using a singleton here is a bad idea, see lexming#5

add test to verify that environment variables don't leak into module file of subsequent installations
@boegel
Copy link
Member

boegel commented Nov 6, 2024

@lexming Can you look into fixing the merge conflict, and get the test to pass?

@boegel boegel changed the title refactor generation of required environment variables in module files refactor generation of required environment variables in module files + deprecate make_module_req_guess method in EasyBlock class Nov 6, 2024
test/framework/toy_build.py Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Nice-to-have
Development

Successfully merging this pull request may close these issues.

2 participants