Skip to content

Commit 777fc4a

Browse files
committed
doc: add *sticky modules* cookbook recipe
1 parent fecc5a5 commit 777fc4a

File tree

10 files changed

+182
-0
lines changed

10 files changed

+182
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#%Module4.7
2+
module-tag sticky compiler
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#%Module
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#%Module
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#%Module
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#%Module
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#%Module4.7
2+
module-tag super-sticky core
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#%Module
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#%Module

doc/source/conf.py

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

0 commit comments

Comments
 (0)