A cute little fox

Michael Jansen

Drive By Coding

Environment Modules

One of the forgotten tools

[Mike]

3-Minute Read

Environment Modules is one of those open source projects that I wish more people would know and use. I always wonder why tools like asdf don’t provide support for it instead of rolling their own implementation. So lets increase awareness.

The Environment Modules package provides for the dynamic modification of a user’s environment via modulefiles.

Environment Modules Homepage

So what does it do? Here is a small example:

~ $ type ansible
bash: type: ansible: not found

~ $ module avail -l ansible/
- Package/Alias -----------------------.- Versions --------.- Last mod. -------
/home/mjansen/local/etc/modules:
ansible/2.8.15                          2.8                 2020/10/28 18:43:05
ansible/2.9.13                          2.9                 2020/10/28 18:43:15
ansible/2.10.1                          2.10:default        2020/10/28 18:42:56

~ $ module load ansible/2.9.13

~ $ ansible --version
ansible 2.9.13
  config file = None
  configured module search path = ['/home/mjansen/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/mjansen/local/opt/ansible/2.9.13/lib64/python3.8/site-packages/ansible
  executable location = /home/mjansen/local/opt/ansible/2.9.13/bin/ansible
  python version = 3.8.6 (default, Nov 09 2020, 12:09:06) [GCC]

~ $ type ansible
ansible is hashed (/home/mjansen/local/opt/ansible/2.9.13/bin/ansible)

~ $ module unload ansible

~ $ type ansible
bash: type: ansible: not found

So in short environment modules allow you to alter your shell session dynamically by

  • Altering the content of environment variables
  • Setting/Removing aliases
  • Create functions in the users environment
  • There is more in the modulefile man page.

Modulefiles are actually tcl scripts. It is a slightly weird (imo) looking scripting language. Tcl and environment modules are available forever. They are from the 1990s.

The ansible script above looks like this:

#%Module1.0#####################################################################
##
## ANSIBLE VERSION
##
proc ModulesHelp { } {
        global version
        puts stderr "\tActivates ansible v$version [ARA]"
}

set     home         $::env(HOME)
set     version      2.9.13
set     root         $home/local/opt/ansible/$version
set     ansible_callback_plugins [exec $root/bin/python3 -m ara.setup.callback_plugins]

module-whatis   "Ansible V$version"

conflict ansible

append-path PATH $root/bin
setenv ANSIBLE_CALLBACK_PLUGINS $ansible_callback_plugins

So why should you care. As a hypothetical developer you probably need to install different versions of libraries and tools to check your programs against or with. Like different Qt Versions or compiler. Most developer I know then proceed to use shell scripts they source to deal with that. This does not allow easy unloading and switching. Utilizing environment modules gives you a much more pleasant experience. My list currently looks like this:

- Package/Alias -----------------------.- Versions --------.- Last mod. -------
/home/mjansen/local/etc/modules:
ansible/2.8.15                          2.8                 2020/10/28 18:43:05
ansible/2.9.13                          2.9                 2020/10/28 18:43:15
ansible/2.10.1                          2.10:default        2020/10/28 18:42:56
catt                                                        2019/08/26 14:58:23
editor/vim                                                  2020/10/26 19:39:10
elixir_escripts                                             2020/11/11 05:29:32
elm/0.19.1-3                            0.19:0.19.1:default 2020/03/31 22:24:21
go/1.13.6                                                   2020/01/21 16:06:16
gopath                                                      2020/01/21 16:16:09
groovy/2.4.7                                                2019/08/26 14:58:23
groovy/2.5.7                                                2019/08/26 14:58:23
home_install                                                2020/02/23 16:20:05
hugo/0.76.5                                                 2020/10/28 18:46:11
hugo/0.80.0                                                 2021/01/09 21:07:52
java/jdk1.8.0_172                                           2019/08/26 14:58:23
jupyter                                                     2019/08/26 14:58:23
maven/3.3.9                                                 2019/08/26 14:58:23
minishift                                                   2020/03/29 16:29:17
novisual                                                    2019/08/26 14:58:23
reclass/1.4.1                                               2020/01/27 14:27:20
reclass/git                                                 2020/12/20 19:51:34
usr_local                                                   2020/01/29 13:36:42
vit                                                         2020/01/15 17:01:25
zeppelin/0.9.0-preview2                                     2020/10/29 16:42:13

Environment modules also has the concept of sessions which allows you to save and load different configurations. Either in a central location (eg. ~/.module) or to a file specified on the command line.

~ $ module save homepage

~ $ module savelist
Named collection list:
 1) homepage  

~ $ module saveshow homepage
-------------------------------------------------------------------
/home/mjansen/.module/homepage:

module use --append /home/mjansen/local/etc/modules
module load editor
module load gopath
module load go
module load hugo

-------------------------------------------------------------------

Modulefiles can even specify conflicts, so you don’t load two different versions of a library or program. They can also specify requirements, so you don’t forget to load a python version before loading ansible.

If you want to try environment modules one word of warning. In opensuse after installing environment modules it is not active. I guess the same applies to other distros. Shell initialization files for additional packages are a sore spot in most distros. You have to activate it manually in your shell initialization file (eg. bashrc).

# ACTIVATE ENVIRONMENT MODULES                                           # {{{2
###############################################################################
case "$0" in
          -sh|sh|*/sh)  modules_shell=sh ;;
       -ksh|ksh|*/ksh)  modules_shell=ksh ;;
       -zsh|zsh|*/zsh)  modules_shell=zsh ;;
    -bash|bash|*/bash)  modules_shell=bash ;;
esac

source /usr/share/Modules/init/$modules_shell
test -r /usr/share/Modules/init/{$modules_shell}_completion && source /usr/share/Modules/init/{$modules_shell}_completion
comments powered by Disqus

Recent Posts

Categories

About

Freelancer, DevOps and Automation. Everything but Java.