|
| 1 | +.. _EESSI: |
| 2 | + |
| 3 | +Adding Environment Modules support to EESSI |
| 4 | +=========================================== |
| 5 | + |
| 6 | +The `European Environment for Scientific Software Installations`_ (EESSI) is |
| 7 | +a collaboration among European HPC centres and industry partners aiming to |
| 8 | +provide a common, optimized stack of scientific software installations usable |
| 9 | +across diverse systems (HPC clusters, workstations, cloud) regardless of |
| 10 | +Linux distribution or CPU architecture |
| 11 | + |
| 12 | +This document analyzes the EESSI framework to determine how it can be adapted |
| 13 | +to support the Environment Modules tool alongside the existing Lmod support. |
| 14 | + |
| 15 | +.. _European Environment for Scientific Software Installations: https://www.eessi.io |
| 16 | + |
| 17 | +Providing equivalent functionality |
| 18 | +---------------------------------- |
| 19 | + |
| 20 | +Here we analyze the content of the EESSI CVMFS repository to find the files |
| 21 | +that are specific to Lmod and define how they should be ported to provide the |
| 22 | +same functionality with Environment Modules. |
| 23 | + |
| 24 | +Files not mentioned here, like ``init/lmod_eessi_archdetect_wrapper.sh``, do |
| 25 | +not need to be adapted to get used in an Environment Modules context. |
| 26 | + |
| 27 | +.. _EESSI Lua module: |
| 28 | + |
| 29 | +``init/modules/EESSI/2025.06.lua`` module |
| 30 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 31 | + |
| 32 | +This Lua modulefile requires a corresponding Tcl version for Environment |
| 33 | +Modules to interpret it. Below are the commands to use when creating the |
| 34 | +equivalent Tcl modulefile to ensure the same functionality: |
| 35 | + |
| 36 | +* ``report`` procedure is equivalent to ``LmodMessage`` |
| 37 | +* ``error`` command is equivalent to ``LmodError`` |
| 38 | +* ``module-help`` (v5.6+) is equivalent to ``help`` (if version below 5.6 is |
| 39 | + expected, define a ``ModulesHelp`` procedure) |
| 40 | + |
| 41 | +A ``.modulerc`` file will be needed to define the ``sticky`` tag onto EESSI |
| 42 | +module. |
| 43 | + |
| 44 | +.. _EESSI bash script: |
| 45 | + |
| 46 | +``init/bash`` script |
| 47 | +^^^^^^^^^^^^^^^^^^^^ |
| 48 | + |
| 49 | +Among other things this script sources module tool initialization script, then |
| 50 | +use the ``module`` command to setup environment. |
| 51 | + |
| 52 | +The only adaptation required is to source the Environment Modules |
| 53 | +initialization script if this module tool is selected. |
| 54 | + |
| 55 | +.. _EESSI Lmod initialization shell scripts: |
| 56 | + |
| 57 | +``init/lmod/<shell>`` scripts |
| 58 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 59 | + |
| 60 | +This scripts initializes module tool the following way: |
| 61 | + |
| 62 | +* reset ``MODULEPATH`` to only point to EESSI modulepath |
| 63 | +* source module tool initialization script |
| 64 | +* if initialization has not been performed yet: |
| 65 | + |
| 66 | + * it load default modules defined externally in |
| 67 | + ``LMOD_SYSTEM_DEFAULT_MODULES`` or load ``EESSI/$EESSI_VERSION`` |
| 68 | + * define this as the initial environment |
| 69 | + |
| 70 | +* otherwise, module tool refresh shell alias and functions in currently loaded |
| 71 | + modules |
| 72 | + |
| 73 | +Sourcing Environment Modules initialization script will setup the initial |
| 74 | +environment defined in its ``initrc`` configuration script unless either the |
| 75 | +``MODULEPATH`` or ``LOADEDMODULES`` environment variables are non-empty. |
| 76 | + |
| 77 | +Here the idea is to unset ``MODULEPATH`` and ``LOADEDMODULES`` to be able to |
| 78 | +initialize EESSI environment with the content of ``initrc``. With such |
| 79 | +strategy, environment definition is only defined in ``initrc`` and not in |
| 80 | +every shell initialization script. |
| 81 | + |
| 82 | +.. code-block:: tcl |
| 83 | +
|
| 84 | + #%Module |
| 85 | + if {[string length [getenv EESSI_SITE_MODULEPATH]]} { |
| 86 | + module use --append [getenv EESSI_SITE_MODULEPATH] |
| 87 | + } |
| 88 | + module use --append [getenv EESSI_MODULEPATH] |
| 89 | + module load EESSI/$EESSI_VERSION |
| 90 | +
|
| 91 | +Before unsetting ``LOADEDMODULES``, it is important to purge any eventually |
| 92 | +loaded modules, including sticky modules. If such command fails, because for |
| 93 | +instance ``module`` command is not defined, it should not disturb the script. |
| 94 | + |
| 95 | +The initialization script could look like to setup EESSI environment with |
| 96 | +Environment Modules: |
| 97 | + |
| 98 | +.. code-block:: sh |
| 99 | +
|
| 100 | + if [ -z "$__Init_Default_Modules" ]; then |
| 101 | + export __Init_Default_Modules=1; |
| 102 | +
|
| 103 | + # unset pre-existing module environment |
| 104 | + module purge --force --no-redirect 2>/dev/null || true |
| 105 | + unset MODULEPATH |
| 106 | + unset LOADEDMODULES |
| 107 | + fi |
| 108 | +
|
| 109 | + # Choose an EESSI CVMFS repository |
| 110 | + EESSI_CVMFS_REPO="${EESSI_CVMFS_REPO:-/cvmfs/software.eessi.io}" |
| 111 | + # Choose an EESSI version |
| 112 | + EESSI_VERSION_DEFAULT="2025.06" |
| 113 | + EESSI_VERSION="${EESSI_VERSION:-${EESSI_VERSION_DEFAULT}}" |
| 114 | + export EESSI_MODULEPATH="${EESSI_CVMFS_REPO}/versions/${EESSI_VERSION}/init/modules" |
| 115 | + . "${EESSI_CVMFS_REPO}/versions/${EESSI_VERSION}/compat/linux/$(uname -m)/usr/share/Modules/init/bash" |
| 116 | +
|
| 117 | +The ``module refresh`` part could be omitted as Environment Modules |
| 118 | +initialization process already performs a refresh if an environment is found |
| 119 | +set. |
| 120 | + |
| 121 | +``init/Magic_Castle/bash`` script |
| 122 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 123 | + |
| 124 | +This script is similar to `EESSI Lmod initialization shell scripts`_ described |
| 125 | +above and the same adaptation strategy could be applied here. |
| 126 | + |
| 127 | +``$EESSI_SOFTWARE_PATH/modules`` modulepaths |
| 128 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 129 | + |
| 130 | +These modulepaths contains Lua modulefiles. Environment Modules only supports |
| 131 | +modulefiles written in Tcl language. Thus Tcl modulefiles are needed in EESSI |
| 132 | +in addition to Lua modulefiles. |
| 133 | + |
| 134 | +The features used in Lua modulefiles are also available in Tcl modulefiles, |
| 135 | +thus if Tcl modulefiles are generated by EasyBuild in EESSI repository, they |
| 136 | +will provide the same functionalities than those provided by Lua modulefiles. |
| 137 | + |
| 138 | +``$EESSI_SOFTWARE_PATH/.lmod/lmodrc.lua`` config file |
| 139 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 140 | + |
| 141 | +``lmodrc.lua`` config file, pointed by ``LMOD_RC`` environment variable is |
| 142 | +only used to define location of module cache data. |
| 143 | + |
| 144 | +Environment Modules does not require such file as cache information is |
| 145 | +always stored at the root of each modulepath. Just build the cache files with |
| 146 | +``module cachebuild`` command in a session where the EESSI modulepaths are |
| 147 | +enabled. |
| 148 | + |
| 149 | +As a consequence ``LMOD_RC`` and ``LMOD_CONFIG_DIR`` environment variable |
| 150 | +should not be ported to Environment Modules. |
| 151 | + |
| 152 | +``$EESSI_SOFTWARE_PATH/.lmod/SitePackage.lua`` config file |
| 153 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 154 | + |
| 155 | +This ``SitePackage.lua`` config file has 3 purposes: |
| 156 | + |
| 157 | +* Define a Lmod ``load`` hook through ``eessi_load_hook`` function |
| 158 | +* Define a Lmod ``isVisible`` hook through ``hide_2022b_modules`` function |
| 159 | +* Call ``load_site_specific_hooks`` function that sources additional |
| 160 | + site-specific ``SitePackage.lua`` files if they exist |
| 161 | + |
| 162 | +The ``load`` hook is used to: |
| 163 | + |
| 164 | +* Print warning message when loading specific module to advice to use other |
| 165 | + version of this module: such warning can be defined in modulepath-specific |
| 166 | + ``.modulerc`` file with the ``module-warn`` command introduced in |
| 167 | + Environment Modules version 5.6. |
| 168 | +* Breaking load of specific module if some files are not found: Environment |
| 169 | + Modules can achieve the same functionality in modulepath-specific |
| 170 | + ``.modulerc`` file with the ``module-forbid`` command. The local files check |
| 171 | + will be performed on any ``module`` command but these forbidden modules will |
| 172 | + be seen already on a ``module avail``. |
| 173 | + |
| 174 | +The ``isVisible`` hook is used to hide modules coming from the ``2022b`` or |
| 175 | +``12.2.0`` toolchains. Environment Modules can achieve the same functionality |
| 176 | +with a modulepath-specific ``.modulerc`` file that calls ``module-hide`` |
| 177 | +command for each of these modules. The full module name and version should be |
| 178 | +used, not a regular expression or a glob pattern. Thus it is advised to |
| 179 | +generate the ``.modulerc`` file after looking at the existing modulefiles in |
| 180 | +modulepath directory. |
| 181 | + |
| 182 | +To provide the same functionality than the ``load_site_specific_hooks`` |
| 183 | +function, a ``siteconfig.tcl`` config file will be needed that will load |
| 184 | +additional site-specific ``siteconfig.tcl`` files if they exist. The |
| 185 | +``source`` Tcl command should be called from ``siteconfig.tcl`` main context |
| 186 | +to load these files. |
| 187 | + |
| 188 | +The main ``siteconfig.tcl`` file should be placed in a central location within |
| 189 | +the EESSI repository and each Environment Modules installation should point to |
| 190 | +it via a symbolic link. No ``LMOD_PACKAGE_PATH`` environment variable should |
| 191 | +be ported to Environment Modules. |
| 192 | + |
| 193 | +Branching depending on chosen module tool |
| 194 | +----------------------------------------- |
| 195 | + |
| 196 | +EESSI project provides to users two ways to initialize. The following sections |
| 197 | +suggest adaptations to these initialization methods to also support |
| 198 | +Environment Modules. |
| 199 | + |
| 200 | +Loading an EESSI environment module |
| 201 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 202 | + |
| 203 | +Provide EESSI Environment Modules initialization shell scripts like `EESSI |
| 204 | +Lmod initialization shell scripts`_ in a ``init/envmodules`` directory (as |
| 205 | +``init/modules`` directory already exists for another purpose). |
| 206 | + |
| 207 | +Create a Tcl counterpart for `EESSI Lua module`_. Such Tcl modulefile can be |
| 208 | +stored in the same directory as the Lua modulefile: when evaluating the |
| 209 | +``EESSI/2025.06`` module, Lmod will interpret the ``EESSI/2025.06.lua`` file |
| 210 | +and Environment Modules the ``EESSI/2025.06`` file. |
| 211 | + |
| 212 | +The ``.modulerc`` file needed in this directory by Environment Modules to |
| 213 | +eventually set the ``EESSI`` module sticky should use code to avoid Lmod to |
| 214 | +parse it (as Lmod does not know the ``module-tag`` modulefile command): |
| 215 | + |
| 216 | +.. code-block:: tcl |
| 217 | +
|
| 218 | + #%Module |
| 219 | + if {![info exists ::env(LMOD_VERSION_MAJOR)]} { |
| 220 | + if {[info exists ::env(EESSI_MODULE_STICKY)]} { |
| 221 | + module-tag sticky EESSI |
| 222 | + } |
| 223 | + } |
| 224 | +
|
| 225 | +Sourcing the EESSI ``bash`` initialization script |
| 226 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 227 | + |
| 228 | +Introduce the ``EESSI_MODULE_TOOL`` environment variable that branches to: |
| 229 | + |
| 230 | +* *Environment Modules* if variable is set to ``EnvironmentModules`` |
| 231 | +* *Lmod* if variable is not set or if set to ``Lmod`` |
| 232 | + |
| 233 | +Use this ``EESSI_MODULE_TOOL`` environment variable in `EESSI bash script`_ to |
| 234 | +determine the correct module tool initialization script to source. |
| 235 | + |
| 236 | +.. code-block:: sh |
| 237 | +
|
| 238 | + case "${EESSI_MODULE_TOOL:-Lmod}" in |
| 239 | + Lmod) source $EESSI_EPREFIX/usr/share/Lmod/init/bash ;; |
| 240 | + EnvironmentModules) source $EESSI_EPREFIX/usr/share/Modules/init/bash ;; |
| 241 | + *) error "Module tool '$EESSI_MODULE_TOOL' is not supported" ;; |
| 242 | + esac |
| 243 | +
|
| 244 | +Such adaptation helps to keep a single ``bash`` initialization script whatever |
| 245 | +the module tool used. |
| 246 | + |
| 247 | +.. vim:set tabstop=2 shiftwidth=2 expandtab autoindent: |
0 commit comments