mirror of
https://github.com/Pmodules/Pmodules.git
synced 2026-06-26 01:23:09 +02:00
f828c728ad
Print error message if the directory cannot be created.
299 lines
8.2 KiB
Bash
299 lines
8.2 KiB
Bash
#!/bin/bash
|
|
|
|
declare PMODULES_MODULEFILES_DIR='modulefiles'
|
|
declare PMODULES_VERSION='@PMODULES_VERSION@'
|
|
declare -A GroupDepths=(['none']=0)
|
|
|
|
declare -a Overlays=()
|
|
declare -A OverlayInfo
|
|
declare -A Dir2OverlayMap
|
|
|
|
declare -r ol_normal='n'
|
|
declare -r ol_hiding='h'
|
|
declare -r ol_replacing='r'
|
|
|
|
|
|
#
|
|
# compute depth of modulefile directory.
|
|
#
|
|
# Args:
|
|
# $1: absolute path of a modulefile directory
|
|
#
|
|
compute_group_depth () {
|
|
local -n result="$1"
|
|
local -r dir="$2"
|
|
if [[ ! -d "${dir}" ]]; then
|
|
${mkdir} -p "${dir}" || \
|
|
std::die 1 "Cannot create directory -- ${dir}"
|
|
fi
|
|
local group=${dir%/*}
|
|
local group=${group##*/}
|
|
result=$(${find} "${dir}" -depth \( -type f -o -type l \) \
|
|
-printf "%d" -quit 2>/dev/null)
|
|
(( result-=2 )) || :
|
|
# if a group doesn't contain a modulefile, depth is negativ
|
|
# :FIXME: better solution?
|
|
(( result < 0 )) && (( result = 0 )) || :
|
|
}
|
|
|
|
#
|
|
# (Re-)Scan available groups in given overlays and compute group depth's
|
|
#
|
|
# Args:
|
|
# $@: overlay names
|
|
#
|
|
scan_groups () {
|
|
local ol
|
|
local depth
|
|
for ol in "$@"; do
|
|
local modulefiles_root="${OverlayInfo[${ol}:modulefiles_root]}"
|
|
local dir
|
|
for dir in "${modulefiles_root}"/*/"${PMODULES_MODULEFILES_DIR}"; do
|
|
local group="${dir%/*}"
|
|
group="${group##*/}"
|
|
if [[ ! -v GroupDepths[${group}] ]]; then
|
|
compute_group_depth depth "${dir}"
|
|
GroupDepths[$group]=${depth}
|
|
fi
|
|
Dir2OverlayMap[${dir%/"${PMODULES_MODULEFILES_DIR}"*}]="${ol}"
|
|
done
|
|
done
|
|
GroupDepths['none']=0
|
|
}
|
|
|
|
declare -A DefaultPmodulesConfig=(
|
|
['defaultgroups']='Tools:Programming'
|
|
['default_groups']='Tools:Programming'
|
|
['defaultreleasestages']='stable'
|
|
['default_reltages']='stable'
|
|
['tmpdir']="/opt/psi/var/tmp/${USER}"
|
|
['tmp_dir']="/opt/psi/var/tmp/${USER}"
|
|
['distfilesdir']='/opt/psi/var/distfiles'
|
|
['distfiles_dir']='/opt/psi/var/distfiles'
|
|
['download_dir']='/opt/psi/var/distfiles'
|
|
['overlays']=''
|
|
)
|
|
|
|
declare -A OverlayConfigKeys=(
|
|
['install_root']='/opt/psi'
|
|
['modulefiles_root']=''
|
|
['excludes']=''
|
|
['type']='n'
|
|
['modulepath']=''
|
|
)
|
|
|
|
pm::get_value(){
|
|
local -- yaml_input="$1"
|
|
local -n val="$2"
|
|
local -- key="$3"
|
|
local -- expected_type="$4"
|
|
|
|
local -- type=''
|
|
type=$( ${yq} -e ".${key} | type" 2>/dev/null <<<"${yaml_input}")
|
|
if [[ "${type}" != "${expected_type}" ]]; then
|
|
std::die 3 "%s" \
|
|
"Value of '${key}' must be of type '${expected_type:2}', but is '${type:2}'!"
|
|
fi
|
|
val=$( ${yq} -e ".${key}" \
|
|
2>/dev/null <<<"${yaml_input}" ) || val=''
|
|
}
|
|
pm::get_seq(){
|
|
local -- yaml_input="$1"
|
|
local -n val="$2"
|
|
local -- key="$3"
|
|
|
|
local -- type=''
|
|
type=$( ${yq} ".${key} | type" 2>/dev/null <<<"${yaml_input}")
|
|
if [[ "${type:2}" == 'null' ]]; then
|
|
val=''
|
|
return 0
|
|
fi
|
|
if [[ "${type}" != '!!seq' ]]; then
|
|
std::die 3 "%s" \
|
|
"Value of '${key}' must be of type 'seq', but is of type '${type:2}'!"
|
|
fi
|
|
val=$( ${yq} -e ".${key}[]" \
|
|
2>/dev/null <<<"${yaml_input}" ) || val=''
|
|
}
|
|
|
|
|
|
pm::read_config(){
|
|
: "
|
|
Read Pmodules configuration files '${PMODULES_ROOT}/config/Pmodules.yaml'
|
|
and '${HOME}/.Pmodules/Pmodules.yaml'.
|
|
|
|
Args:
|
|
none
|
|
"
|
|
get_config_of_overlay(){
|
|
: "
|
|
Get configuration of an overlay.
|
|
|
|
Args:
|
|
$1 YAML config
|
|
$2 name of overlay
|
|
"
|
|
local -r yaml_input="$1"
|
|
local -r ol_name="$2"
|
|
local -- key=''
|
|
local -a keys=()
|
|
local -- value=''
|
|
|
|
Overlays+=( "${ol_name}" )
|
|
# init overlay with defaults
|
|
for key in "${!OverlayConfigKeys[@]}"; do
|
|
OverlayInfo[${ol_name}:${key}]="${OverlayConfigKeys[${key}]}"
|
|
done
|
|
# get keys in YAML input
|
|
readarray -t keys < <( ${yq} -e ".|keys|.[]" <<<"${yaml_input}" 2>/dev/null ) || \
|
|
std::die 3 "Oops: retrieving keys from:\n${yaml_input}"
|
|
for key in "${keys[@]}"; do
|
|
[[ -v OverlayConfigKeys[${key,,}] ]] || \
|
|
std::die 3 "%s -- %s\n%s" \
|
|
"Invalid key in configuration" \
|
|
"${key}" "${yaml_input}"
|
|
case ${key,,} in
|
|
install_root )
|
|
pm::get_value "${yaml_input}" value "${key}" '!!str'
|
|
OverlayInfo[${ol_name}:install_root]=$(${envsubst} <<< "${value}")
|
|
mkdir -p "${OverlayInfo[${ol_name}:install_root]}" 2>/dev/null
|
|
[[ -d ${OverlayInfo[${ol_name}:install_root]} ]] || \
|
|
std::die 3 \
|
|
"Invalid installation root directory for overlay '${ol_name}' -- ${value}"
|
|
;;
|
|
modulefiles_root )
|
|
pm::get_value "${yaml_input}" value "${key}" '!!str'
|
|
OverlayInfo[${ol_name}:modulefiles_root]=$(${envsubst} <<< "${value}")
|
|
mkdir -p "${OverlayInfo[${ol_name}:modulefiles_root]}" 2>/dev/null
|
|
[[ -d ${OverlayInfo[${ol_name}:modulefiles_root]} ]] || \
|
|
std::die 3 \
|
|
"Invalid modulefiles root directory for overlay '${ol_name}' -- ${value}"
|
|
;;
|
|
type )
|
|
pm::get_value "${yaml_input}" value "${key}" '!!str'
|
|
case ${value} in
|
|
"${ol_normal}" | "${ol_replacing}" | "${ol_hiding}" )
|
|
:
|
|
;;
|
|
* )
|
|
std::die 3 "Invalid type for overlay '${ol_name}' -- ${type}"
|
|
;;
|
|
esac
|
|
OverlayInfo[${ol_name}:type]="${value}"
|
|
;;
|
|
excludes )
|
|
pm::get_seq "${yaml_input}" value "${key}" '!!seq'
|
|
local -a tmp_array=()
|
|
readarray -t tmp_array <<<${value}
|
|
local excludes=''
|
|
printf -v excludes "%s:" "${tmp_array[@]}"
|
|
OverlayInfo[${ol_name}:excludes]=$(${envsubst} <<<"${excludes%:}" )
|
|
;;
|
|
modulepath )
|
|
pm::get_seq "${yaml_input}" value "${key}" '!!seq'
|
|
local -a tmp_array=()
|
|
readarray -t tmp_array <<<${value}
|
|
local modulepath=''
|
|
printf -v modulepath "%s:" "${tmp_array[@]}"
|
|
OverlayInfo[${ol_name}:modulepath]=$(${envsubst} <<< "${modulepath%:}")
|
|
;;
|
|
esac
|
|
done
|
|
OverlayInfo[${ol_name}:used]='no'
|
|
if [[ -z "${OverlayInfo[${ol_name}:modulefiles_root]}" ]]; then
|
|
OverlayInfo[${ol_name}:modulefiles_root]=${OverlayInfo[${ol_name}:install_root]}
|
|
fi
|
|
local modulefiles_root=${OverlayInfo[${ol_name}:modulefiles_root]}
|
|
Dir2OverlayMap[${modulefiles_root}]="${ol_name}"
|
|
}
|
|
|
|
get_config_of_overlays(){
|
|
: "
|
|
Get configuration of overlays in YAML input.
|
|
|
|
Args:
|
|
$1 YAML input
|
|
"
|
|
local -r yaml_input="$1"
|
|
local -- overlay=''
|
|
local -a overlays=()
|
|
readarray -t overlays < <( ${yq} -e '.|keys|.[]' <<<"${yaml_input}" )
|
|
|
|
for overlay in "${overlays[@]}"; do
|
|
local yaml_tmp
|
|
pm::get_value "${yaml_input}" yaml_tmp "${overlay}" '!!map'
|
|
get_config_of_overlay "${yaml_tmp}" "${overlay}"
|
|
done
|
|
}
|
|
|
|
get_config(){
|
|
: "
|
|
Get Pmodules configuration.
|
|
|
|
Args:
|
|
$1 Pmodules configuration file
|
|
"
|
|
local -r config_file="$1"
|
|
local -- yaml_input=''
|
|
yaml_input=$( ${yq} -Ne e "." "${config_file}" 2>/dev/null ) || \
|
|
std::die 3 "Cannot read configuration file '${config_file}'!"
|
|
|
|
local -a keys=()
|
|
readarray -t keys < <( ${yq} -e ".|keys().[]" <<<"${yaml_input}" 2>/dev/null ) || \
|
|
std::die 3 "Oops: retrieving keys from:\n${yaml_input}"
|
|
for key in "${keys[@]}"; do
|
|
[[ -v DefaultPmodulesConfig[${key,,}] ]] || \
|
|
std::die 3 "%s -- %s\n%s" \
|
|
"Invalid key in configuration" \
|
|
"${key}" "${yaml_input}"
|
|
case ${key,,} in
|
|
defaultgroups | default_groups )
|
|
pm::get_value "${yaml_input}" DefaultGroups "${key}" '!!str'
|
|
;;
|
|
defaultreleasestages | default_reltages )
|
|
pm::get_value "${yaml_input}" DefaultReleaseStages "${key}" '!!str'
|
|
;;
|
|
tmpdir | tmp_dir )
|
|
pm::get_value "${yaml_input}" TmpDir "${key}" '!!str'
|
|
;;
|
|
distfilesdir | download_dir )
|
|
pm::get_value "${yaml_input}" DistfilesDir "${key}" '!!str'
|
|
;;
|
|
overlays )
|
|
local tmp_str=''
|
|
pm::get_value "${yaml_input}" tmp_str "${key}" '!!map'
|
|
get_config_of_overlays "${tmp_str}"
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
Overlays=()
|
|
|
|
# system config file
|
|
local -r sys_config_file="${PMODULES_HOME%%/Tools*}/config/Pmodules.yaml"
|
|
test -r "${sys_config_file}" || \
|
|
std::die 3 \
|
|
"%s %s -- %s" \
|
|
"base overlay definition file" \
|
|
"does not exist or is not readable" \
|
|
"$_"
|
|
DefaultGroups="${DefaultPmodulesConfig['default_groups']}"
|
|
DefaultReleaseStages="${DefaultPmodulesConfig['default_reltages']}"
|
|
TmpDir="${DefaultPmodulesConfig['tmp_dir']}"
|
|
DistfilesDir="${DefaultPmodulesConfig['download_dir']}"
|
|
|
|
get_config "${sys_config_file}"
|
|
|
|
local -r usr_config_file="${HOME}/.Pmodules/Pmodules.yaml"
|
|
if [[ -r "${usr_config_file}" ]]; then
|
|
get_config "${usr_config_file}"
|
|
fi
|
|
}
|
|
|
|
# Local Variables:
|
|
# mode: sh
|
|
# sh-basic-offset: 8
|
|
# tab-width: 8
|
|
# End:
|