Skip to content

Commit e1611cd

Browse files
author
Vasileios Karakasis
authored
Merge pull request #1654 from vkarak/bugfix/lmod-crash-pre-82
[bugfix] Fix module backend implementation for Lmod versions < 8.2
2 parents 4bf3156 + 05957e4 commit e1611cd

File tree

3 files changed

+82
-4
lines changed

3 files changed

+82
-4
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
runs-on: ubuntu-latest
3838
strategy:
3939
matrix:
40-
modules-version: [Lmod, Tmod32, Tmod4]
40+
modules-version: [Lmod, Lmod77, Tmod32, Tmod4]
4141
steps:
4242
- uses: actions/checkout@v2
4343
- name: Build Image for ${{ matrix.modules-version }}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#
2+
# Execute this from the top-level ReFrame source directory
3+
#
4+
5+
#
6+
# LMod versions prior to 8.2 emitted Python commands differently, so we use this
7+
# Dockerfile to test the bindings of older versions
8+
#
9+
10+
11+
FROM ubuntu:20.04
12+
13+
ENV TZ=Europe/Zurich
14+
ENV DEBIAN_FRONTEND=noninteractive
15+
ENV _LMOD_VER=7.7
16+
17+
# ReFrame user
18+
RUN useradd -ms /bin/bash rfmuser
19+
20+
# ReFrame requirements
21+
RUN \
22+
apt-get -y update && \
23+
apt-get -y install ca-certificates && \
24+
update-ca-certificates && \
25+
apt-get -y install gcc && \
26+
apt-get -y install make && \
27+
apt-get -y install git && \
28+
apt-get -y install python3 python3-pip
29+
30+
# Required utilities
31+
RUN apt-get -y install wget
32+
33+
# Install Lmod
34+
RUN \
35+
apt-get -y install lua5.3 lua-bit32:amd64 lua-posix:amd64 lua-posix-dev liblua5.3-0:amd64 liblua5.3-dev:amd64 tcl tcl-dev tcl8.6 tcl8.6-dev:amd64 libtcl8.6:amd64 lua-filesystem:amd64 lua-filesystem-dev:amd64 && \
36+
wget -q https://github.com/TACC/Lmod/archive/${_LMOD_VER}.tar.gz -O lmod.tar.gz && \
37+
tar xzf lmod.tar.gz && \
38+
cd Lmod-${_LMOD_VER} && \
39+
./configure && make install
40+
41+
ENV BASH_ENV=/usr/local/lmod/lmod/init/profile
42+
43+
USER rfmuser
44+
45+
# Install ReFrame from the current directory
46+
COPY --chown=rfmuser . /home/rfmuser/reframe/
47+
48+
WORKDIR /home/rfmuser/reframe
49+
50+
RUN ./bootstrap.sh
51+
52+
CMD ["/bin/bash", "-c", "./test_reframe.py --rfm-user-config=ci-scripts/configs/lmod.py -v"]

reframe/core/modules.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,21 @@ def emit_load_instr(self, module):
492492
def emit_unload_instr(self, module):
493493
'''Emit the instruction that unloads module.'''
494494

495+
def process(self, source):
496+
'''Process the Python source emitted by the Python bindings of the
497+
different backends.
498+
499+
Backends should call this before executing any Python commands.
500+
501+
:arg source: The Python source code to be executed.
502+
:returns: The modified Python source code to be executed. By default
503+
``source`` is returned unchanged.
504+
505+
.. versionadded:: 3.4
506+
507+
'''
508+
return source
509+
495510
def __repr__(self):
496511
return type(self).__name__ + '()'
497512

@@ -562,7 +577,7 @@ def _execute(self, cmd, *args):
562577
completed.stderr,
563578
completed.returncode)
564579

565-
exec(completed.stdout)
580+
exec(self.process(completed.stdout))
566581
return completed.stderr
567582

568583
def available_modules(self, substr):
@@ -692,7 +707,7 @@ def _execute(self, cmd, *args):
692707
with open(exec_match.group(1), 'r') as content_file:
693708
cmd = content_file.read()
694709

695-
exec(cmd)
710+
exec(self.process(cmd))
696711
return completed.stderr
697712

698713

@@ -740,7 +755,7 @@ def _execute(self, cmd, *args):
740755
modulecmd = self.modulecmd(cmd, *args)
741756
completed = osext.run_command(modulecmd, check=False)
742757
namespace = {}
743-
exec(completed.stdout, {}, namespace)
758+
exec(self.process(completed.stdout), {}, namespace)
744759

745760
# _mlstatus is set by the TMod4 only if the command was unsuccessful,
746761
# but Lmod sets it always
@@ -824,6 +839,17 @@ def __init__(self):
824839
def name(self):
825840
return 'lmod'
826841

842+
def process(self, source):
843+
major, minor, *_ = self.version().split('.')
844+
major, minor = int(major), int(minor)
845+
if (major, minor) < (8, 2):
846+
# Older Lmod versions do not emit an `import os` and emit an
847+
# invalid `false` statement in case of errors; we fix these here
848+
return 'import os\n\n' + source.replace('false',
849+
'_mlstatus = False')
850+
851+
return source
852+
827853
def modulecmd(self, *args):
828854
return ' '.join([self._lmod_cmd, 'python', *args])
829855

0 commit comments

Comments
 (0)