diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index 9425f8dfb..087b4870b 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -178,9 +178,48 @@ fi export > env_base.env +# The 2-tag / alternative-reco setup below uses 'module save/purge/restore' to stash +# and swap the software environment. If the shell provides no 'module' function, build +# one on a 'modulecmd' binary. Its location varies by version, so resolve it flexibly +# (was hardwired to /usr/bin/modulecmd) and verify it supports saved collections. Fail +# hard -- but only when an alternative-reco tag is set, since single-tag jobs never call +# 'module' -- instead of silently no-op'ing every 'module' call (cf. O2-7070). +# The candidate list also resolves symlinks ('readlink -f') and probes the canonical +# environment-modules install (/usr/share/Modules): on some HPC/container setups +# /usr/bin/modulecmd is a *dangling* symlink (-> /etc/alternatives -> the real .tcl), +# which exec's as "No such file or directory"; this recovers when the real binary is +# still reachable, and otherwise still fails hard (a genuinely missing Modules tree in +# the job's mount namespace is a site-side problem). if ! declare -F module > /dev/null; then + MODULECMD_BIN="" + for _cand in "${MODULECMD}" "/usr/bin/modulecmd" "$(command -v modulecmd 2>/dev/null)" \ + "${MODULESHOME:+${MODULESHOME}/libexec/modulecmd}" \ + "$(readlink -f /usr/bin/modulecmd 2>/dev/null)" \ + /usr/share/Modules/libexec/modulecmd* /usr/share/Modules/*/libexec/modulecmd*; do + if [ -n "${_cand}" ] && [ -x "${_cand}" ] && "${_cand}" bash savelist > /dev/null 2>&1; then + MODULECMD_BIN="${_cand}" + break + fi + done + if [ -n "${MODULECMD_BIN}" ]; then + echo_info "Using modulecmd at ${MODULECMD_BIN}" + elif [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then + echo_error "Alternative-reco (2-tag) requested (ALIEN_JDL_O2DPG_ASYNC_RECO_TAG=${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG})" + echo_error "but no 'modulecmd' supporting saved collections (save/restore) was found." + echo_error " Looked at: \$MODULECMD='${MODULECMD}', /usr/bin/modulecmd (+readlink -f), PATH," + echo_error " \$MODULESHOME/libexec/modulecmd, /usr/share/Modules/{,*/}libexec/modulecmd*." + echo_error " Diagnostics: MODULESHOME='${MODULESHOME}' /usr/bin/modulecmd -> '$(readlink -f /usr/bin/modulecmd 2>/dev/null)' PATH='${PATH}'" + exit 1 + else + echo_info "No 'modulecmd' found, but no alternative-reco tag is set, so 'module' is not needed; continuing." + fi + export MODULECMD_BIN module() { - eval "$(/usr/bin/modulecmd bash "$@")"; + if [ -z "${MODULECMD_BIN}" ]; then + echo_error "'module ${*}' invoked but no usable 'modulecmd' was found (see earlier diagnostics)." + return 127 + fi + eval "$("${MODULECMD_BIN}" bash "$@")"; } export -f module fi