Merged with newest version of Achim
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Hardcoded path to dialog software
|
||||
LOCAL_DIALOGHOME=Tools/dialog/1.2.1
|
||||
DIALOG_CMD=$PSI_PREFIX/$LOCAL_DIALOGHOME/bin/dialog
|
||||
DIALOG_CMD=$PMODULES_HOME/bin/dialog
|
||||
|
||||
declare -a modlist # module info
|
||||
declare -A selected # module info indices selected
|
||||
@@ -338,9 +337,9 @@ function module_picker() {
|
||||
|
||||
# if DIALOG_LIB is NOT set, call module picker
|
||||
[[ ${DIALOG_LIB:+"is_lib"} == "is_lib" ]] || {
|
||||
if [[ -x ${PSI_PREFIX}/${PSI_CONFIG_DIR}/modulecmd.bash ]]; then
|
||||
module_picker "$1" < <(${PSI_PREFIX}/${PSI_CONFIG_DIR}/modulecmd.bash bash search --no-header -a 2>&1)
|
||||
if [[ -x ${PMODULES_HOME}/bin/modulecmd ]]; then
|
||||
module_picker "$1" < <(${PMODULES_HOME}/bin/modulecmd bash search --no-header -a 2>&1)
|
||||
else
|
||||
echo "ERROR: module environment configuration: ${PSI_PREFIX}/${PSI_CONFIG_DIR}/modulecmd.bash is not an executable!"
|
||||
echo "ERROR: module environment configuration: ${PMODULES_HOME}/bin/modulecmd is not an executable!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ die() {
|
||||
cout='1'
|
||||
else
|
||||
cout='2'
|
||||
fi
|
||||
fi
|
||||
if [[ -n $@ ]]; then
|
||||
local -r fmt=$1
|
||||
shift
|
||||
@@ -47,7 +47,7 @@ get_YN_answer() {
|
||||
local ans
|
||||
read -p "${prompt}" ans
|
||||
case ${ans} in
|
||||
y|Y )
|
||||
y|Y )
|
||||
return 0;;
|
||||
* )
|
||||
return 1;;
|
||||
@@ -65,15 +65,14 @@ check_pmodules_env() {
|
||||
[[ -n "${PSI_TEMPLATES_DIR}" ]] &&
|
||||
[[ -n "${PMODULES_HOME}" ]] &&
|
||||
[[ -n "${PMODULES_VERSION}" ]] || die 1 "
|
||||
Error: the module environment you are going to use as source has not been
|
||||
initialized properly!"
|
||||
Error: not running within a valid module environment!"
|
||||
|
||||
[[ -d "${PSI_PREFIX}" ]] &&
|
||||
[[ -d "${PSI_PREFIX}/${PSI_CONFIG_DIR}" ]] &&
|
||||
[[ -d "${PSI_PREFIX}/${PSI_MODULES_ROOT}" ]] &&
|
||||
[[ -d "${PSI_PREFIX}/${PSI_TEMPLATES_DIR}" ]] &&
|
||||
[[ -d "${PMODULES_HOME}" ]] || die 1 "
|
||||
Error: the module environment '$PSI_PREFIX' has not been initialized properly!"
|
||||
Error: the module environment '$PSI_PREFIX' is invalid!"
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -30,9 +30,12 @@ Available SubCommands and Args:
|
||||
|
||||
install <module> [--with=<dep>...]
|
||||
Install matching modules
|
||||
|
||||
sync [--delete] [--dst=<dst>] <src>
|
||||
Synchronize modules.
|
||||
"
|
||||
}
|
||||
|
||||
|
||||
|
||||
declare force='no'
|
||||
declare dry_run='no'
|
||||
@@ -56,6 +59,17 @@ install <module> [--with=<dep>...]
|
||||
" 1>&2
|
||||
}
|
||||
|
||||
subcommand_help_sync() {
|
||||
echo "
|
||||
sync [--delete] [--dst=<dst>] <src>
|
||||
Synchronize environment modules and configuration files
|
||||
from Pmodule environment <src> to Pmodule environment <dst>
|
||||
(default: currently active Pmodule environment).
|
||||
If --delete is given, unmarked modules present in <dst>
|
||||
will be deleted.
|
||||
" 1>&2
|
||||
}
|
||||
|
||||
subcommand_help() {
|
||||
if [[ $# == 0 ]]; then
|
||||
usage
|
||||
@@ -135,6 +149,26 @@ sync_module() {
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Sync the Pmodules configuration and templates
|
||||
#
|
||||
# $1: source prefix of Pmodule environment
|
||||
# $2: target prefix of Pmodule environment
|
||||
#
|
||||
sync_config() {
|
||||
src="$1/${PSI_CONFIG_DIR}/"
|
||||
dst="$2/${PSI_CONFIG_DIR}/"
|
||||
$DRY rsync --recursive --links --perms --delete \
|
||||
"${src}" "${dst}" || die 1 "Error: synch operation failed!"
|
||||
echo
|
||||
|
||||
src="$1/${PSI_TEMPLATES_DIR}/"
|
||||
dst="$2/${PSI_TEMPLATES_DIR}/"
|
||||
$DRY rsync --recursive --links --perms --delete \
|
||||
"${src}" "${dst}" || die 1 "Error: synch operation failed!"
|
||||
echo
|
||||
}
|
||||
|
||||
subcommand_init() {
|
||||
local src=''
|
||||
local target_prefixes=()
|
||||
@@ -147,7 +181,7 @@ subcommand_init() {
|
||||
fi
|
||||
eval set -- "${opts}"
|
||||
while (($# > 0)); do
|
||||
case $1 in
|
||||
case $1 in
|
||||
--src )
|
||||
src=$2
|
||||
shift
|
||||
@@ -188,9 +222,9 @@ subcommand_init() {
|
||||
[[ -z "${user}" ]] || \
|
||||
die 1 "Error: --user option is only allowed if running as root!"
|
||||
fi
|
||||
|
||||
check_pmodules_env || die 1 "Giving up ..."
|
||||
|
||||
|
||||
check_pmodules_env || die 1 "Giving up..."
|
||||
|
||||
echo "
|
||||
Attempting to create a minimal module environment from the
|
||||
environment at '${PSI_PREFIX}'
|
||||
@@ -212,26 +246,16 @@ environment at '${PSI_PREFIX}'
|
||||
$DRY mkdir -p "${target_prefix}" || die 1 "Error: make directory failed!"
|
||||
echo
|
||||
|
||||
src="${PSI_PREFIX}/${PSI_CONFIG_DIR}/"
|
||||
dst="${target_prefix}/${PSI_CONFIG_DIR}/"
|
||||
echo "Synching configuration from '${src}' to '${dst}'..."
|
||||
$DRY rsync --recursive --links --perms --delete \
|
||||
"${src}" "${dst}" || die 1 "Error: synch operation failed!"
|
||||
echo
|
||||
|
||||
src="${PSI_PREFIX}/${PSI_TEMPLATES_DIR}/"
|
||||
dst="${target_prefix}/${PSI_TEMPLATES_DIR}/"
|
||||
echo "Synching template files from '${src}' to '${dst}'..."
|
||||
$DRY rsync --recursive --links --perms --delete \
|
||||
"${src}" "${dst}" || die 1 "Error: synch operation failed!"
|
||||
echo
|
||||
echo "Syncing configuration ..."
|
||||
sync_config "${PSI_PREFIX}" \
|
||||
"${target_prefix}" || die 1 "Error: configuration synchronization failed!"
|
||||
|
||||
echo "Syncing Pmodules ..."
|
||||
sync_module "Tools/Pmodules/${PMODULES_VERSION}" \
|
||||
"${PSI_PREFIX}" \
|
||||
"${target_prefix}" || die 1 "Error: sync Pmodules failed!"
|
||||
echo
|
||||
|
||||
|
||||
if [[ -n "${user}" ]]; then
|
||||
echo "Changing user of new module environment to '${user}'..."
|
||||
$DRY chown -R "${user}" "${target_prefix}" || die 1 "Error: changing owner failed!"
|
||||
@@ -290,6 +314,121 @@ subcommand_install() {
|
||||
${PMODULES_HOME}/bin/modulecmd bash search "${module_pattern[@]}" "${with[@]/#/--with}" "${releases[@]/#/--release=}" --no-header
|
||||
}
|
||||
|
||||
subcommand_sync() {
|
||||
local delete=false
|
||||
local opts=''
|
||||
local dst_prefix=''
|
||||
local source_prefix=''
|
||||
opts=$(get_options -o h -l dst: -l delete -l help -- "$@")
|
||||
if [[ $? != 0 ]]; then
|
||||
subcommand_help_sync
|
||||
exit 1
|
||||
fi
|
||||
eval set -- "${opts}"
|
||||
while (($# > 0)); do
|
||||
case $1 in
|
||||
--dst )
|
||||
dst_prefix="$2"
|
||||
shift
|
||||
;;
|
||||
--delete )
|
||||
delete=true
|
||||
;;
|
||||
-- )
|
||||
:
|
||||
;;
|
||||
-* | -h | --help )
|
||||
echo "$1: illegal option" 1>&2
|
||||
subcommand_help_init
|
||||
exit 1
|
||||
;;
|
||||
* )
|
||||
[[ -n "${source_prefix}" ]] && die 1 "Error: Only one source is allowed!"
|
||||
source_prefix="$1"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
unset -v opts
|
||||
if [[ -z "${dst_prefix}" ]]; then
|
||||
[[ -z "${PSI_PREFIX}" ]] && die 1 "Error: No current module environment and no destination specified!"
|
||||
dst_prefix="${PSI_PREFIX}"
|
||||
fi
|
||||
(
|
||||
PSI_PREFIX="${dst_prefix}" check_pmodules_env || die 1 "Error: invalid destination modules environment!"
|
||||
) || die 1 "Giving up..."
|
||||
(
|
||||
PSI_PREFIX="${src_prefix}" check_pmodules_env || die 1 "Error: invalid source modules environment!"
|
||||
) || die 1 "Giving up..."
|
||||
[[ "$( cd "$src_prefix"; pwd -P )" == "$( cd "$dst_prefix"; pwd -P )" ]] && die 1 "Error: source and destination are equal!"
|
||||
local modbin=${PMODULES_HOME#"${PSI_PREFIX}/"}/bin/modulecmd.tcl
|
||||
local file_type_src=$( file -b "${src_prefix}/${modbin}" 2>&1 || echo err1 )
|
||||
local file_type_dst=$( file -b "${dst_prefix}/${modbin}" 2>&1 || echo err2 )
|
||||
[[ "${file_type_src}" == "${file_type_dst}" ]] || die 1 "Error: The file signatures in the source and destination installation do not match!"
|
||||
unset -v file_type_src file_type_dst
|
||||
|
||||
local profile_script="${src_prefix}/${PSI_CONFIG_DIR}/profile.bash"
|
||||
[[ -r "${profile_script}" ]] || die 1 "Error: Unable to find profile script of installation $profile_script";
|
||||
local search_script="${src_prefix}/${modbin}/bin/modulecmd"
|
||||
[[ -x "${search_script}" ]] || die 1 "Error: Unable to find search script of installation $search_script";
|
||||
# local dialog_script="${src_prefix}/${modbin}/bin/dialog.bash"
|
||||
local dialog_script="./dialog.bash"
|
||||
[[ -r "$dialog_script" ]] || die 1 "Error: Unable to find dialog script of installation $dialog_script";
|
||||
|
||||
source "$profile_script" # set variables for the source installation
|
||||
DIALOG_LIB=1 # use dialog script as a library
|
||||
source "$dialog_script" # dialog functions
|
||||
|
||||
local -a selected_modules
|
||||
|
||||
# Redefine module_out to append modules to the selected_modules variable
|
||||
function module_out() {
|
||||
local -a args=(${modlist[$1]})
|
||||
local path=""
|
||||
IFS=/
|
||||
[[ -n "${args[3]}" ]] && path="/${args[*]:3}"
|
||||
unset IFS
|
||||
selected_modules+=( "${args[2]}${path}/${args[0]}" )
|
||||
}
|
||||
|
||||
module_picker "${dst_prefix}" < <("$search_script" bash search --no-header -a 2>&1) # this calls module_out for each selected module, filling up the selected_modules array
|
||||
|
||||
local -a destination_modules=( $(cd "${dst_prefix}/${PSI_MODULES_ROOT}"; find -L . -type f | while read f; do echo ${f#./}; done) )
|
||||
|
||||
# redefine set difference, the version in dialog.bash only handles integers
|
||||
function set_difference() { # $1 \ $2
|
||||
local -a operand1=($1)
|
||||
local -a operand2=($2)
|
||||
local -A members
|
||||
local elem
|
||||
for elem in "${operand1[@]}"; do
|
||||
members[$elem]=1
|
||||
done
|
||||
for elem in "${operand2[@]}"; do
|
||||
unset members[$elem]
|
||||
done
|
||||
echo ${!members[@]}
|
||||
}
|
||||
|
||||
if [[ "$delete" == "true" ]]; then
|
||||
local -a modules_delete=( $(set_difference "${destination_modules[*]}" "${selected_modules[*]}") )
|
||||
for m in "${modules_delete[@]}"; do
|
||||
delete_module "$m" "$dst_prefix"
|
||||
done
|
||||
unset modules_delete
|
||||
fi
|
||||
|
||||
local -a modules_copy=( $(set_difference "${selected_modules[*]}" "${destination_modules[*]}") )
|
||||
if [[ -n $modules_copy ]]; then
|
||||
echo "Syncing configuration ..."
|
||||
sync_config "$src_prefix" "$dst_prefix" || die 1 "Error: syncing the configuration failed"
|
||||
fi
|
||||
for m in "${modules_copy[@]}"; do
|
||||
sync_module "$m" "$src_prefix" "$dst_prefix" || die 1 "Error: syncing of module $m failed!"
|
||||
done
|
||||
unset modules_copy
|
||||
}
|
||||
|
||||
while (($# > 0)); do
|
||||
case $1 in
|
||||
-h | -H | -\? | --help | -help )
|
||||
@@ -311,7 +450,7 @@ while (($# > 0)); do
|
||||
echo "$1: unknown switch.\n" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
init|install|help )
|
||||
init|install|sync|help )
|
||||
subcommand="subcommand_$1"
|
||||
shift
|
||||
sargs=( $* )
|
||||
|
||||
Reference in New Issue
Block a user