1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
.. _sticky-modules-rcp:
Sticky modules
==============
When providing a configurable environment to users, site's staff may require
that some part of this environment remain loaded whatever the user does.
Such feature is for instance useful when every details of the user environment
are configured through the use of modulefiles. Even the core setup that is
usually configured through the :file:`/etc/profile.d` initialization scripts.
But by using modulefiles for core initialization, end users can fully see how
things are setup on their environment by using
:subcmd:`module display<display>`. When the environment core setup is achieved
by loading a specific modulefile, it is important that such module remains
loaded to keep this initial setup on whatever the module actions the user
performs over its environment.
This recipe describes how to keep modulefiles loaded by forbidding their
unload. Such unloadable modules are called *sticky modules*.
Implementation
--------------
:ref:`Sticky modules` are simply modules that cannot be unloaded once loaded.
Such behavior could be achieved by basically breaking the modulefile
evaluation when attempting to unload the sticky module:
.. code-block:: tcl
if {[module-info mode unload]} {
break
}
Using the ``break`` Tcl command to stop the modulefile evaluation does not
require to install a recent version of Modules to get a basic sticky
mechanism.
To get a smoother sticky mechanism with two different level of stickiness,
allowing to reload environment or to swap a sticky module by another
version of the same module name, the *sticky* and *super-sticky* module tags
have been introduced in Modules v4.7.
A modulefile is declared *sticky* by applying it the ``sticky`` tag with the
:mfcmd:`module-tag` modulefile command. Such sticky module cannot be unloaded,
unless if the unload action is forced or if the module reloads after being
unloaded.
Modulefile can also be defined ``super-sticky`` by applying the corresponding
module tag. *Super-sticky* module cannot be unloaded even if the unload action
is forced. It can only be unloaded if the module reloads afterward.
In case the stickiness applies to the generic module name (and does not target
a specific module version or version-set), one version of the sticky or
super-sticky module can be swapped by another version of this same module.
**Compatible with Modules v4.7+**
Usage examples
--------------
For this recipe, a *core* module acts as the initial setup of user's
environment. This module must not be unloaded otherwise user's environment may
be considered broken.
So this *core* module is tagged *super-sticky* with the :mfcmd:`module-tag`
modulefile command in :file:`core/.modulerc` file:
.. code-block:: tcl
module-tag super-sticky core
Once module got loaded, it cannot be unloaded even if these unload actions are
forced.
.. parsed-literal::
:ps:`$` module list
Currently Loaded Modulefiles:
1) :sgrss:`core/1.0`
Key:
:sgrss:`super-sticky`
:ps:`$` module unload core
Unloading :sgrhi:`core/1.0`
:sgrer:`ERROR`: Unload of super-sticky module 'core/1.0' skipped
:ps:`$` module purge -f
Unloading :sgrhi:`core/1.0`
:sgrer:`ERROR`: Unload of super-sticky module 'core/1.0' skipped
:ps:`$` module list
Currently Loaded Modulefiles:
1) :sgrss:`core/1.0`
Key:
:sgrss:`super-sticky`
However it is still possible to change version of this *super-sticky* module.
.. parsed-literal::
:ps:`$` module switch core/2.0
:ps:`$` module list
Currently Loaded Modulefiles:
1) :sgrss:`core/2.0`
Key:
:sgrss:`super-sticky`
In this recipe environment, the *compiler* module provides several flavors:
*compA* and *compB*. Site's staff have decided that user's environment should
always have a compiler module loaded by default.
So the *compiler* module is set *sticky* with the :mfcmd:`module-tag`
modulefile command in :file:`compiler/.modulerc` file:
.. code-block:: tcl
module-tag sticky compiler
As stickiness is defined over the generic *compiler* name, users can switch
between available compiler flavors:
.. parsed-literal::
:ps:`$` module list
Currently Loaded Modulefiles:
1) :sgrss:`core/2.0` 2) :sgrs:`compiler/compB/2.1`
Key:
:sgrss:`super-sticky` :sgrs:`sticky`
:ps:`$` module switch compiler/compA
:ps:`$` module list
Currently Loaded Modulefiles:
1) :sgrss:`core/2.0` 2) :sgrs:`compiler/compA/1.2`
Key:
:sgrss:`super-sticky` :sgrs:`sticky`
Unload attempt fails by default:
.. parsed-literal::
:ps:`$` module unload compiler
Unloading :sgrhi:`compiler/compA/1.2`
:sgrer:`ERROR`: Unload of sticky module 'compiler/compA/1.2' skipped
However if a user really wants to get rid of the *compiler* module, the unload
action can be forced:
.. parsed-literal::
:ps:`$` module unload -f compiler
Unloading :sgrhi:`compiler/compA/1.2`
:sgrwa:`WARNING`: Unload of sticky module 'compiler/compA/1.2' forced
:ps:`$` module list
Currently Loaded Modulefiles:
1) :sgrss:`core/2.0`
Key:
:sgrss:`super-sticky`
Last but not least, the sticky modules should get loaded when the user's shell
session initializes. So the *core* and *compiler* modules should be defined
for load in the initialization RC file |file etcdir_initrc|:
.. code-block:: tcl
#%Module
module use --append .../example/sticky-modules/modulefiles
module load core
module load compiler/compB
.. vim:set tabstop=2 shiftwidth=2 expandtab autoindent:
|