Files
2026-09-28 17:14:01 +02:00

230 lines
6.5 KiB
Markdown

# PModules
!!! warning
Although this guide shows how to configure PModules on RHEL9, PModules with AFS backend is not supported on RHEL9!
This guide describes how to configure PModules on RHEL9 via hiera.
More details about Pmodules can be found here: https://gitea.psi.ch/Pmodules/
```{note}
PModules on RHEL9 (and central distribution of PModules) are currently not supported by the Linux team. Use at your own risk!
```
Installation packages (the PModules packages are available in the pli-misc repository - https://repos.psi.ch/rhel9/latest/pli-misc/):
```yaml
base::pkg_group::pmodules:
- "Pmodules"
# RHEL8 apparently requires that you explicitly specify the package version like this
# - "Pmodules-2.0.2-1.el8"
# - "Pmodules_bash-5.2.37-1.el8"
# - "Pmodules_modules-3.2.10.2-1.el8"
base::package_groups:
- "pmodules"
```
Configuration of PModules via /etc/Pmodules.yaml and /etc/profile.d/pmodules.sh:
```yaml
files::files:
'/etc/Pmodules.yaml':
content: |
DefaultGroups: Tools:Programming
DefaultReleaseStages: stable
TmpDir: /var/tmp/
DistfilesDir: /var/cache/Pmodules/distfiles
Overlays:
base:
install_root: /opt/psi
/etc/profile.d/pmodules.sh:
content: |
# source (p)module command
if [[ ${UID} -ge 1000 && ! ${USER} =~ -adm$ ]]; then
if [[ -r source /usr/share/Pmodules/init/bash ]]; then
source /usr/share/Pmodules/init/bash
fi
fi
```
If you are using an NFS share to provide pmodules you should mount the share with local caching enabled for better performance (for more details see https://linux.psi.ch/documentation/admin-guide/configuration/files/mount#caching).
```yaml
mounter::def::pmodules:
ensure: 'mounted'
mountpoint: '/opt/psi'
device: 'whatever-server.psi.ch:/pmodules'
options: 'fsc,nosharecache,sec=krb5'
type: 'nfs4'
mounter::mounts:
- 'pmodules'
```
## Migration
!!! note
These instructions were kindly provided by Ivano Talamo, and are based on the experience of migrating PModules for the RA cluster. There are no guarantees that this will work for your use case, so please check carefully for your usecase before using.
### Copy of a Single Module Without Dependencies
Trying with java version 15u36 that has no dependencies:
```bash
[~]$ cat /opt/psi/Programming/Java/15u36/share/Programming/Java/dependencies
[~]$
```
Copying the content with:
```bash
# replace DESTINATION and NEW_PMODULE_BASE according to your needs
DESTINATION=root@ra-s-003
NEW_PMODULE_BASE=/opt/psi
rsync -avz /opt/psi/Programming/Java/15u36/ ${DESTINATION}:${NEW_PMODULE_BASE}/Programming/Java/15u36/
rsync -avz /opt/psi/Programming/modulefiles/Java/15u36 ${DESTINATION}:${NEW_PMODULE_BASE}/Programming/modulefiles/Java/15u36
rsync -avz /opt/psi/Programming/modulefiles/Java/.release-15u36 ${DESTINATION}:${NEW_PMODULE_BASE}/Programming/modulefiles/Java/.release-15u36
```
Then trying to use it:
```bash
[~]$ module avail
-------------------------------- Programming --------------------------------
Java/15u36
[~]$ module load Java/15u36
[~]$ java --version
openjdk 15 2020-09-15
OpenJDK Runtime Environment (build 15+36-1562)
OpenJDK 64-Bit Server VM (build 15+36-1562, mixed mode, sharing)
```
To automate the copy of a single module, you can use the following function:
```bash
# replace DESTINATION and NEW_PMODULE_BASE according to your needs
DESTINATION=root@ra-s-003
NEW_PMODULE_BASE=/opt/psi
copy_pmodule() {
group=$1
module=$2
version=$3
modulefile=/opt/psi/$group/modulefiles/$module/$version
release=/opt/psi/$group/modulefiles/$module/.release-$version
software=/opt/psi/$group/$module/$version/
ssh $DESTINATION "mkdir -p $NEW_PMODULE_BASE/$group/$module/$version/"
ssh $DESTINATION "mkdir -p $NEW_PMODULE_BASE/$group/modulefiles/$module/"
for i in $modulefile $release $software
do
rsync -avz $i $DESTINATION:$i
done
}
```
So now a single module can be copied with e.g.:
```bash
module_copy Programming cuda 12.8.1
```
### Copy of a Module Including the Dependencies
To determine the dependencies, you can use the following functions:
```bash
get_group() {
module=$1
module search -a $module --no-header 2>&1 | head -1 |awk '{print $3}'
}
get_info() {
group=$1
module=$2
version=$3
if [[ ! -f /opt/psi/$group/modulefiles/$module/$version ]]
then
echo "****** ERROR. /opt/psi/$group/modulefiles/$module/$version not found"
else
cat /opt/psi/$group/modulefiles/$module/$version |grep -i maintainer|sed 's/module-maintainer[ \t]*//'
fi
}
get_deps() {
local module=$1
local version=$2
local space=${3:-0}
for i in $(seq $space)
do
echo -n " "
done
group=$(get_group $module/$version)
info=$(get_info $group $module $version)
ALIGN=$(expr 40 - $space)
printf "%-${ALIGN}s %s\n" "$module/$version" "($info)"
dependency_file_1=/opt/psi/$group/modulefiles/$module/.deps-$version
dependency_file_2=/opt/psi/$group/$module/$version/.dependencies
if [[ -f $dependency_file_1 && -f $dependency_file_2 ]]
then
echo "Both dependency file exit. Error"
return
fi
if [[ ! -f $dependency_file_1 && ! -f $dependency_file_2 ]]
then
return
fi
dependency_file=$dependency_file_1
if [[ -f $dependency_file_2 ]]
then
dependency_file=$dependency_file_2
fi
for dep in $(cat $dependency_file|sed '/^$/d')
do
module=$(echo $dep|cut -d '/' -f 1)
version=$(echo $dep|cut -d '/' -f 2)
group=$(get_group $module/$version)
get_deps $module $version $(expr $space + 3)
done
}
```
We get the following dependencies for crystfel 0.10.2:
```bash
[~]$ get_deps crystfel 0.10.2
crystfel/0.10.2 ("Dmitry Ozerov <dmitry.ozerov@psi.ch>")
gcc/12.1.0 ("Achim Gsell <achim.gsell@psi.ch>")
hdf5_serial/1.12.2 (****** ERROR. /opt/psi/Compiler/modulefiles/hdf5_serial/1.12.2 not found)
pinkindexer/2021.08 ("Dmitry Ozerovv<dmitry.ozerov@psi.ch>")
xgandalf/2021.08 ("Dmitry Ozerov <dmitry.ozerov@psi.ch>")
fdip/2021.08 ("Dmitry Ozerov <dmitry.ozerov@psi.ch>")
xds/20250523 ("MX Data <jiaxin.duan@psi.ch>")
mosflm/7.4.0 ("MX Data <mx-software@psi.ch>")
HDF5_bitshuffle/2025.03 ("Filip Leonarski <filip.leonarski@psi.ch>")
HDF5_LZ4/2018.05 ("Dmitry Ozerov <dmitry.ozerov@psi.ch>")
DirAx/1.17 ("Dmitry Ozerov <dmitry.ozerov@psi.ch>")
```
As the dependencies are already resolved recursively, you can now simply copy all the listed modules with the copy function defined above.
Example for crystfel 0.10.2:
```bash
for get_deps crystfel 0.10.2 | cut -d ' ' -f 1
do
module=$(echo $dep|cut -d '/' -f 1)
version=$(echo $dep|cut -d '/' -f 2)
copy_pmodule $group $module $version
done
```