Hide or forbid modulefile

Configuration

  • No specific configuration

Use cases

  • Restrict usage of particular software to a limited set of user (RestrictUsage)

    • Included in module specification result for a not granted user: no

    • Visible for a not granted user on a full avail: no

    • Visible for a not granted user on a targeted avail: no

    • Visible for a not granted user once loaded on a list: yes

    • Load tentative for a not granted user: error

  • Allow usage of particular software once clearance has been obtained (AllowOnceCleared)

    • Included in module specification result for a not granted user: yes

    • Visible for a not granted user on a full avail: yes

    • Visible for a not granted user on a targeted avail: yes

    • Visible for a not granted user once loaded on a list: yes

    • Load tentative for a not granted user: error

  • Expire a software after a given date (Expire)

    • Included in module specification result for a not granted user: no after expiration date

    • Visible for a not granted user on a full avail: no after expiration date

    • Visible for a not granted user on a targeted avail: no after expiration date

    • Visible for a not granted user once loaded on a list: yes, even after expiration date

    • Load tentative for a not granted user: error after expiration date

  • Disclose a software after a given date (Disclose)

    • Included in module specification result for a not granted user: no prior disclosure date

    • Visible for a not granted user on a full avail: no prior disclosure date

    • Visible for a not granted user on a targeted avail: no prior disclosure date

    • Visible for a not granted user once loaded on a list: yes, even prior disclosure date

    • Load tentative for a not granted user: error prior disclosure date

  • Hide software not of interest for current user (HideNotOfInt)

    • Included in module specification result for a not granted user: yes

    • Visible for a not granted user on a full avail: no, unless specific option set

    • Visible for a not granted user on a targeted avail: yes

    • Visible for a not granted user once loaded on a list: yes

    • Load tentative for a not granted user: success

  • Hide software only useful for other software as dependency (HideDep)

    • Included in module specification result for a not granted user: yes

    • Visible for a not granted user on a full avail: no, unless specific option set

    • Visible for a not granted user on a targeted avail: yes

    • Visible for a not granted user once loaded on a list: yes

    • Load tentative for a not granted user: success

  • Hide dependency software once loaded (HideDepOnceLoaded)

    • Included in module specification result for a not granted user: see HideDep

    • Visible for a not granted user on a full avail: see HideDep

    • Visible for a not granted user on a targeted avail: see HideDep

    • Visible for a not granted user once loaded on a list: no, unless specific option set

    • Load tentative for a not granted user: see HideDep

