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

add check_group support for module files in Tcl syntax #4418

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 14 additions & 7 deletions easybuild/tools/module_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -758,8 +758,18 @@ def check_group(self, group, error_msg=None):
:param group: string with the group name
:param error_msg: error message to print for users outside that group
"""
self.log.warning("Can't generate robust check in TCL modules for users belonging to group %s.", group)
return ''
if self.modules_tool.supports_tcl_check_group:
if error_msg is None:
error_msg = "You are not part of '%s' group of users that have access to this software; " % group
error_msg += "Please consult with user support how to become a member of this group"

error_msg = 'error "%s"' % error_msg
res = self.conditional_statement('module-info usergroups %s' % group, error_msg, negative=True)
else:
self.log.warning("Can't generate robust check in Tcl modules for users belonging to group %s.", group)
res = ''

return res

def comment(self, msg):
"""Return string containing given message as a comment."""
Expand Down Expand Up @@ -1181,10 +1191,7 @@ def check_group(self, group, error_msg=None):
:param group: string with the group name
:param error_msg: error message to print for users outside that group
"""
lmod_version = self.modules_tool.version
min_lmod_version = '6.0.8'

if LooseVersion(lmod_version) >= LooseVersion(min_lmod_version):
if self.modules_tool.supports_lua_check_group:
if error_msg is None:
error_msg = "You are not part of '%s' group of users that have access to this software; " % group
error_msg += "Please consult with user support how to become a member of this group"
Expand All @@ -1194,7 +1201,7 @@ def check_group(self, group, error_msg=None):
else:
warn_msg = "Can't generate robust check in Lua modules for users belonging to group %s. "
warn_msg += "Lmod version not recent enough (%s), should be >= %s"
self.log.warning(warn_msg, group, lmod_version, min_lmod_version)
self.log.warning(warn_msg, group, self.modules_tool.version, self.modules_tool.REQ_VERSION_LUA_CHECK_GROUP)
res = ''

return res
Expand Down
10 changes: 10 additions & 0 deletions easybuild/tools/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ class ModulesTool(object):
VERSION_OPTION = '--version'
# minimal required version (StrictVersion; suffix rc replaced with b (and treated as beta by StrictVersion))
REQ_VERSION = None
# minimal required version to check user's group in modulefile
REQ_VERSION_TCL_CHECK_GROUP = None
REQ_VERSION_LUA_CHECK_GROUP = None
# deprecated version limit (support for versions below this version is deprecated)
DEPR_VERSION = None
# maximum version allowed (StrictVersion; suffix rc replaced with b (and treated as beta by StrictVersion))
Expand Down Expand Up @@ -208,6 +211,8 @@ def __init__(self, mod_paths=None, testing=False):
self.check_module_function(allow_mismatch=build_option('allow_modules_tool_mismatch'))
self.set_and_check_version()
self.supports_depends_on = False
self.supports_lua_check_group = False
self.supports_tcl_check_group = False

def __str__(self):
"""String representation of this ModulesTool instance."""
Expand Down Expand Up @@ -1326,6 +1331,7 @@ class EnvironmentModules(EnvironmentModulesTcl):
COMMAND_ENVIRONMENT = 'MODULES_CMD'
REQ_VERSION = '4.0.0'
MAX_VERSION = None
REQ_VERSION_TCL_CHECK_GROUP = '4.6.0'
VERSION_REGEXP = r'^Modules\s+Release\s+(?P<version>\d[^+\s]*)(\+\S*)?\s'

SHOW_HIDDEN_OPTION = '--all'
Expand All @@ -1352,6 +1358,8 @@ def __init__(self, *args, **kwargs):
setvar('MODULES_LIST_TERSE_OUTPUT', '', verbose=False)

super(EnvironmentModules, self).__init__(*args, **kwargs)
version = StrictVersion(self.version)
self.supports_tcl_check_group = version >= StrictVersion(self.REQ_VERSION_TCL_CHECK_GROUP)

def check_module_function(self, allow_mismatch=False, regex=None):
"""Check whether selected module tool matches 'module' function definition."""
Expand Down Expand Up @@ -1430,6 +1438,7 @@ class Lmod(ModulesTool):
REQ_VERSION = '6.5.1'
DEPR_VERSION = '7.0.0'
REQ_VERSION_DEPENDS_ON = '7.6.1'
REQ_VERSION_LUA_CHECK_GROUP = '6.0.8'
xdelaruelle marked this conversation as resolved.
Show resolved Hide resolved
VERSION_REGEXP = r"^Modules\s+based\s+on\s+Lua:\s+Version\s+(?P<version>\d\S*)\s"

