From f15209ee280fc19f9fc3938bb14c6931cec47475 Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Tue, 3 Mar 2015 17:27:16 +0100 Subject: [PATCH] scripts/Bootstrap/Pmodules/init_local_env.bash: almost rewritten --- .../Bootstrap/Pmodules/init_local_env.bash | 263 ++++++++++-------- 1 file changed, 151 insertions(+), 112 deletions(-) diff --git a/scripts/Bootstrap/Pmodules/init_local_env.bash b/scripts/Bootstrap/Pmodules/init_local_env.bash index d477b3d..434f54f 100755 --- a/scripts/Bootstrap/Pmodules/init_local_env.bash +++ b/scripts/Bootstrap/Pmodules/init_local_env.bash @@ -2,160 +2,199 @@ function usage() { - PROG=$(basename $0) - echo "Usage: $PROG --dir= [--user=]" - echo " Initializes a local module environment in " - echo " for user . must not exist yet." - echo " The parameter must only be present if" - echo " $PROG is executed as root." + local -r prog=$(basename $0) + echo "Usage: $prog [--user=] [--force] [--dry-run] " + echo " Initializes a local module environment in " + echo " for user . must not exist yet." + echo " The parameter must only be present if" + echo " $prog is executed as root." +} + +log() { + local -ri fd=$1 + local -r fmt="$2\n" + shift 2 + printf -- "$fmt" "$@" >> /dev/fd/$fd +} + +info() { + log 2 "$1\n" "${@:2}" +} + +error() { + log 2 "$1\n" "${@:2}" +} + +debug() { + [[ ${PSI_DEBUG} ]] || return 0 + log 2 "$@" +} + +die() { + local -ri ec=$1 + shift + local cout + if (( ec == 0)); then + cout='1' + else + cout='2' + fi + if [[ -n $@ ]]; then + local -r fmt=$1 + shift + log $cout "$fmt" "$@" + fi + exit $ec } declare force='no' +declare dry_run='no' +declare DRY='' +declare target_dirs=() while (($# > 0)); do if [[ "${1#--dir}" != "$1" ]]; then option="${1#--dir}" option="${option#=}" [[ -z "$option" ]] && { shift; option="$1"; } - ENV_DIR="$option" + {target_dir}="$option" elif [[ "${1#--user}" != "$1" ]]; then option="${1#--user}" option="${option#=}" [[ -z "$option" ]] && { shift; option="$1"; } ENV_USER="$option" - else + elif [[ "$1" == "--force" ]]; then + force='yes' + elif [[ "$1" == "--dry-run" ]]; then + dry_run='yes' + DRY='echo' + elif [[ "$1" =~ "^-" ]]; then echo "Error: Unknown option: $1" usage exit 1 + else + target_dirs+=( "$1" ) fi shift done -[[ -z "$ENV_DIR" ]] && { - echo "Error: --dir parameter is required!" +if [[ ${#target_dirs[@]} == 0 ]]; then + echo "Error: no target directory specified!" usage exit 1 -} +fi if (( EUID == 0 )); then - [[ -z "$ENV_USER" ]] && { + if [[ -z "$ENV_USER" ]]; then echo "Error: --user parameter is required!" usage exit 1 - } + fi USER_ID=$(id -u "$ENV_USER") - (( $? == 0 )) || { + if (( $? != 0 )); then echo "Error: Unable to retrieve user id of user '$ENV_USER'" exit 1 - } + fi else - [[ -z "$ENV_USER" ]] || { + if [[ -n "$ENV_USER" ]]; then echo "Error: --user option is only allowed if running as root!" usage exit 1 - } + fi USER_ID=$EUID fi -if [[ -d "$ENV_DIR" ]] && [[ ${force} == no ]]; then - echo "Warning: $ENV_DIR already exists." - read -p "Do you really want to re-run the initialization? (y/N) " ans - case ${ans} in - y|Y ) - : - ;; - * ) - exit 1 - ;; - esac -fi - -echo "Attempting to create a local module environment from a partial copy of the environment at '$PSI_PREFIX'" - -[[ -d "$PSI_PREFIX" ]] && -[[ -d "$PSI_PREFIX/$PSI_CONFIG_DIR" ]] && -[[ -d "$PSI_PREFIX/$PSI_MODULES_ROOT" ]] && -[[ -d "$MODULESHOME" ]] || { - echo "Error: the module environment '$PSI_PREFIX' has not been initialized properly!" - echo "Maybe it is not a module environment, not accessible, or the init script at" - echo "'$PSI_PREFIX/config/profile.bash' has not been sourced." - exit 1 +[[ -n "${PSI_PREFIX}" ]] && +[[ -n "${PSI_CONFIG_DIR}" ]] && +[[ -n "${PSI_MODULES_ROOT}" ]] && +[[ -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!" } -echo "Creating directory $ENV_DIR..." -mkdir -p "$ENV_DIR" || { - echo "Error: cannot create directory $ENV_DIR!" - exit 1 -} -pushd "$ENV_DIR" || { - echo "Error: Cannot change to directory $ENV_DIR" - rmdir "$ENV_DIR" - exit -} -ENV_DIR=$(pwd -P) -popd -trap "rm -rf $ENV_DIR" EXIT -(( EUID == 0 )) && { - echo "Changing owner of directory $ENV_DIR to $ENV_USER..." - chown $USER_ID "$ENV_DIR" - su $ENV_USER || { - echo "Error: cannot change user to $ENV_USER!" - exit 1 - } +[[ -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!" } -(( EUID == USER_ID )) || { - echo "Error: attempt to run as user with id $USER_ID failed!" - exit 1 +echo " +Attempting to create a minimal module environment from the +environment at '${PSI_PREFIX}' +" + +function init_pmodules_environment() { + local -r target_dir=$1 + local src='' + local dst='' + echo "Initializing target directory '${target_dir}' ..." + if [[ -d "${target_dir}" ]] && [[ ${force} == no ]]; then + echo "Warning: ${target_dir} already exists." + read -p "Do you really want to re-run the initialization? (y/N) " ans + case ${ans} in + y|Y ) + : + ;; + * ) + exit 1 + ;; + esac + fi + + dst="${target_dir}" + echo "Creating target directory '${src}'..." + $DRY mkdir -p "${dst}" || die 1 "Error: make directory failed!" + echo + + src="${PSI_PREFIX}/${PSI_CONFIG_DIR}/" + dst="${target_dir}/${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_dir}/${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 + + src="${PMODULES_HOME}/" + dst="${target_dir}/${PMODULES_HOME#$PSI_PREFIX/}/" + echo "Synching Pmodules software from '${src}' to '${dst}'..." + $DRY mkdir -p "${dst}" || die 1 "Error: creating target directory failed!" + $DRY rsync --recursive --links --perms --delete \ + "${src}" "${dst}" || die 1 "Error: synch operation failed!" + echo + + src="${PSI_PREFIX}/${PSI_MODULES_ROOT}/Tools/Pmodules" + dst="${target_dir}/${PSI_MODULES_ROOT}/Tools/Pmodules" + echo "Setting up modulefile for Pmodules in '${dst}'..." + $DRY mkdir -p "${dst}" || die 1 "Error: make directory failed!" + $DRY ln -fs "../../../${PSI_TEMPLATES_DIR}/Tools/Pmodules/modulefile" \ + "${dst}/${PMODULES_VERSION}" || die 1 "Error: setting sym-link failed!" + $DRY cp "${src}/.release-${PMODULES_VERSION}" "${dst}" || die 1 "Error: setting release failed!" + echo + if [[ -n "${ENV_USER}" ]]; then + echo "Changing user of new module environment to '${ENV_USER}'..." + $DRY chown -R "${ENV_USER}" "${target_dir}" || die 1 "Error: changing owner failed!" + echo + fi + echo "New minimal module environment created at '${target_dir}'." + echo "To use this environment, execute" + echo " ln -s ${target_dir} /opt/psi as root (delete the /opt/psi link if it already exists)" + echo " source ${target_dir}/$PSI_CONFIG_DIR/profile.bash" } -cd "$ENV_DIR" || { - echo "Error: failed to change working directory to $ENV_DIR!" - exit 1 -} - -echo "Copy configuration..." -rsync --recursive --links --perms --delete ${PSI_PREFIX}/${PSI_CONFIG_DIR}/ ${PSI_CONFIG_DIR}/ || { - echo "Error: copy operation failed!" - exit 1 -} - -echo "Copy template files..." -rsync --recursive --links --perms --delete ${PSI_PREFIX}/${PSI_TEMPLATES_DIR}/ ${PSI_TEMPLATES_DIR}/ || { - echo "Error: copy operation failed!" - exit 1 -} - -echo "Copy module software..." -DST_PMODULES_HOME=${PMODULES_HOME#$PSI_PREFIX/} -mkdir -p ${DST_PMODULES_HOME} || { - echo "Error: creating directory for modules software failed!" - exit 1 -} -rsync --recursive --links --perms --delete ${PMODULES_HOME}/ ${DST_PMODULES_HOME}/ || { - echo "Error: copying modules software failed!" - exit 1 -} - -echo "Create directory $PSI_MODULES_ROOT..." -mkdir -p $PSI_MODULES_ROOT || { - echo "Error: cannot create directory $PSI_MODULES_ROOT!" - exit 1 -} - -echo "Create directory $PSI_MODULES_ROOT/Tools/Pmodules..." -mkdir -p "${PSI_MODULES_ROOT}/Tools/Pmodules" || { - echo "Error: cannot create directory ${PSI_MODULES_ROOT}/Tools/Pmodules!" - exit 1 -} - -ln -fs "../../../${PSI_TEMPLATES_DIR}/Tools/Pmodules/modulefile" "${PSI_MODULES_ROOT}/Tools/Pmodules/${PMODULES_VERSION}" -cp "${PSI_PREFIX}/${PSI_MODULES_ROOT}/Tools/Pmodules/.release-${PMODULES_VERSION}" "${PSI_MODULES_ROOT}/Tools/Pmodules" - -echo "Local module environment created at $ENV_DIR." -echo "To use this environment, execute" -echo " ln -s $ENV_DIR /opt/psi as root (delete the /opt/psi link if it already exists)" -echo " source $ENV_DIR/$PSI_CONFIG_DIR/profile.bash" - -trap - EXIT +umask 022 +for target_dir in "${target_dirs[@]}"; do + init_pmodules_environment "${target_dir}" +done