Specification

  • 2 new modulefile commands are introduced for the needs described above: module-hide and module-forbid

  • module-hide removes visibility of specified modules

    • module-hide acts when modules are searched (avail, whatis and search sub-commands) or selected (load, unload, display, etc sub-commands)

    • Visibility is however enabled if hidden module is specifically searched

      • On all context hidden module mod/1.0 is included in result for instance if mod/1.0 or mod@1.0,2.0 are specified

      • But hidden module mod/1.0 is excluded from result if mod@:2.0 or mod@1: are specified

      • And is also excluded from result if mod or mod/* are specified when mod/1.0 is set default

      • Unless if search is made to select one module since in this context a mod search query is equivalent to mod/default

      • Hard-hidden modules are not disclosed even if specifically searched

    • Excluded from module resolution result

      • Unless precisely specified on the following selection contexts:

      • For example, the hidden module mod/1.0

        • is included in module load mod/1.0 result

        • is excluded from module load mod/1 result, even if default symbol targets it

        • is excluded from module load mod result, unless if default symbol targets it (as query is equivalent to mod/default)

        • is excluded from module load mod@:2 result, even if default symbol targets it

        • is included in module load mod@1.0,2.0 result

        • is included/excluded the same way for prereq and conflict sub-commands than load sub-command

        • is matched by is-loaded and info-loaded sub-commands querying it once loaded

        • is excluded from module whatis result

        • is included/excluded the same way for whatis sub-command than avail sub-command

        • is excluded from module avail result

        • is excluded from module avail m* result

        • is included in module avail mod/1.0 result

        • is excluded from module avail mod/1 result, even if default symbol targets it

        • is excluded from module avail mod result, even if default symbol targets it (as query is NOT equivalent to mod/default in this context)

        • is excluded from module avail mod@:2 result, even if default symbol targets it

        • is included in module avail mod@1.0,2.0 result

    • Included in module resolution result if --all option of avail, whatis, search and aliases sub-commands is set

      • --all option does not apply to is-avail sub-command to make it coherent with load sub-command (e.g., a is-avail mod returning true implies load mod effectively loading a module)

    • Visibility of a module targeted by a module-hide command, with regular hiding level defined, acts similarly than for a file whose name is prefixed by a dot character on Unix platform

    • If --soft option is set on module-hide command, module hiding is weakened

      • Module is always included in resolution result for the following contexts

      • For example, the hidden module mod/1.0

        • is included in module load mod/1.0 result

        • is included in module load mod/1 result

        • is included in module load mod result

        • is included in module load mod@:2 result

        • is included in module load mod@1.0,2.0 result

        • is included/excluded the same way for prereq and conflict sub-commands than load sub-command

        • is matched by is-loaded and info-loaded sub-commands querying it once loaded

        • is excluded from module whatis result

        • is included/excluded the same way for whatis sub-command than avail sub-command

        • is excluded from module avail result

        • is excluded from module avail m* result

        • is included in module avail mod/1.0 result

        • is included in module avail mod/1 result

        • is included in module avail mod result

        • is included in module avail mod@:2 result

        • is included in module avail mod@1.0,2.0 result

    • If --hard option is set on module-hide command, hiding is hardened and designated modules are never unveiled

      • Designated modules are strictly hidden, also referred as hard-hidden

        • --all option of avail sub-command cannot unveil them

      • Excluded from module resolution result, which means it is always excluded from resolution on following context:

      • For example, the hard-hidden module mod/1.0

        • is excluded from module load mod/1.0 result

        • is excluded from module load mod result, even if default symbol targets it

        • is excluded from module load mod/1 result, even if default symbol targets it

        • is excluded from module load mod@:2 result, even if default symbol targets it

        • is excluded from module load mod@1.0,2.0 result

        • is included/excluded the same way for prereq and conflict sub-commands than load sub-command

        • is matched by is-loaded and info-loaded sub-commands querying it once loaded

        • is excluded from any avail query result

        • is included/excluded the same way for whatis sub-command than avail sub-command

      • Visibility of a module targeted by a module-hide --hard command acts like if no modulefile exists on filesystem

    • If --hidden-loaded option is set on module-hide, hiding also applies to specified modules once they are loaded

      • Hidden once loaded modules do not appear on module list

        • Unless --all option is set on list sub-command

      • Hidden once loaded modules load, unload or tag is not reported

        • If this evaluation has been triggered automatically

          • By an automated module handling mechanism for instance

          • Which means user has not explicitly asked the module load or unload

        • And was automatically loaded, in case of an automatic unload

          • Which means the automatic unload of an hidden loaded module will be reported if it was manually loaded

        • And if verbosity level is lower than verbose2 level

        • And if no issue occurs during hidden module evaluation

        • Switch of hidden modules is not reported

          • If both switched-off and switched-on modules are set hidden

          • If switched-off module were automatically loaded

          • And if the switch evaluation has been automatically triggered

      • When those modules are loaded, a hidden-loaded tag is applied to them and recorded in __MODULES_LMTAG environment variable to keep track of their hidden status

      • Hidden once loaded status does not affect is-loaded: these modules will always be reported if they match is-loaded queries

  • module-forbid disallow evaluation of specified modules

    • It does not imply hiding, but can be of course coupled with module-hide calls

    • Evaluation of targeted modules is forbidden

      • Error is rendered prior evaluation when trying to load, display, help, test, path, whatis them

      • Note that for whatis evaluation mode, an error is reported only if a module is referred by its exact name which is not the case on search sub-command as no module is specified, just a keyword to search

      • No error occurs when unloading a module that were set forbidden after it was loaded by user

    • As it impacts module evaluation, module-forbid is only effective when it targets modulefiles or virtual modules

      • Module alias or symbolic version are not impacted by module-forbid directives

      • Even if they match some module-forbid statements, they are still resolved to their target and these targets do not inherit the forbidden tag set on their alias, symbol.

      • When a module-forbid command targets a directory, this directory is still resolved to its target, but the target inherits the forbidden tag as it matches the name specified on module-forbid command

    • When combined with a module-hide --hard command, designated modules is unveiled if referred by its exact name and set in error

      • Thus an error is obtained when trying to reach module instead of not finding it (which is the regular behavior for hard-hidden modules)

  • module-hide accepts options that change its behavior:

    • --hidden-loaded: hides module from loaded module list

    • --soft: lightweight module hide

    • --hard: highest hiding level

    • --not-user: specify a list of users unaffected by hide mechanism

    • --not-group: specify a list of groups whose member are unaffected by hide mechanism

    • --user: specify a list of users specifically affected by hide mechanism

    • --group: specify a list of groups whose member are specifically affected by hide mechanism

    • --before: enables hide mechanism until a given date

    • --after: enables hide mechanism after a given date

  • module-forbid accepts options that change its behavior:

    • --not-user: specify a list of users unaffected by forbid mechanism

    • --not-group: specify a list of groups whose member are unaffected by forbid mechanism

    • --user: specify a list of users specifically affected by forbid mechanism

    • --group: specify a list of groups whose member are specifically affected by forbid mechanism

    • --before: enables forbid mechanism until a given date

    • --after: enables forbid mechanism after a given date

    • --message: supplements error message obtained when trying to evaluate a forbidden module with given text message

    • --nearly-message: supplements warning message obtained when evaluating a nearly forbidden module with given text message

  • Each use case expressed above are covered by following command:

    • RestrictUsage: module-hide --hard

    • AllowOnceCleared: module-forbid

    • Expire: module-forbid --after + module-hide --hard --after

    • Disclose: module-hide --hard --before

    • HideNotOfInt: module-hide --soft

    • HideDep: module-hide --soft

    • HideDepOnceLoaded: module-hide --soft --hidden-loaded

  • module-hide and module-forbid accept the specification of several modules

    • For instance module-hide mod1 mod2...

    • Advanced module version specifiers are supported if relative module option is enabled

    • Full path specification are not supported, as modulerc are not evaluated when reaching a modulefile specified as full path

      • For instance, /path/to/modulefiles/.modulerc is not evaluated when loading /path/to/modulefiles/mod/1.0

      • Thus module-hide and module-forbid commands set in this modulerc files are not evaluated

      • If module is specified as full path, no error is returned, but it will have no effect as demonstrated above

        • Unless on very specific cases, where a global rc file defines these hidden/forbidden commands for the full path modules

  • --user, --group, --not-user and --not-group specification is only supported on Unix platform

    • These options raise an error when used on Windows platform

    • In which case relative module-hide or module-forbid command is made ineffective as well as remaining content of the modulerc script hosting them

    • Error message is clearly seen when trying to load related modules and indicate where to find the erroneous command

  • --user and --group options prevail over --not-user and --not-group options

    • When --user or --group is set, exclusion list from --not-user and --not-group are ignored

  • --before and --after are also supported by module-hide to phase-out modules prior to forbid their evaluation

  • --before and --after accept a date time as value

    • Accepted date time format is YYYY-MM-DD[THH:MM]

    • If no time value is specified (just a date like 2020-08-01), 00:00 is assumed

      • So 2020-08-01 is translated into 2020-08-01T00:00

    • An error is raised if submitted date time value does not match accepted date time format

    • if both --before and --after options are set and before date is greater than after date

      • targeted module is always hidden/forbidden

      • no error is returned

  • --before and --after options are not supported on Tcl version below 8.5

    • Prior 8.5, clock scan command does not have a -format option

    • This option is required to support defined date time format

    • An error is raised when --before or --after options are used over a Tcl version below 8.5

  • --message option adds additional text to the access denied error message

    • Newline set in text message are preserved, which could help to control text output format

    • Message content is set along forbidden module specification

      • Message recorded for matching module specification will be printed

      • Message recorded on other matching specification will be ignored, only message from retained matching specification is printed

      • Firstly evaluated module-forbid command that matches module specification is retained with its message property

  • a module matching a module-forbid statement whose --after limit is close is considered nearly forbidden

    • nearly-forbidden tag applies to such module

    • matched module-forbid statement should of course not be disabled for current user or group due to --not-user or --not-group option values

    • the near range is defined by the nearly_forbidden_days configuration, which equals to 14 (14 days) by default

    • this configuration accepts an integer value which represents a number of days prior forbidding starts to be effective for module

    • nearly_forbidden_days configuration can be set at configure time with --with-nearly-forbidden-days option or afterward with the config sub-command (which sets the MODULES_NEARLY_FORBIDDEN_DAYS environment variable)

    • when evaluating a nearly-forbidden module, a warning message is reported to indicate that module access will soon be denied

  • --nearly-message option adds additional text to the access will be denied warning message

    • Newline set in text message are preserved, which could help to control text output format

    • Message content is set along nearly-forbidden module specification

      • Message recorded for matching module specification will be printed

      • Message recorded on other matching specification will be ignored, only message from retained matching specification is printed

      • Firstly evaluated module-forbid command that matches module specification is retained with its message property

  • module-hide and module-forbid are intended to be used in modulerc files

    • as they impact modulefile resolution

    • they also need to be enabled in modulefile context as global/user rc files are evaluated as modulefile, not modulerc

  • several module-hide calls for the same module will supersede each other

    • definition with the highest hiding level wins

    • which means the most restrictive call wins

    • a --hidden-loaded status set is kept even if corresponding module-hide call is not the highest one

    • the multiple definitions can come across different modulerc files (global, modulepath or modulefile rc levels)

  • Module specification passed as argument to module-hide and module-forbid are matched exactly against available modules

    • Exception made when extended_default or icase mechanisms are enabled

    • Which means wildcard characters like * or ? are treated literally

  • Auto symbols (@default and @latest) are adapted when a latest version is hidden

    • Auto symbols are applied to this version if it is selected specifically (for instance loaded by its full name)

    • Auto symbols are applied to another version when hidden latest is not selected specifically, even if specified with @latest auto symbol

  • Auto-symbols cannot be set hidden

    • When a defined default or latest symbol is set hidden, it is replaced by a default or latest auto-symbol targeting highest available module version

    • Targeting an auto-symbol with a module-hide command, will have no effect

  • When module specification of module-hide targets:

    • A symbolic version

      • This symbol only is hidden

      • Modulefile targeted by hidden symbolic version stays visible

    • An alias

      • This alias only is hidden

      • Modulefile targeted by hidden alias stays visible

    • A modulefile targeted by either symbolic version or alias

      • This modulefile is hidden and all symbolic versions targeting it

      • Aliases targeting modulefile stays visible (thus resolving alias in load or whatis contexts make hidden modulefile target visible unless if set hard-hidden)

  • Hidden alias or symbolic version should not appear in the list of alternative names of loaded modules

    • Unless this alias or symbolic version is not hard-hidden and is used to designate the module to load

    • When default symbolic version is set hidden

      • also remove parent module name from the list of alternative names

      • if resolution query corresponds to parent module name, unhide default symbol unless if hard-hidden

  • On avail sub-command

    • Hidden symbolic versions are not reported along module they target

      • Unless for non-hard-hidden symbols specifically designated in search query

    • A --default filtered search considers search query matches default symbol

      • So default symbolic version will appear in result unless if hard-hidden

  • Different hiding level are considered

    • -1: module is not hidden

    • 0: soft hiding (applied with module-hide --soft)

    • 1: regular hiding (applied with dot name module or default module-hide command)

    • 2: hard hiding (applied with module-hide --hard)

  • Hiding threshold

    • is 0 by default, which means module is considered hidden if its hiding level is greater or equal to 0

    • is raised to 2 when --all option is applied, which means module is considered hidden if its hiding level is greater or equal to 2