SHOW_HIDDEN_OPTION = '--show-hidden'
Expand All @@ -1454,6 +1463,7 @@ def __init__(self, *args, **kwargs):
self.USER_CACHE_DIR = os.path.join(os.path.expanduser('~'), '.cache', 'lmod')
else:
self.USER_CACHE_DIR = os.path.join(os.path.expanduser('~'), '.lmod.d', '.cache')
self.supports_lua_check_group = version >= StrictVersion(self.REQ_VERSION_LUA_CHECK_GROUP)

def check_module_function(self, *args, **kwargs):
"""Check whether selected module tool matches 'module' function definition."""
Expand Down
25 changes: 25 additions & 0 deletions test/framework/module_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1598,6 +1598,31 @@ def test_generated_module_file_swap(self):
# one/1.0 module was swapped for one/1.1
self.assertEqual(loaded_mods[-2]['mod_name'], 'one/1.1')

def test_check_group(self):
"""Test check_group method."""
if self.MODULE_GENERATOR_CLASS == ModuleGeneratorTcl:
if self.modtool.supports_tcl_check_group:
expected = '\n'.join([
"if { ![ module-info usergroups group_name ] } {",
" error \"mesg\"",
"}",
'',
])
self.assertEqual(expected, self.modgen.check_group("group_name", error_msg="mesg"))
else:
self.assertEqual('', self.modgen.check_group("group_name", error_msg="mesg"))
else:
if self.modtool.supports_lua_check_group:
expected = '\n'.join([
'if not ( userInGroup("group_name") ) then',
' LmodError("mesg")',
'end',
'',
])
self.assertEqual(expected, self.modgen.check_group("group_name", error_msg="mesg"))
else:
self.assertEqual('', self.modgen.check_group("group_name", error_msg="mesg"))


class TclModuleGeneratorTest(ModuleGeneratorTest):
"""Test for module_generator module for Tcl syntax."""
Expand Down
28 changes: 24 additions & 4 deletions test/framework/toy_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
from easybuild.tools.filetools import adjust_permissions, change_dir, copy_file, mkdir, move_file
from easybuild.tools.filetools import read_file, remove_dir, remove_file, which, write_file
from easybuild.tools.module_generator import ModuleGeneratorTcl
from easybuild.tools.modules import Lmod
from easybuild.tools.modules import Lmod, EnvironmentModules
from easybuild.tools.py2vs3 import reload, string_type
from easybuild.tools.run import run_cmd
from easybuild.tools.utilities import nub
Expand Down Expand Up @@ -749,9 +749,29 @@ def test_toy_group_check(self):
self.mock_stdout(False)

if get_module_syntax() == 'Tcl':
pattern = "Can't generate robust check in TCL modules for users belonging to group %s." % group_name
regex = re.compile(pattern, re.M)
self.assertTrue(regex.search(outtxt), "Pattern '%s' found in: %s" % (regex.pattern, outtxt))
module_version = LooseVersion(self.modtool.version)
if isinstance(self.modtool, EnvironmentModules) and module_version >= LooseVersion('4.6.0'):
toy_mod = os.path.join(self.test_installpath, 'modules', 'all', 'toy', '0.0')
toy_mod_txt = read_file(toy_mod)

if isinstance(group, tuple):
group_name = group[0]
error_msg_pattern = "Hey, you're not in the '%s' group!" % group_name
else:
group_name = group
error_msg_pattern = "You are not part of '%s' group of users" % group_name

pattern = '\n'.join([
r'^if \{ \!\[ module-info usergroups %s \] \} \{' % group_name,
r' error "%s[^"]*"' % error_msg_pattern,
r'\}$',
])
regex = re.compile(pattern, re.M)
self.assertTrue(regex.search(outtxt), "Pattern '%s' found in: %s" % (regex.pattern, toy_mod_txt))
else:
pattern = "Can't generate robust check in Tcl modules for users belonging to group %s." % group_name
regex = re.compile(pattern, re.M)
self.assertTrue(regex.search(outtxt), "Pattern '%s' found in: %s" % (regex.pattern, outtxt))

elif get_module_syntax() == 'Lua':
lmod_version = os.getenv('LMOD_VERSION', 'NOT_FOUND')
Expand Down