cea-hpc / modules

Environment Modules: provides dynamic modification of a user's environment
http://modules.sourceforge.net/
GNU General Public License v2.0
668 stars 102 forks source link

skip initialization of user .modulerc #479

Closed idesk2596 closed 1 year ago

idesk2596 commented 1 year ago

Hi,

Is it possible to avoid sourcing user ~/.modulerc when initializing the module function?

maybe set some MODULE_SKIP_USER_MODULERC=1 or some equivalent which will be taken care of during source "$ENV_MODULES_INSTALL_PATH/init/bash" ?

[ using version 5.1.1 ]

Thanks.

xdelaruelle commented 1 year ago

Such feature does not exist at the moment.

Best you can do is to redefine the runModulerc procedure of modulecmd.tcl with a siteconfig.tcl configuration file. With ongoingCommandName you can test in your personalized runModulerc that an autoinit command is ongoing, then you could drop the user modulerc file.

proc runModulerc {} {                                                          
   set rclist {}                                                               

   if {[set rcfile [getConf rcfile]] ne {}} {                                  
      # if MODULERCFILE is a dir, look at a modulerc file in it                
      if {[file isdirectory $rcfile]\                                          
         && [file isfile $rcfile/modulerc]} {                                  
         lappend rclist $rcfile/modulerc                                       
      } elseif {[file isfile $rcfile]} {                                       
         lappend rclist $rcfile                                                
      }                                                                        
   }                                                                           
   if {[file isfile @etcdir@/rc]} {                                            
      lappend rclist @etcdir@/rc                                               
   }
   if {[ongoingCommandName] ne {autoinit}} {
      if {[info exists ::env(HOME)] && [file isfile $::env(HOME)/.modulerc]} {    
         lappend rclist $::env(HOME)/.modulerc                                    
      }                                                                           
   }

   setState rc_running 1                                                       
   foreach rc $rclist {                                                        
      if {[file readable $rc]} {                                               
         reportDebug "Executing $rc"                                           
         cmdModuleSource load $rc                                              
         lappendState rc_loaded $rc                                            
      }                                                                        
   }                                                                           
   unsetState rc_running                                                       

   # identify alias or symbolic version set in these global RC files to be     
   # able to include them or not in output or resolution processes             
   array set ::g_rcAlias [array get ::g_moduleAlias]                           
   array set ::g_rcVersion [array get ::g_moduleVersion]                       
   array set ::g_rcVirtual [array get ::g_moduleVirtual]                       
}
xdelaruelle commented 1 year ago

For next version, a feature can be added to skip user modulerc on commands listed in a configuration variable.

idesk2596 commented 1 year ago

Thanks @xdelaruelle ,

I don't want to drop all together, but no rush I'll wait for the next version, it will be great if it can be also added as a global flag to the module arguments like:

$ module --no-user-rc load ..

so already initialized 'module' can skip the user .modulerc as well, this, as it's being called with every 'module' execution.

To get you the idea for the motivation here, we have several OSs, Ubuntu, RHEL, SLES.. and like to maintain one executable relative in PATH, and altered via module to change the package location for the OS underneath.

example:

default PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/nas/bin

$ cat /usr/nas/bin/lcov

#!/bin/bash

export MODULEPATH=/usr/nas/share/modulefiles
declare -F module >/dev/null || source /usr/nas/pkgs/environment-modules/stable/init/bash
module -s load lcov

exec lcov "$@"

The lcov modulefile in that example:

$ cat /usr/nas/share/modulefiles/lcov/1.15

#%Module4.0 # -*- mode: tcl; -*-
##

set     name            lcov
set     version         1.15
set     compiler        gcc-11.2.0
set     sys               x86_64
set     topdir          /usr/nas/pkgs/spack/common/pkgs

set     osver           [ exec /usr/nas/bin/osid ]
set     march           [ exec /usr/nas/bin/march ]

set     platdir         $topdir/linux-${osver}-${march}/stable/${name}-${version}
set     genericdir      $topdir/linux-${osver}-${sys}/stable/${name}-${version}

if { [file isdirectory $platdir] } {
    set instdir $platdir
} elseif { [file isdirectory $genericdir] } {
    set instdir $genericdir
} else {
    if { [ module-info mode load ] } {
      puts stderr "ERROR: OS and/or machine architecture not supported, please contact the administrator."
      break
    }
}

prepend-path PATH               $instdir/bin

The end goal is that the module directive executable won't interpreted user .modulerc, so nothing coming from the user can disturb it.