Implementation of YAML configuration files

This commit is contained in:
2023-10-20 17:35:15 +02:00
parent c3e9047f78
commit 3c66af7565
5 changed files with 1103 additions and 536 deletions
+59 -36
View File
@@ -15,6 +15,17 @@ declare -r FNAME_BDEPS='.build_dependencies'
# abs. path is "${PREFIX}/${_docdir}/${module_name}"
declare -r _DOCDIR='share/doc'
declare -a SOURCE_URLS=()
declare -a SOURCE_SHA256_SUMS=()
declare -a SOURCE_NAMES=()
declare -A SOURCE_UNPACK_DIRS=()
declare -a CONFIGURE_ARGS=()
declare -a PATCH_FILES=()
declare -a PATCH_STRIPS=()
declare -a PATCH_STRIP_DEFAULT='1'
declare -a MODULE_DOCFILES=()
declare -- configure_with='auto'
#.............................................................................
#
# Exit script on errror.
@@ -148,7 +159,7 @@ pbuild::add_to_group() {
"%s " "${module_name}/${module_version}:" \
"${FUNCNAME}: only one argument is allowed."
fi
if [[ ${yaml_config} == 'yes' ]]; then
if [[ ${opt_yaml} == 'yes' ]]; then
std::info \
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
fi
@@ -330,7 +341,7 @@ readonly -f pbuild::version_eq
# Default is all.
#
pbuild::supported_compilers() {
if [[ ${yaml_config} == 'yes' ]]; then
if [[ ${opt_yaml} == 'yes' ]]; then
std::info \
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
fi
@@ -353,7 +364,7 @@ readonly -f pbuild.supported_compilers
# Default is all.
#
pbuild::supported_systems() {
if [[ ${yaml_config} == 'yes' ]]; then
if [[ ${opt_yaml} == 'yes' ]]; then
std::info \
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
fi
@@ -385,15 +396,23 @@ readonly -f pbuild::use_flag
# $1 download URL
# $2 optional file-name (of)
pbuild::set_download_url() {
if [[ ${opt_yaml} == 'yes' ]]; then
std::info \
"Using ${FUNCNAME} is deprecated with YAML module configuration files."
fi
pbuild.set_urls "$@"
}
readonly -f pbuild::set_download_url
pbuild.set_urls(){
local -i _i=${#SOURCE_URLS[@]}
SOURCE_URLS[_i]="$1"
SOURCE_URLS[_i]=$1
if (( $# > 1 )); then
SOURCE_NAMES[$_i]="${2:-${1##*/}}"
SOURCE_NAMES[$_i]=${2:-${1##*/}}
else
SOURCE_NAMES[$_i]="${1##*/}"
fi
}
readonly -f pbuild::set_download_url
#..............................................................................
#
@@ -604,10 +623,8 @@ pbuild::prep() {
local dir=''
local key="${SOURCE_NAMES[i]}"
if [[ -v SOURCE_UNPACK_DIRS[${key}] ]]; then
echo "dir specified"
dir="${SOURCE_UNPACK_DIRS[${key}]}"
else
echo "use SRC_DIR"
dir="${SRC_DIR}"
fi
unpack "${source_fname}" "${dir}"
@@ -642,6 +659,10 @@ pbuild::use_cmake() {
}
readonly -f pbuild::use_cmake
pbuild.configure_with(){
configure_with="$1"
}
#..............................................................................
#
# Use this C-compiler
@@ -665,10 +686,17 @@ readonly -f pbuild::use_cc
# Arguments:
# none
#
declare -- compile_in_sourcetree='No'
pbuild::compile_in_sourcetree() {
BUILD_DIR="${SRC_DIR}"
compile_in_sourcetree='Yes'
}
readonly -f pbuild::compile_in_sourcetree
pbuild.compile_in_sourcetree(){
if [[ "${1,,}" == 'Yes' ]]; then
compile_in_sourcetree='Yes'
fi
}
#..............................................................................
#
@@ -697,7 +725,7 @@ pbuild::configure() {
;;
esac
if [[ -r "${SRC_DIR}/configure" ]] && \
[[ "${configure_with}" == 'undef' ]] || \
[[ "${configure_with}" == 'auto' ]] || \
[[ "${configure_with}" == 'autotools' ]]; then
${SRC_DIR}/configure \
--prefix="${PREFIX}" \
@@ -706,7 +734,7 @@ pbuild::configure() {
"%s " "${module_name}/${module_version}:" \
"configure failed"
elif [[ -r "${SRC_DIR}/CMakeLists.txt" ]] && \
[[ "${configure_with}" == 'undef' ]] || \
[[ "${configure_with}" == 'auto' ]] || \
[[ "${configure_with}" == "cmake" ]]; then
# note: in most/many cases a cmake module is used!
cmake \
@@ -733,15 +761,22 @@ pbuild::configure() {
#
# Default compile function.
#
# Note:
# Makefiles generated by autotools can fail if the environemnt variable
# V is set.
#
# Arguments:
# none
#
pbuild::compile() {
local v_save="$V"
unset V
(( JOBS == 0 )) && JOBS=$(_get_num_cores)
${make} -j${JOBS} || \
std::die 3 \
"%s " "${module_name}/${module_version}:" \
"compilation failed!"
declare -g V="${v_save}"
}
##############################################################################
@@ -820,9 +855,9 @@ pbuild::install_shared_libs() {
# The following two functions are the entry points called by modbuild!
#
declare yaml_config='yes'
declare opt_yaml='yes'
pbuild.build_module_legacy(){
yaml_config='no'
opt_yaml='no'
_build_module "$@"
}
readonly -f pbuild.build_module_legacy
@@ -1091,29 +1126,21 @@ _build_module() {
VERSIONS+=( ${V_MAJOR} )
}
local -r module_name="$1"
local -r module_version="$2"
P="$1"
V="$2"
declare -g BUILD_ROOT="${PMODULES_TMPDIR}/${module_name}-${module_version}"
parse_version "${V}"
declare -g BUILD_ROOT="${PMODULES_TMPDIR}/${P}-${V}"
SRC_DIR="${BUILD_ROOT}/src"
BUILD_DIR="${BUILD_ROOT}/build"
# P and V can be used in the build-script, so we have to set them here
P="${module_name}"
V="${module_version}"
parse_version "${module_version}"
if [[ "${compile_in_sourcetree,,}" == 'yes' ]]; then
BUILD_DIR="${SRC_DIR}"
else
BUILD_DIR="${BUILD_ROOT}/build"
fi
declare -g PREFIX=''
SOURCE_URLS=()
SOURCE_SHA256_SUMS=()
SOURCE_NAMES=()
declare -Ag SOURCE_UNPACK_DIRS=()
CONFIGURE_ARGS=()
PATCH_FILES=()
PATCH_STRIPS=()
PATCH_STRIP_DEFAULT='1'
MODULE_DOCFILES=()
configure_with='undef'
} # init_build_environment()
#......................................................................
@@ -1405,10 +1432,6 @@ _build_module() {
cleanup_modulefiles(){
local ol=''
for ol in "${Overlays[@]}"; do
local i
for ((i=0; i<${#mod_overlays[@]}; i++ )); do
[[ "${ol}" == "${mod_overlays[i]}" ]] && continue 2
done
[[ "${ol}" == "${ol_name}" ]] && continue
local mod_root="${OverlayInfo[${ol}:mod_root]}"
local dir="${modulefile_dir/${ol_mod_root}/${mod_root}}"
+690 -242
View File
File diff suppressed because it is too large Load Diff
+96 -47
View File
@@ -26,7 +26,8 @@ declare -r libexecdir="${prefix}/libexec"
source "${libdir}/libstd.bash"
source "${libdir}/libpmodules.bash"
declare -r os_name="$(uname -s)"
declare -r os_name=$(uname -s)
declare -r os_release=$(std::get_os_release)
path="${libexecdir}:/bin:/usr/bin"
std::def_cmds "${path}" \
@@ -278,39 +279,89 @@ die_is_blocked(){
"module is blocked on this system" "$1"
}
#
# get release stage of module
# Note:
# - the release stage of a module outside ${OverlayInfo[@]} is always 'stable'
# - the release stage of a module inside ${OverlayInfo[@]} without a
# coresponding file is always 'unstable'
#
# Args:
# $1 reference variable to return release stage
# $2 modulefile directory (element of MODULEPATH)
# $3 module name/version
#
get_release_stage() {
local -n grs_rel_stage="$1"
get_module_config(){
: "
Read module configuration.
If a file '.config-<version>' exists, read configuration from this
file. The file must be in YAML format. The following keys are
supported:
RelStage: <relstage>
Systems: <list-of-systems>
Blocklist: <list-of-host-names>
If the above configuration file doesn't exist, get the release
stage from '.release-<version>'. Restrictions to systems or blocking
hosts is not possible.
Note:
- the release stage of a module outside our hierarchy is always
'stable'.
- the release stage of a module inside out hierarchy without a
config file is always 'unstable'.
"
local -n ref_cfg="$1"
local -r dir="$2"
local -r modulefile="${dir}/$3"
ref_cfg['rel_stage']='unstable'
ref_cfg['systems']=''
ref_cfg['blocklist']=''
if [[ ! -v Dir2OverlayMap[${dir%/${PMODULES_MODULEFILES_DIR}*}] ]]; then
grs_rel_stage='stable'
# this module is not in an overlay
ref_cfg['rel_stage']='stable'
return
fi
#
# In an overlay the name of the module-file is something like
# dir/modulefiles/name/version
# the corresponding file is
# dir/modulefiles/name/.release-version
#
local -r config_file="${modulefile%/*}/.config-${modulefile##*/}"
local -r rel_stage_file="${modulefile%/*}/.release-${modulefile##*/}"
if [[ -r ${rel_stage_file} ]]; then
# read file, remove empty lines, spaces etc
grs_rel_stage=$( < "${rel_stage_file}" )
if [[ -r ${config_file} ]]; then
local -- yaml=$(${yq} -e '.')
local -- key=''
for key in ${!ref_cfg[@]}; do
case "${key,,}" in
systems | blocklist )
value=$( ${yq} -e ".${key}[]" \
2>/dev/null <<<"${yaml}") ||
value='null'
;;
* )
value=$( ${yq} -e ".${key}" \
2>/dev/null <<<"${yaml}") ||
value='null'
;;
esac
if [[ "${value}" != 'null' ]]; then
ref_cfg[${key}]="${value}"
fi
done
return 0
elif [[ -r ${rel_stage_file} ]]; then
ref_cfg['rel_stage']=$( < "${rel_stage_file}" )
else
grs_rel_stage='unstable'
ref_cfg['rel_stage']='unstable'
fi
}
is_available(){
: "
Module is available if
- release stage is used
- the systems list is empty or the system is in the list
- the blocklist is empty or the hostname is NOT in the list
"
local -n ref_cfg="$1"
local -- rel_stages="$2"
local -- system="$3"
local -- hostname="$4"
[[ ":${rel_stages}:" =~ ":${ref_cfg['rel_stage']}:" ]] || return 1
if [[ "${ref_cfg['systems']}" != "" ]]; then
[[ "${ref_cfg['systems']//$'\n'/:}:" =~ "${system}" ]] || return 1
fi
if [[ "${ref_cfg['blocklist']}" != "" ]]; then
[[ "${ref_cfg['blocklist']//$'\n'/:}:" =~ "${hostname}" ]] && return 1
fi
}
@@ -1080,10 +1131,11 @@ get_available_modules() {
add='yes' # module is NOT in an overlay
fi
[[ "${add}" == 'no' ]] && continue
get_release_stage rel_stage "${dir}" "${mod}"
[[ :${used_rel_stages}: =~ :${rel_stage}: ]] || continue
local -A cfg=()
get_module_config cfg "${dir}" "${mod}"
is_available cfg "${used_rel_stages}" "${os_release}" "${HOSTNAME}" || continue
gam_mods+=( "${mod}" ${rel_stage} "${dir}/${mod}" "${ol}" )
gam_mods+=( "${mod}" "${cfg['rel_stage']}" "${dir}/${mod}" "${ol}" )
dict[${sdirs}/${mod}]=1
done < <(${find} -L "${dir_entries[@]}" \
\( -type f -o -type l \) \
@@ -1123,9 +1175,9 @@ find_modulefile() {
local -i col=$((${#dir} + 2 ))
local -a modules
if [[ ${module} == */* ]]; then
# a version number has been specified. But we still might
# have the same module/version with different use flags.
# The different release stages we ignore in this case.
# a version number has been specified. The first module
# found will be returned, independend from the release
# stage.
modules=( $(${find} -L "${dir}" -type f -not -name ".*" \
-ipath "${dir}/${module}*" \
| cut -b${col}-) )
@@ -1137,19 +1189,19 @@ find_modulefile() {
else
continue
fi
get_release_stage \
fm_rel_stage \
"${dir}" \
"${mod}"
local -A cfg=()
get_module_config cfg "${dir}" "${mod}"
is_available cfg "${ReleaseStages}" "${os_release}" "${HOSTNAME}" || continue
fm_modulefile="${dir}/${mod}"
fm_rel_stage="${cfg['rel_stage']}"
fm_dir="${dir}"
return 0
done
else
# no version has been specified. This makes it more
# difficult. We have to load the newest version taking
# the used release stages and flags into account.
# the used release stages into account.
# get list of reverse sorted version numbers
(( col += ${#module} + 1 ))
@@ -1168,16 +1220,13 @@ find_modulefile() {
else
continue
fi
get_release_stage \
fm_rel_stage \
"${dir}" \
"${mod}"
# don't load modules with unused release stages
if [[ :${UsedReleaseStages}: =~ :${fm_rel_stage}: ]]; then
fm_modulefile="${dir}/${mod}"
fm_dir="${dir}"
return 0
fi
local -A cfg=()
get_module_config cfg "${dir}" "${mod}"
is_available cfg "${ReleaseStages}" "${os_release}" "${HOSTNAME}" || continue
fm_modulefile="${dir}/${mod}"
fm_rel_stage="${cfg['rel_stage']}"
fm_dir="${dir}"
return 0
done
fi
done