-
Notifications
You must be signed in to change notification settings - Fork 211
Proposed changes to make EasyBuild plugin-able through entrypoints #4918
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: develop
Are you sure you want to change the base?
Conversation
9d3321c
to
c21684c
Compare
I only took a (very) quick look at this, but couple of questions:
Other random thoughts:
|
72d2804
to
35e1919
Compare
This is what I've implemented as a demo as it was probably the easiest features, but i think several other features could also be done through plugins. A few ideas:
I think several features could be implemented, requiring varying degree of effort
Will work on it
Added a guard for it. It was also needed to pass the CI (still need a more robust way as the
Yes they coexist, bot for easyblocks and toolchains I've modified the functions that get them to include the one coming from entrypoints after the ones already picked up by easybuild.
|
1fabe4c
to
f8f63d9
Compare
…tlib.metadata` in old python
5e3953c
to
b0aeb73
Compare
0e0cc87
to
46af0e9
Compare
- Added listing of entrypoints available through `--show-config` - Enhanced test cases
The errors in the 3.7 CI seems to be of the kind
or
do not think it is related to this PR |
What it looks likeUsing the test repo from https://github.com/Crivella/test_eb_ep Running an ECEasyconfigcrivella@crivella-desktop:~$ workon easybuild-dev
(easybuild-dev) crivella@crivella-desktop:~$ cd test/easyconfigs/
(easybuild-dev) crivella@crivella-desktop:~/test/easyconfigs$ cat test_test.eb
easyblock = 'TestEasyBlock'
name = 'test_eps'
version = '1.0.0'
homepage = 'https://localhost:8000'
description = """TEST"""
toolchain = {'name': 'gompi', 'version': '2024a'}
dependencies = [
]
osdependencies = []
sources = []
checksums = []
# skipsteps = ['configure', 'build']
# install_cmd = ':'
# files_to_copy = [(['tmpi'], 'bin')]
# sanity_check_paths = {
# 'files': ['],
# 'dirs': [],
# }
moduleclass = 'debugger' Running without entrypoints(easybuild-dev) crivella@crivella-desktop:~/test/easyconfigs$ eb test_test.eb --installpath=`mktemp -d`
== Temporary log file in case of crash /home/crivella/.local/easybuild/logs/easybuild-b0o3evp8.log
WARNING: Index for /home/crivella/Documents/GIT/easybuild-easyconfigs/easybuild/easyconfigs is no longer valid (too old), so ignoring it...
ERROR: Failed to process easyconfig /home/crivella/test/easyconfigs/test_test.eb: Failed to obtain class for TestEasyBlock
easyblock (not available?): No module named 'easybuild.easyblocks.generic.testeasyblock'
####################################################################
# Show that the package is installed
(easybuild-dev) crivella@crivella-desktop:~/test/easyconfigs$ pip list | grep test
pytest 8.2.1
test_eb_entrypoints 0.1.0 /home/crivella/test/test_eb_ep Running with entrypoints####################################################################
# Rerun with entrypoints
(easybuild-dev) crivella@crivella-desktop:~/test/easyconfigs$ eb test_test.eb --installpath=`mktemp -d` --use-entrypoints
== Temporary log file in case of crash /home/crivella/.local/easybuild/logs/easybuild-u3l0_o3j.log
== Running entry point start hook...
Hello, World! ----------------------------------------
Hello, World! ----------------------------------------
Hello, World! ----------------------------------------
Hello, World! ----------------------------------------
Hello, World! ----------------------------------------
WARNING: Index for /home/crivella/Documents/GIT/easybuild-easyconfigs/easybuild/easyconfigs is no longer valid (too old), so ignoring it...
WARNING: Index for /home/crivella/Documents/GIT/easybuild-easyconfigs/easybuild/easyconfigs is no longer valid (too old), so ignoring it...
== processing EasyBuild easyconfig /home/crivella/test/easyconfigs/test_test.eb
== building and installing test_eps/1.0.0-gompi-2024a...
>> installation prefix: /tmp/tmp.vfsQsDBt6t/software/test_eps/1.0.0-gompi-2024a
== fetching files and verifying checksums...
== ... (took < 1 sec)
== creating build dir, resetting environment...
>> build dir: /home/crivella/.local/easybuild/build/test_eps/1.0.0/gompi-2024a
== ... (took < 1 sec)
== unpacking...
== ... (took < 1 sec)
== patching...
== ... (took < 1 sec)
== preparing...
>> loading toolchain module: gompi/2024a
>> defining build environment for gompi/2024a toolchain
== ... (took < 1 sec)
== configuring...
== Running entry point configure hook...
test_pre_configure called with args: (<test_eb_entrypoints.easyblock.TestEasyBlock object at 0x7de8329c31d0>,) and kwargs: {}
TestEasyBlock: configure_step called.
== Running entry point configure hook...
test_post_configure called with args: (<test_eb_entrypoints.easyblock.TestEasyBlock object at 0x7de8329c31d0>,) and kwargs: {}
== ... (took < 1 sec)
== building...
TestEasyBlock: build_step called.
== ... (took < 1 sec)
== testing...
== ... (took < 1 sec)
== installing...
TestEasyBlock: install_step called.
== ... (took < 1 sec)
== taking care of extensions...
== ... (took < 1 sec)
== restore after iterating...
== ... (took < 1 sec)
== postprocessing...
== ... (took < 1 sec)
== sanity checking...
TestEasyBlock: sanity_check_step called.
== ... (took < 1 sec)
== cleaning up...
== ... (took < 1 sec)
== creating module...
>> generating module file @ /tmp/tmp.vfsQsDBt6t/modules/all/test_eps/1.0.0-gompi-2024a.lua
== ... (took < 1 sec)
== permissions...
== ... (took < 1 sec)
== packaging...
== ... (took < 1 sec)
== COMPLETED: Installation ended successfully (took 1 secs)
== Results of the build can be found in the log file(s) /tmp/tmp.vfsQsDBt6t/software/test_eps/1.0.0-gompi-2024a/easybuild/easybuild-test_eps-1.0.0-20250619.164447.log
== Build succeeded for 1 out of 1
== Summary:
* [SUCCESS] test_eps/1.0.0-gompi-2024a
== Temporary log file(s) /home/crivella/.local/easybuild/logs/easybuild-u3l0_o3j.log* have been removed.
== Temporary directory /tmp/eb-26gjnn8r has been removed. Docs CLI optionsRuns with:
docs options#####################################################################
# Commands with package installed
(easybuild-dev) crivella@crivella-desktop:~/test/easyconfigs$ eb --show-config
#
# Current EasyBuild configuration
# (C: command line argument, D: default value, E: environment variable, F: configuration file)
#
buildpath (D) = /home/crivella/.local/easybuild/build
containerpath (D) = /home/crivella/.local/easybuild/containers
debug (E) = True
github-user (E) = Crivella
installpath (D) = /home/crivella/.local/easybuild
output-style (E) = no_color
repositorypath (D) = /home/crivella/.local/easybuild/ebfiles_repo
robot-paths (E) = /home/crivella/Documents/GIT/easybuild-easyconfigs/easybuild/easyconfigs, /home/crivella/test/easyconfigs, /home/crivella/test/easyconfigs/LLVMtc
rpath (D) = True
sourcepath (D) = /home/crivella/.local/easybuild/sources
test-report-env-filter (E) = re.compile('^SSH|USER|HOSTNAME|UID|.*COOKIE.*|.*LICENSE.*|.*LICENCE.*|TMUX|NVM|GNOME_|DBUS_')
tmp-logdir (E) = /home/crivella/.local/easybuild/logs
Hooks from entrypoints (3):
- EntrypointHook <test_eb_entrypoints.hooks:test_pre_configure>
- EntrypointHook <test_eb_entrypoints.hooks:hello_world>
- EntrypointHook <test_eb_entrypoints.hooks:test_post_configure>
Easyblocks from entrypoints (1):
- EntrypointEasyblock <test_eb_entrypoints.easyblock:TestEasyBlock>
Toolchains from entrypoints (5):
- EntrypointToolchain <test_eb_entrypoints.unified:Lompi>
- EntrypointToolchain <test_eb_entrypoints.unified:Lolf>
- EntrypointToolchain <test_eb_entrypoints.unified:LLVMtc>
- EntrypointToolchain <test_eb_entrypoints.unified:Lfbf>
- EntrypointToolchain <test_eb_entrypoints.unified:LFoss>
(easybuild-dev) crivella@crivella-desktop:~/test/easyconfigs$ eb --list-easyblocks | grep Test
|-- TestEasyBlock
(easybuild-dev) crivella@crivella-desktop:~/test/easyconfigs$ eb --list-toolchains | grep lfos
lfoss: BLACS, FFTW, FlexiBLAS, LLVMtc, OpenMPI, ScaLAPACK
(easybuild-dev) crivella@crivella-desktop:~/test/easyconfigs$ cd ../test_eb_ep/
(easybuild-dev) crivella@crivella-desktop:~/test/test_eb_ep [main ≡]
#####################################################################
# Uninstall the package
(easybuild-dev) crivella@crivella-desktop:~/test/test_eb_ep [main ≡]
$ pip uninstall test_eb_entrypoints
Found existing installation: test_eb_entrypoints 0.1.0
Uninstalling test_eb_entrypoints-0.1.0:
Would remove:
/home/crivella/.virtualenvs/easybuild-dev/lib/python3.11/site-packages/test_eb_entrypoints-0.1.0.dist-info/*
/home/crivella/.virtualenvs/easybuild-dev/lib/python3.11/site-packages/test_eb_entrypoints.pth
Proceed (Y/n)?
Successfully uninstalled test_eb_entrypoints-0.1.0
#####################################################################
# Commands without package installed
(easybuild-dev) crivella@crivella-desktop:~/test/test_eb_ep [main ≡]
$ eb --show-config
#
# Current EasyBuild configuration
# (C: command line argument, D: default value, E: environment variable, F: configuration file)
#
buildpath (D) = /home/crivella/.local/easybuild/build
containerpath (D) = /home/crivella/.local/easybuild/containers
debug (E) = True
github-user (E) = Crivella
installpath (D) = /home/crivella/.local/easybuild
output-style (E) = no_color
repositorypath (D) = /home/crivella/.local/easybuild/ebfiles_repo
robot-paths (E) = /home/crivella/Documents/GIT/easybuild-easyconfigs/easybuild/easyconfigs, /home/crivella/test/easyconfigs, /home/crivella/test/easyconfigs/LLVMtc
rpath (D) = True
sourcepath (D) = /home/crivella/.local/easybuild/sources
test-report-env-filter (E) = re.compile('^SSH|USER|HOSTNAME|UID|.*COOKIE.*|.*LICENSE.*|.*LICENCE.*|TMUX|NVM|GNOME_|DBUS_')
tmp-logdir (E) = /home/crivella/.local/easybuild/logs
(easybuild-dev) crivella@crivella-desktop:~/test/test_eb_ep [main ≡]
$ eb --list-easyblocks | grep Test
(easybuild-dev) crivella@crivella-desktop:~/test/test_eb_ep [main ≡]
$ eb --list-toolchains | grep lfos |
I like the idea - anything that makes it potentially easier to customise EB is a good thing. |
- Code cleanup - Better function names - Improved tests/comments/docstrints
The proposed changes leverage python EntryPoints to allow injecting new functionalities in easybuild without touching the main repo
For now this is a demo of what could be possible implementing the following:
easybuild.toolchain
entrypoint to inject a toolchain into EasyBuild from a separate python packageeasybuild.easyblock
entrypoint to inject a new easyblock into EasyBuild from a separate python packageeasybuild.hooks
entrypoint to inject new hooks into EasyBuild from a separate python packageFor easier error detection in the plugin package, the new
easybuild.tools.entrypoints
defines severalregisted_XXX
decorators that needs to be used in order to pass the entrypoint validation.An example of a python package that makes use of the proposed functionalities can be found in https://github.com/Crivella/test_eb_ep
Using entrypoints is not enabled by default and requires the
--use-entrypoints
flag to be passed toeb
command.Possible upsides
Possible downsides
TODO
MAYBE
Notes
importlib.metadata
has been part of python only from3.8
before the 3rd partyimportlib-metadata
package would be requireddocs.py
CLI options like--list-easyblocks
--list-toolchains
and--show-config
that are run before the build options are initialized, the default is to assume thatuse_entrypoints
isTrue
. At runtime when the hooks/easyblocks/toolchains need to be injected, this will only be performed if the options is actually set toTrue