Commit 612040c8 authored by gsell's avatar gsell
Browse files

Merge branch 'master' of gitorious.psi.ch:scicomp/psi-modules-buildenvironment

parents 3f19aa36 8ee8c3d9
#!/usr/bin/env bash
function usage() {
PROG=$(basename $0)
echo "Usage: $PROG --dir=<directory> [--user=<user>]"
echo " Initializes a local module environment in <directory>"
echo " for user <user>. <directory> must not exist yet."
echo " The <user> parameter must only be present if"
echo " $PROG is executed as root."
}
declare force='no'
while (($# > 0)); do
if [[ "${1#--dir}" != "$1" ]]; then
option="${1#--dir}"
option="${option#=}"
[[ -z "$option" ]] && { shift; option="$1"; }
ENV_DIR="$option"
elif [[ "${1#--user}" != "$1" ]]; then
option="${1#--user}"
option="${option#=}"
[[ -z "$option" ]] && { shift; option="$1"; }
ENV_USER="$option"
else
echo "Error: Unknown option: $1"
usage
exit 1
fi
shift
done
[[ -z "$ENV_DIR" ]] && {
echo "Error: --dir parameter is required!"
usage
exit 1
}
if (( EUID == 0 )); then
[[ -z "$ENV_USER" ]] && {
echo "Error: --user parameter is required!"
usage
exit 1
}
USER_ID=$(id -u "$ENV_USER")
(( $? == 0 )) || {
echo "Error: Unable to retrieve user id of user '$ENV_USER'"
exit 1
}
else
[[ -z "$ENV_USER" ]] || {
echo "Error: --user option is only allowed if running as root!"
usage
exit 1
}
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
}
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
}
}
(( EUID == USER_ID )) || {
echo "Error: attempt to run as user with id $USER_ID failed!"
exit 1
}
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 module software..."
LOCAL_MODHOME=${MODULESHOME#$PSI_PREFIX/}
mkdir -p ${LOCAL_MODHOME} || {
echo "Error: creating directory for modules software failed!"
exit 1
}
rsync --recursive --links --perms --delete ${MODULESHOME}/ ${LOCAL_MODHOME}/ || {
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 "Using sudo to set the link $PSI_PREFIX to $ENV_DIR..."
# sudo bash -c "rm -f $PSI_PREFIX && ln -s $ENV_DIR $PSI_PREFIX" || {
# echo "WARNING: The link $PSI_PREFIX could not be set to $ENV_DIR!"
# echo "Please set this link manually as root:"
# echo " ln -s $ENV_DIR $PSI_PREFIX"
# }
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
#!/bin/bash
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
}
#
# get answer to yes/no question
#
# $1: prompt
#
get_YN_answer() {
local -r prompt="$1"
local ans
read -p "${prompt}" ans
case ${ans} in
y|Y )
return 0;;
* )
return 1;;
esac
}
get_options() {
"${bindir}/getopt" "$@"
}
check_pmodules_env() {
[[ -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!"
[[ -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!"
}
# Local Variables:
# mode: sh
# sh-basic-offset: 8
# tab-width: 8
# End:
#!/bin/bash
declare -r bindir=$( cd $(dirname $0) && pwd -P )
"${bindir}/bash" "${bindir}/modmanage.bash" "$@"
#!@PMODULES_HOME@/bin/bash
shopt -s expand_aliases
declare -r bindir=$(cd $(dirname "$0") && pwd)
declare -r libdir=$(cd "${bindir}/../lib" && pwd)
source "${libdir}/libpmodules.bash"
print_version() {
echo "
Pmodules ${version} using Tcl Environment Modules @MODULES_VERSION@
Copyright GNU GPL v2
" 1>&2
}
usage() {
local -r prog=$(basename $0)
print_version
echo "
Usage: ${prog} [ switches ] [ subcommand ] [subcommand-args ]
Switches:
--dry-run do nothing
--force force overwrite
Available SubCommands and Args:
init [--src=<src>] [--user=<user>] --dst=<dst>
Initialize a new minimal Pmodule environment.
"
}
declare force='no'
declare dry_run='no'
declare DRY=''
declare subcommand=''
declare sargs=()
subcommand_help_init() {
echo "
init [--src=<src>] [--user=<user>] <dst>
Initialize a new minimal Pmodule environment in directory
<dst>. The <user> parameter must only be present if
${prog} is executed as root.
" 1>&2
}
subcommand_help() {
if [[ $# == 0 ]]; then
usage
elif typeset -F subcommand_help_$1 > /dev/null 2>&1 ; then
# help for sub-command
subcommand_help_$1
else
usage
fi
}
#
# Derive the relative module installation path
# from the relative modulefile path
#
# $1: relative module file path
#
get_module_prefix() {
local -a comp=( ${1//\// } ) # split rel.path into components
local path="${comp[0]}" # result path
local -i i
for ((i=1; i<${#comp[@]}; i+=2)); do
path+="/${comp[$((-i-1))]}/${comp[$((-i))]}"
done
echo "${path}"
}
#
# Derive the relative module release file path
# from the relative module file path
#
# $1: relative module file path
#
get_releasefile_name() {
echo "$(dirname "$1")/.release-$(basename "$1")"
}
#
# Sync a module from one Pmodules environment to another:
# - sync module installation
# - sync modulefile
# - sync release file
#
# $1: relative modulefile path
# $2: source prefix of Pmodule environment
# $3: target prefix of Pmodule environment
#
sync_module() {
local -r rel_modulefile=$1
local -r src_prefix=$2
local -r target_prefix=$3
local -r rel_module_prefix=$( get_module_prefix "${rel_modulefile}" )
local -r rel_releasefile=$( get_releasefile_name "${rel_modulefile}" )
mkdir -p "${target_prefix}/${rel_module_prefix}" || return $?
$DRY rsync --links --perms --recursive --delete \
"${src_prefix}/${rel_module_prefix}/" \
"${target_prefix}/${rel_module_prefix}/" || return $?
local dir=$( dirname "${target_prefix}/${PSI_MODULES_ROOT}/${rel_modulefile}" )
mkdir -p "${dir}" || return $?
$DRY rsync --links --perms --recursive \
"${src_prefix}/${PSI_MODULES_ROOT}/${rel_modulefile}" \
"${target_prefix}/${PSI_MODULES_ROOT}/${rel_modulefile}" \
|| return $?
$DRY rsync --links --perms --recursive \
"${src_prefix}/${PSI_MODULES_ROOT}/${rel_releasefile}" \
"${target_prefix}/${PSI_MODULES_ROOT}/${rel_releasefile}" \
|| return $?
}
subcommand_init() {
local src=''
local target_prefixes=()
local user=''
local opts=''
opts=$(get_options -o h -l src: -l user: -l help -- "$@")
if [[ $? != 0 ]]; then
subcommand_help_init
exit 1
fi
eval set -- "${opts}"
while (($# > 0)); do
case $1 in
--src )
src=$2
shift
;;
--user )
user=$2
shift
;;
-- )
:
;;
-* | -h | --help )
echo "$1: illegal option" 1>&2
subcommand_help_init
exit 1
;;
* )
target_prefixes+=( "$1" )
;;
esac
shift
done
(( ${#target_prefixes[@]} != 0 )) || die 1 "Error: no target directory specified!"
if [[ -n "${src}" ]]; then
[[ -d "${src}" ]] || die 1 "Error: ${src}: source directory does not exist!"
[[ -r "${src}/config/profile.bash" ]] || \
die 1 "Error: ${src}: shell profile does not exist or is not readable!"
source "${src}/config/profile.bash"
fi
local -i euid=$(id -u)
if (( euid == 0 )); then
[[ -n "$ENV_USER" ]] || \
die 1 "Error: --user parameter is required!"
id -u "$ENV_USER" > /dev/null 2>&1 || \
die 1 "Error: Unable to retrieve user id of user '$ENV_USER'"
else
[[ -z "$ENV_USER" ]] || \
die 1 "Error: --user option is only allowed if running as root!"
fi
check_pmodules_env || die 1 "Giving up ..."
echo "
Attempting to create a minimal module environment from the
environment at '${PSI_PREFIX}'
"
init_pmodules_environment() {
local -r target_prefix=$1
local src=''
local dst=''
echo "Initializing target directory '${target_prefix}' ..."
echo
if [[ -d "${target_prefix}" ]] && [[ ${force} == no ]]; then
echo "Warning: ${target_prefix} already exists."
get_YN_answer "Do you really want to re-run the initialization? (y/N) " \
die 1 "Abort ..."
fi
echo "Creating target directory '${target_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 Pmodules ..."
sync_module "Tools/Pmodules/${PMODULES_VERSION}" \
"${PSI_PREFIX}" \
"${target_prefix}" || die 1 "Error: sync Pmodules failed!"
echo
if [[ -n "${ENV_USER}" ]]; then
echo "Changing user of new module environment to '${ENV_USER}'..."
$DRY chown -R "${ENV_USER}" "${target_prefix}" || die 1 "Error: changing owner failed!"
echo
fi
echo "New minimal module environment created at '${target_prefix}'."
echo "To use this environment, execute"
echo " sudo ln -fs ${target_prefix} /opt/psi"
echo " source /opt/psi/${PSI_CONFIG_DIR}/profile.bash"
}
umask 022
for target_prefix in "${target_prefixes[@]}"; do
init_pmodules_environment "${target_prefix}"
done
}
while (($# > 0)); do
case $1 in
-h | -H | -\? | --help | -help )
usage
exit 1
;;
-V | --version )
print_version
exit 1
;;
-f | --force )
force='yes'
;;
--dry-run )
dry_run='yes'
DRY='echo'
;;
-* )
echo "$1: unknown switch.\n" 1>&2
exit 1
;;
init|help )
subcommand="subcommand_$1"
shift
sargs=( $* )
shift $#
;;
* )
echo "$1: unknown sub-command" 1>&2
exit 1
esac
shift
done
$subcommand "${sargs[@]}"
# Local Variables:
# mode: sh
# sh-basic-offset: 8
# tab-width: 8
# End:
......@@ -47,7 +47,7 @@ Switches:
-c|--create create caches for avail and apropos
-i|--icase ignored
-u|--userlvl <lvl> set user level to (nov[ice],exp[ert],adv[anced])
Available SubCommands and Args:
Available SubCommands and Args:
+ add|load modulefile [modulefile ...]
+ rm|unload modulefile [modulefile ...]
+ switch|swap [modulefile1] modulefile2
......
This diff is collapsed.
......@@ -12,7 +12,8 @@ source "/opt/psi/config/environment.bash"
sed_cmd="s:@PMODULES_HOME@:${PMODULES_HOME}:g;"
sed_cmd+="s:@PMODULES_VERSION@:${PMODULES_VERSION}:g;"
sed_cmd+="s:@MODULES_VERSION@:${MODULES_VERSION}:g"
sed "${sed_cmd}" "${SRC_DIR}/modulecmd.bash" > "${SRC_DIR}/modulecmd"
sed "${sed_cmd}" "${SRC_DIR}/modulecmd.in" > "${SRC_DIR}/modulecmd"
sed "${sed_cmd}" "${SRC_DIR}/modmanage.in" > "${SRC_DIR}/modmanage.bash"
install -d -m 0755 "${PMODULES_HOME}/bin"
install -d -m 0755 "${PMODULES_HOME}/config"
......@@ -20,8 +21,8 @@ install -d -m 0755 "${PMODULES_HOME}/init"
install -d -m 0755 "${PMODULES_HOME}/lib"
install -m 0755 "${SRC_DIR}/modulecmd" "${PMODULES_HOME}/bin"
install -m 0755 "${SRC_DIR}/init_local_env.bash" "${PMODULES_HOME}/bin"
install -m 0755 "${SRC_DIR}/modsync.bash" "${PMODULES_HOME}/bin"
install -m 0755 "${SRC_DIR}/modmanage" "${PMODULES_HOME}/bin"
install -m 0755 "${SRC_DIR}/modmanage.bash" "${PMODULES_HOME}/bin"
install -m 0755 "${SRC_DIR}/dialog.bash" "${PMODULES_HOME}/bin"
install -m 0755 "${SRC_DIR}/environment.bash" "${PMODULES_HOME}/config"
......@@ -30,4 +31,5 @@ install -m 0755 "${SRC_DIR}/profile.bash" "${PMODULES_HOME}/config"
install -m 0644 "${SRC_DIR}/bash" "${PMODULES_HOME}/init"
install -m 0644 "${SRC_DIR}/bash_completion" "${PMODULES_HOME}/init"
install -m 0644 "${SRC_DIR}/libpmodules.bash" "${PMODULES_HOME}/lib"
install -m 0644 "${SRC_DIR}/libmodules.tcl" "${PMODULES_HOME}/lib"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment