SOP — Lmod 站点扩展与模块收敛(SitePackage / slurm 模块退役 / 版本别名)¶
变更日期:2026-10-05 实施人:rain(Agent 执行) 状态:已完成,验收通过 归档目录:
slurm_ins/lmod_site_package_20261005/触发来源:用户对 Lmod 的四点问询(提示块干扰 /slurm模块是否该取消 / csh 补全 / 对标 EDA 行业标准)
1. 背景¶
上一轮(slurm_csh_profile_20261005)补齐了 csh 侧登录注入后,module avail 暴露出两处长期存在的不一致,另有一处使用习惯缺口:
module avail尾部固定打印一段提示块("If the avail list is too long consider trying: ...")。它来自 Lmod 的messageDir/en.lua的avail条目,由StandardPackage.lua注册的msgHook在Hub:avail()(Hub.lua:1451)末尾输出,没有单独开关;且与模块列表同走 stderr,2>/dev/null会把列表一起丢掉。Core/slurm/26.05.2.lua已无存在价值:登录环境由/etc/profile.d/slurm-path.{sh,csh}、slurm_configless.{sh,csh}双轨注入,该模块只是重复前置 PATH(外加一个无人依赖的SLURM_HOME),在module avail里纯属噪音。- 同工具多版本无法不带版本加载:
siemens/calibre/下并存2026.1与2015.2_36.27,module load calibre会因多重匹配报错。
2. 目标¶
module avail不再打印提示块,其余消息(尤其警告)格式与行为不变;- 生成器不再产出
slurm模块,并清理共享盘上遗留的Core/slurm/目录(先备份); - 健康检查与之对齐(不再借
slurm模块做样本); module load calibre命中默认版本2026.1,另提供calibre/latest别名;- 全程幂等:复跑零变更、全跳过;不停服、不重启任何 daemon。
3. 前置条件¶
- root SSH 可达 6 台:控制
.16/.17、计算.18/.19/.20、提交.28; - 工程
.venv/与config/slurm_deploy.yaml就绪;Lmod 8.7.65(EPEL)已装; /opt/modulefiles为 NFS 共享挂载(192.168.31.249:/data/nfs/modulefiles),内容主节点为控制主节点.16;- 执行前
squeue必须为空(本实现体在 TaskProlog 变化时会重启 slurmd;本次 TaskProlog 无变化,实测未触发)。
4. 影响范围¶
| 项 | 内容 |
|---|---|
| 主机 | .16 .17 .18 .19 .20 .28 共 6 台 |
| 文件 | 新增 /etc/lmod/site/SitePackage.lua;改 /etc/profile.d/zzz_site_lmod.sh、.csh(各追加 LMOD_PACKAGE_PATH 段);内容主节点新增 /opt/modulefiles/siemens/calibre/.modulerc.lua;删除 /opt/modulefiles/Core/slurm/ |
| 是否停服 | 否,不重启 daemon |
| 在跑作业 | 不受影响(只改登录环境变量与模块可见性) |
| 窗口期 | 随时;删目录前有备份,可回滚 |
5. 分步操作¶
本次以生成器代码为准(改
slurm_ins的渲染与部署逻辑),下发由部署器完成。以下给出等价底层操作供阅读、复核与手工复现;幂等与错误处理由实现体保证。 实现体:module_env_assets.py(渲染)、module_env_deployer.py(判定/执行/验证/卸载)。
步骤 1:渲染站点 Lmod 扩展 SitePackage.lua¶
Lmod 的 initialize_lmod()(libexec/utils.lua)先 require("StandardPackage"),再把 LMOD_PACKAGE_PATH 的每个目录前置进 package.path,最后 require("SitePackage");而 Hook.register 的默认动作是 replace——故站点文件里注册的 msgHook 会覆盖默认实现,这是 Lmod 官方留的扩展点(rpm 自带的 SitePackage.lua 只是占位文件)。
坑:SitePackage.lua 一旦出错会让全站 Lmod 失效,故只覆盖 msgHook、其余消息沿用与 StandardPackage 同构的默认格式化(string_utils 的 split/fillWords + TermWidth),并在下发前用实机 luac -p 与隔离 LMOD_PACKAGE_PATH 功能验证。
# 备份(若已存在)
cp -a /etc/lmod/site/SitePackage.lua /etc/lmod/site/SitePackage.lua.bak.$(date +%Y%m%d-%H%M%S)
mkdir -p /etc/lmod/site
cat > /etc/lmod/site/SitePackage.lua <<'EOF'
-- 站点 Lmod 扩展(由 slurm 部署器生成,请勿手工修改)
require("strict")
require("TermWidth")
require("string_utils")
local hook = require("Hook")
local i18n = require("i18n")
local function default_msg(kind, a) -- 与 StandardPackage 默认 l_msg 同构
local twidth = TermWidth()
local s = i18n(kind, {}) or ""
if (s:len() > 0) then
for line in s:split("\n") do
a[#a+1] = "\n"
a[#a+1] = line:fillWords("", twidth)
end
a[#a+1] = "\n"
end
a[#a+1] = "\n"
return a
end
local silent = { ["avail"] = true } -- 屏蔽的消息类型
local function site_msg(kind, a)
if (silent[kind]) then return a end
return default_msg(kind, a)
end
hook.register("msgHook", site_msg)
EOF
chmod 644 /etc/lmod/site/SitePackage.lua
luac -p /etc/lmod/site/SitePackage.lua # 语法自检,必须无输出
预期:luac -p 无输出;module --config | grep -i 'Site Pkg location' 显示 /etc/lmod/site/SitePackage.lua(未生效时显示 standard)。
步骤 2:把 LMOD_PACKAGE_PATH 写进双轨站点脚本¶
必须 export/setenv——Lmod 每次启动都从环境读该变量。csh 侧 case 模式串须为字面路径(csh 不对模式做变量展开),判重避免重复 source 时叠加。
# /etc/profile.d/zzz_site_lmod.sh 追加(高危:覆盖前先备份)
_lmod_pkg_dir="/etc/lmod/site"
case ":${LMOD_PACKAGE_PATH:-}:" in
*":${_lmod_pkg_dir}:"*) ;;
*) LMOD_PACKAGE_PATH="${_lmod_pkg_dir}${LMOD_PACKAGE_PATH:+:$LMOD_PACKAGE_PATH}"
export LMOD_PACKAGE_PATH ;;
esac
unset _lmod_pkg_dir
# /etc/profile.d/zzz_site_lmod.csh 追加
if ( ! $?LMOD_PACKAGE_PATH ) then
setenv LMOD_PACKAGE_PATH "/etc/lmod/site"
else
switch (":${LMOD_PACKAGE_PATH}:")
case "*:/etc/lmod/site:*":
breaksw
default:
setenv LMOD_PACKAGE_PATH "/etc/lmod/site:${LMOD_PACKAGE_PATH}"
breaksw
endsw
endif
预期:bash -n 无输出;/bin/csh -f -c 'source /etc/profile.d/zzz_site_lmod.csh; printenv LMOD_PACKAGE_PATH' 输出 /etc/lmod/site。
步骤 3:生成器取消 slurm 模块并登记退役目录¶
module_env.slurm_module.enabled=false 后 modulefile_paths() 不再产出该文件;但生成器只写不删,历史文件会继续被扫到,故由 obsolete_module_file_dirs(本站自有常量,非通配)声明待清理目录 Core/slurm。
# 生成器:slurm_module.enabled: false → 不再渲染 Core/slurm/<ver>.lua
# 部署器:sync 探测 [ -d /opt/modulefiles/Core/slurm ] → apply 备份后删除
预期:module avail 的 Core 段不再出现 slurm/26.05.2。
步骤 4:内容主节点备份并清理退役目录¶
高危:删除共享盘模块目录影响全体用户,故先打包备份、备份失败即中止(实现体用 && 串联)。
# 在内容主节点 192.168.31.16 上
B=/var/backups/slurm/modulefiles; mkdir -p "$B"
tar -C /opt/modulefiles -czf "$B/Core-slurm.removed.tar.gz" Core/slurm
rm -rf /opt/modulefiles/Core/slurm
test ! -e /opt/modulefiles/Core/slurm && echo PRUNED
步骤 5:同工具多版本默认值与别名(.modulerc.lua)¶
yaml 工具条目加 default_version: true 与 version_aliases: ["latest"],渲染成 siemens/calibre/.modulerc.lua:
cat > /opt/modulefiles/siemens/calibre/.modulerc.lua <<'EOF'
module_version("calibre/2026.1", "default")
module_version("calibre/2026.1", "latest")
EOF
预期:module load siemens 后 module -t avail 出现 calibre/latest(@calibre/2026.1);module load calibre 命中 calibre/2026.1。
步骤 6:下发(实现体入口)¶
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env --dry-run # 预演
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env # 下发
预期:待执行变更 > 0、退出码 0、末尾 ✅ 部署完成 且健康校验通过。
6. 验证¶
| # | 命令 | 实测结果 |
|---|---|---|
| 1 | 6 台 module --config \| grep -i 'Site Pkg location' |
均为 /etc/lmod/site/SitePackage.lua ✅ |
| 2 | su - cy01 -c 'module avail' 2>&1 \| grep -c 'avail list is too long' |
0(对照组无 LMOD_PACKAGE_PATH 时为 1,即机制确由站点扩展生效) ✅ |
| 3 | su - cy01 -c 'module avail' |
Core 段为 cadence pdk siemens site synopsys,无 slurm ✅ |
| 4 | .16 上 test ! -e /opt/modulefiles/Core/slurm |
已删除;备份包 /var/backups/slurm/modulefiles/Core-slurm.removed.tar.gz(620 B)存在 ✅ |
| 5 | su - cy01 -c 'module load siemens; module -t avail' |
calibre/latest(@calibre/2026.1)、calibre/2026.1、calibre/2015.2_36.27 ✅ |
| 6 | 隔离树功能测试(/tmp 造两版本 + 真实生成的 .modulerc.lua) |
module load calibre rc=0 → 加载 calibre/2026.1 ✅ |
| 7 | 6 台 csh 登录态 MODULEPATH 含 /opt/modulefiles/Core |
全部通过(双轨脚本改动未回归) ✅ |
| 8 | 幂等复跑 --module-env |
第二次「待执行 0 / 幂等跳过 27 / 退出码 0」 ✅ |
7. 回滚¶
系统侧(恢复变更前状态):
# 1) 还原被清理的 modulefile 目录(内容主节点 .16)
tar -C /opt/modulefiles -xzf /var/backups/slurm/modulefiles/Core-slurm.removed.tar.gz
# 2) 移除站点扩展与别名
rm -f /etc/lmod/site/SitePackage.lua /opt/modulefiles/siemens/calibre/.modulerc.lua
# 3) 恢复双轨站点脚本中「无 LMOD_PACKAGE_PATH 段」的旧内容
# (旧内容 = 从 backup/slurm_ins/ 的源文件重新渲染;实现体入口见下)
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env --rollback
--rollback 会恢复 slurm.conf 的 TaskProlog、删除站点脚本与 SitePackage.lua,并从备份包还原 Core/slurm(实现体 uninstall() 已含该步)。
代码侧:从 backup/slurm_ins/ 恢复源文件后复跑 --module-env。注意:
config/slurm_deploy.yaml.bak.20261005-150000是本轮动手前状态(由本轮 4 处编辑逆向重建,精确);- 两个
.py的历史备份早于本轮改动(分别是 10-05 主题与 09-27 主题的快照),不是动手前快照——需按本 SOP 第 5 章的改动手工逆向,或直接回退到「不复用旧文件、只撤销第 5 章各步」的方式。
备份位置与清单见 backup/README.md。
8. 风险说明¶
| 风险 | 缓解 |
|---|---|
SitePackage.lua 出错导致全站 Lmod 不可用 |
只覆盖 msgHook,其余逻辑与 StandardPackage 同构;下发前 luac -p + 隔离 LMOD_PACKAGE_PATH 功能验证(提示块 1→0);6 台 verify() 每次校验 module --config 的 Site Pkg 位置 |
删除共享盘 Core/slurm/ 影响用户脚本 |
已核查:全站家目录仅 cy01/1(module help 输出留档)与 rain01/.history(csh 历史)命中 module load slurm,无任何脚本依赖;删除前打包备份,--rollback 可还原 |
| 健康检查失去「load 后命令可见」样本 | verify_modules 置空,改由 SitePackage 生效 + Core 路径可见 + csh 站点脚本三项覆盖;Slurm 命令可达性由 node_env / submit_node 两阶段各自验证 |
.modulerc.lua 与兼容侧维护的 calibre/2015.2_36.27 冲突 |
该文件只声明默认与别名,不改动任何既有 modulefile;2015.2_36.27 仍可显式加载 |
流程缺口(已记):本轮动手前未先生成两个 .py 的动手前快照(仅 yaml 做了逆向重建) |
变更已验收通过且幂等;代码侧回滚按第 5 章逐处逆向编辑执行;后续同类变更必须先做源文件快照再动手 |
附录:本次交付物与未落地项¶
| 文件 | 说明 |
|---|---|
backup/slurm_ins/config/slurm_deploy.yaml.bak.20261005-150000 |
动手前配置(逆向重建,600) |
backup/slurm_ins/module_env_assets.py.bak.20261005-135507 等 |
历史版本源文件(非动手前快照,见第 7 章说明) |
本 SOP.md |
变更档案 |
未在本轮落地(按建议顺序留待后续):
- ④ Spider cache:实测本机 Lmod 的
Cached loads (LMOD_CACHED_LOADS)为no(默认不用缓存),启用需同时生成缓存 + 置LMOD_CACHED_LOADS=yes+ 内容变更后重建,否则会「看不到新模块」。当前模块树仅 ~10 个模块,收益为零而风险非零,建议 EDA 工具树就位前再启用(届时落在--module-env的收尾步骤)。 - ⑤
deprecate()标注与命名统一:目标对象(synopsys/vcs-el7、synopsys/eda2018、calibre/2015.2_36.27、virtuoso/IC06.17.700等)不在本工程生成器管辖内(由eda_tools_ins兼容侧维护),改名会破坏其归属;建议改为在生成器侧支持deprecated: true(供纳管工具使用),跨工程改名另立变更。
来源:
/home/rain/Documents/slurm/slurm_ins/lmod_site_package_20261005/SOP.md| 最后更新:2026-10-05 14:57(由build/sync.py同步,请勿在站点侧修改)