From d152a516f50307b3a1de4ce38958f181aaa52bf8 Mon Sep 17 00:00:00 2001 From: Sylvester Joosten <sjoosten@anl.gov> Date: Thu, 30 Sep 2021 16:20:58 +0000 Subject: [PATCH] Macos support --- README.md | 74 ++++++----- install.sh | 356 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 286 insertions(+), 144 deletions(-) diff --git a/README.md b/README.md index 4a9724ab3..7b3e04d70 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,12 @@ EIC software container Simple Installation ------------ + +*The environment has been tested on linux (requires singularity v3+) and MacOS (requires +docker)* + +Please follow the steps below to setup and run the container in your environment. + 1. Create a local directory that you want to work in, e.g `$HOME/eic`, and go into this directory. ```bash @@ -25,44 +31,19 @@ eic-shell 4. Within your development environment (`eic-shell`), you can install software to the internal `$ATHENA_PREFIX` -Singularity Container Dowload for Development Usage +Singularity Container setup for Development Usage ------------- **Note: this container download script is meant for expert usage. If it is unclear to you -why you would want to do this, you are probably looking for the single installation +why you would want to do this, you are probably looking for the simple `jug_xl` installation above.** -To download the `jug_dev:testing` base image, do -```bash -curl https://eicweb.phy.anl.gov/containers/eic_container/-/raw/master/download_dev.sh | bash -``` -To download the `jug_xl:nightly` image, do + +You can use the same install scripts to setup other container setups, including `jug_dev` +(the main development container). Note that for `jug_dev` there is no nighlty release, and +the appropriate version (tag) would be `testing`. To setup the `jug_dev:testing` environment, do ```bash -curl https://eicweb.phy.anl.gov/containers/eic_container/-/raw/master/download_dev.sh | bash -s -- -c jug_xl -v nightly +curl https://eicweb.phy.anl.gov/containers/eic_container/-/raw/master/install.sh | bash -s -- -c jug_dev -v testing ``` -Using the docker container for your CI purposes ------------------------------------------------ - -The docker containers are publicly accessible from -[Dockerhub](https://hub.docker.com/u/eicweb). You probably want to use the default -`jug_xl` container. Relevant versions are: - - `eicweb/jug_xl:nightly`: nightly release, with latest detector and reconstruction - version. This is probably what you want to use unless you are dispatching a large - simulation/reconstruciton job - - `eicweb/jug_xl:3.0-stable`: latest stable release, what you want to use for large - simulation jobs (for reproducibility). Please coordinate with the software group to - ensure all desired software changes are present in this container. - -1. To load the container environment in your run scripts, you have to do nothing special. - The environment is already setup with good defaults, so you can use all the programs - in the container as usual and assume everything needed to run the included software - is already setup. - -2. If using this container as a basis for a new container, you can direction access - the full container environment from a docker `RUN` shell command with no further - action needed. For the most optimal experience, you can install your software to - `/usr/local` to fully integrate with the existing environment. (Note that, internally, - `/usr/local` is a symlink to `/opt/view`). - Included software: ------------------ - Included software (for the exact versions, check the file [spack.yaml](spack.yaml) or use the command `eic-info` inside the container): @@ -103,3 +84,32 @@ Included software: - igprof - The singularity build exports the following applications: - eic-shell: a development shell in the image + +Using the docker container for your CI purposes +----------------------------------------------- + +**These instructions are old and need updating. In general we recommend using +`eicweb/juggler:latest` for most CI usages. This image is functionally identical to +`jug_xl:nightly`** + +The docker containers are publicly accessible from +[Dockerhub](https://hub.docker.com/u/eicweb). You probably want to use the default +`jug_xl` container. Relevant versions are: + - `eicweb/jug_xl:nightly`: nightly release, with latest detector and reconstruction + version. This is probably what you want to use unless you are dispatching a large + simulation/reconstruciton job + - `eicweb/jug_xl:3.0-stable`: latest stable release, what you want to use for large + simulation jobs (for reproducibility). Please coordinate with the software group to + ensure all desired software changes are present in this container. + +1. To load the container environment in your run scripts, you have to do nothing special. + The environment is already setup with good defaults, so you can use all the programs + in the container as usual and assume everything needed to run the included software + is already setup. + +2. If using this container as a basis for a new container, you can direction access + the full container environment from a docker `RUN` shell command with no further + action needed. For the most optimal experience, you can install your software to + `/usr/local` to fully integrate with the existing environment. (Note that, internally, + `/usr/local` is a symlink to `/opt/view`). + diff --git a/install.sh b/install.sh index 6e31bca90..1de24d8c8 100755 --- a/install.sh +++ b/install.sh @@ -1,5 +1,12 @@ #!/bin/bash +## Simple setup script that installs the container +## in your local environment under $PREFIX/local/lib +## and creates a simple top-level launcher script +## that launches the container for this working directory +## with the $ATHENA_PREFIX variable pointing +## to the $PREFIX/local directory + CONTAINER="jug_xl" VERSION="nightly" PREFIX="$PWD" @@ -10,6 +17,7 @@ function print_the_help { echo " -p,--prefix Working directory to deploy the environment (D: $PREFIX)" echo " -t,--tmpdir Change tmp directory (D: $([[ -z "$TMPDIR" ]] && echo "/tmp" || echo "$TMPDIR"))" echo " -n,--no-cvmfs Disable check for local CVMFS (D: enabled)" + echo " -c,--container Container version (D: $CONTAINER)" echo " -v,--version Version to install (D: $VERSION)" echo " -h,--help Print this message" echo "" @@ -23,7 +31,7 @@ while [ $# -gt 0 ]; do key=$1 case $key in -p|--prefix) - PREFIX=$2 + PREFIX=$(realpath $2) shift shift ;; @@ -37,6 +45,11 @@ while [ $# -gt 0 ]; do DISABLE_CVMFS_USAGE=true shift ;; + -c|--container) + CONTAINER=$2 + shift + shift + ;; -v|--version) VERSION=$2 shift @@ -54,7 +67,9 @@ while [ $# -gt 0 ]; do esac done +## create prefix if needed mkdir -p $PREFIX || exit 1 +pushd $PREFIX if [ ! -d $PREFIX ]; then echo "ERROR: not a valid directory: $PREFIX" @@ -64,125 +79,123 @@ fi echo "Setting up development environment for eicweb/$CONTAINER:$VERSION" -## Simple setup script that installs the container -## in your local environment under $PREFIX/local/lib -## and creates a simple top-level launcher script -## that launches the container for this working directory -## with the $ATHENA_PREFIX variable pointing -## to the $PREFIX/local directory +mkdir -p $PREFIX/local/lib || exit 1 -mkdir -p local/lib || exit 1 +function install_linux() { + SINGULARITY= + ## check for a singularity install + ## default singularity if new enough + if [ $(type -P singularity ) ]; then + SINGULARITY=$(which singularity) + SINGULARITY_VERSION=`$SINGULARITY --version` + if [ ${SINGULARITY_VERSION:0:1} = 2 ]; then + ## too old, look for something else + SINGULARITY= + fi + fi + if [ -z $SINGULARITY ]; then + ## first priority: a known good install (this one is on JLAB) + if [ -d "/apps/singularity/3.7.1/bin/" ]; then + SINGULARITY="/apps/singularity/3.7.1/bin/singularity" + ## whatever is in the path is next + elif [ $(type -P singularity ) ]; then + SINGULARITY=$(which singularity) + ## cvmfs singularity is last resort (sandbox mode can cause issues) + elif [ -f "/cvmfs/oasis.opensciencegrid.org/mis/singularity/bin/singularity" ]; then + SINGULARITY="/cvmfs/oasis.opensciencegrid.org/mis/singularity/bin/singularity" + ## not good... + else + echo "ERROR: no singularity found, please make sure you have singularity in your \$PATH" + exit 1 + fi + fi + echo " - Found singularity at $SINGULARITY" -SINGULARITY= -## check for a singularity install -## default singularity if new enough -if [ $(type -P singularity ) ]; then - SINGULARITY=$(which singularity) + ## get singularity version + ## we only care if is 2.x or not, so we can use singularity --version + ## which returns 2.xxxxx for version 2 SINGULARITY_VERSION=`$SINGULARITY --version` + SIF= if [ ${SINGULARITY_VERSION:0:1} = 2 ]; then - ## too old, look for something else - SINGULARITY= - fi -fi -if [ -z $SINGULARITY ]; then - ## first priority: a known good install (this one is on JLAB) - if [ -d "/apps/singularity/3.7.1/bin/" ]; then - SINGULARITY="/apps/singularity/3.7.1/bin/singularity" - ## whatever is in the path is next - elif [ $(type -P singularity ) ]; then - SINGULARITY=$(which singularity) - ## cvmfs singularity is last resort (sandbox mode can cause issues) - elif [ -f "/cvmfs/oasis.opensciencegrid.org/mis/singularity/bin/singularity" ]; then - SINGULARITY="/cvmfs/oasis.opensciencegrid.org/mis/singularity/bin/singularity" - ## not good... - else - echo "ERROR: no singularity found, please make sure you have singularity in your \$PATH" - exit 1 - fi -fi -echo " - Found singularity at $SINGULARITY" - -## get singularity version -## we only care if is 2.x or not, so we can use singularity --version -## which returns 2.xxxxx for version 2 -SINGULARITY_VERSION=`$SINGULARITY --version` -SIF= -if [ ${SINGULARITY_VERSION:0:1} = 2 ]; then - SIF="$PREFIX/local/lib/${CONTAINER}-${VERSION}.simg" - - echo "WARNING: your singularity version $SINGULARITY_VERSION is ancient, we strongly recommend using version 3.x" - echo "We will attempt to use a fall-back SIMG image to be used with this singularity version" - if [ -f /gpfs02/eic/athena/${CONTAINER}-${VERSION}.simg ]; then - ln -sf /gpfs02/eic/athena/${CONTAINER}-${VERSION}.simg ${SIF} + SIF="$PREFIX/local/lib/${CONTAINER}-${VERSION}.simg" + + echo "WARNING: your singularity version $SINGULARITY_VERSION is ancient, we strongly recommend using version 3.x" + echo "We will attempt to use a fall-back SIMG image to be used with this singularity version" + if [ -f /gpfs02/eic/athena/${CONTAINER}-${VERSION}.simg ]; then + ln -sf /gpfs02/eic/athena/${CONTAINER}-${VERSION}.simg ${SIF} + else + echo "Attempting last-resort singularity pull for old image" + echo "This may take a few minutes..." + INSIF=`basename ${SIF}` + singularity pull --name "${INSIF}" docker://eicweb/$CONTAINER:$VERSION + mv ${INSIF} $SIF + chmod +x ${SIF} + unset INSIF + fi + ## we are in sane territory, yay! else - echo "Attempting last-resort singularity pull for old image" - echo "This may take a few minutes..." - INSIF=`basename ${SIF}` - singularity pull --name "${INSIF}" docker://eicweb/$CONTAINER:$VERSION - mv ${INSIF} $SIF - chmod +x ${SIF} - unset INSIF + ## check if we can just use cvmfs for the image + SIF="$PREFIX/local/lib/${CONTAINER}-${VERSION}.sif" + if [ -z "$DISABLE_CVMFS_USAGE" -a -d /cvmfs/singularity.opensciencegrid.org/eicweb/${CONTAINER}:${VERSION} ]; then + SIF="$PREFIX/local/lib/${CONTAINER}-${VERSION}" + ## need to cleanup in this case, else it will try to make a subdirectory + rm -rf ${SIF} + ln -sf /cvmfs/singularity.opensciencegrid.org/eicweb/${CONTAINER}:${VERSION} ${SIF} + elif [ -f /cvmfs/eic.opensciencegrid.org/singularity/athena/${CONTAINER}_v${VERSION}.sif ]; then + ln -sf /cvmfs/eic.opensciencegrid.org/singularity/athena/${CONTAINER}_v${VERSION}.sif ${SIF} + elif [ -f /gpfs02/cvmfst0/eic.opensciencegrid.org/singularity/athena/${CONTAINER}_v${VERSION}.sif ]; then + ln -sf /gpfs02/cvmfst0/eic.opensciencegrid.org/singularity/athena/${CONTAINER}_v${VERSION}.sif ${SIF} + ## check if we have an internal CI image we will use for testing purposes + elif [ -f $PWD/.gitlab-ci/${CONTAINER}-${VERSION}.sif ]; then + ln -sf $PWD/.gitlab-ci/${CONTAINER}-${VERSION}.sif ${SIF} + ## if not, download the container to the system + else + ## get the python installer and run the old-style install + ## work in temp directory + tmp_dir=$(mktemp -d -t ci-XXXXXXXXXX) + pushd $tmp_dir + wget https://eicweb.phy.anl.gov/containers/eic_container/-/raw/master/install.py + chmod +x install.py + ./install.py -f -c $CONTAINER -v $VERSION . + INSIF=lib/`basename ${SIF}` + mv $INSIF $SIF + chmod +x ${SIF} + ## cleanup + popd + rm -rf $tmp_dir + unset INSIF + fi fi -## we are in sane territory, yay! -else - ## check if we can just use cvmfs for the image - SIF="$PREFIX/local/lib/${CONTAINER}-${VERSION}.sif" - if [ -z "$DISABLE_CVMFS_USAGE" -a -d /cvmfs/singularity.opensciencegrid.org/eicweb/${CONTAINER}:${VERSION} ]; then - SIF="$PREFIX/local/lib/${CONTAINER}-${VERSION}" - ## need to cleanup in this case, else it will try to make a subdirectory - rm -rf ${SIF} - ln -sf /cvmfs/singularity.opensciencegrid.org/eicweb/${CONTAINER}:${VERSION} ${SIF} - elif [ -f /cvmfs/eic.opensciencegrid.org/singularity/athena/${CONTAINER}_v${VERSION}.sif ]; then - ln -sf /cvmfs/eic.opensciencegrid.org/singularity/athena/${CONTAINER}_v${VERSION}.sif ${SIF} - elif [ -f /gpfs02/cvmfst0/eic.opensciencegrid.org/singularity/athena/${CONTAINER}_v${VERSION}.sif ]; then - ln -sf /gpfs02/cvmfst0/eic.opensciencegrid.org/singularity/athena/${CONTAINER}_v${VERSION}.sif ${SIF} - ## check if we have an internal CI image we will use for testing purposes - elif [ -f $PWD/.gitlab-ci/${CONTAINER}-${VERSION}.sif ]; then - ln -sf $PWD/.gitlab-ci/${CONTAINER}-${VERSION}.sif ${SIF} - ## if not, download the container to the system + + echo $SIF + ls $SIF 2>&1 > /dev/null && GOOD_SIF=1 + if [ -z "$SIF" -o -z "$GOOD_SIF" ]; then + echo "ERROR: no singularity image found" + exit 1 else - ## get the python installer and run the old-style install - ## work in temp directory - tmp_dir=$(mktemp -d -t ci-XXXXXXXXXX) - pushd $tmp_dir - wget https://eicweb.phy.anl.gov/containers/eic_container/-/raw/master/install.py - chmod +x install.py - ./install.py -f -c $CONTAINER -v $VERSION . - INSIF=lib/`basename ${SIF}` - mv $INSIF $SIF - chmod +x ${SIF} - ## cleanup - popd - rm -rf $tmp_dir - unset INSIF + echo " - Deployed ${CONTAINER} image: $SIF" fi -fi -echo $SIF -ls $SIF 2>&1 > /dev/null && GOOD_SIF=1 -if [ -z "$SIF" -o -z "$GOOD_SIF" ]; then - echo "ERROR: no singularity image found" - exit 1 -else - echo " - Deployed ${CONTAINER} image: $SIF" -fi + ## We want to make sure the root directory of the install directory + ## is always bound. We also check for the existence of a few standard + ## locations (/scratch /volatile /cache) and bind those too if found + echo " - Determining additional bind paths" + PREFIX_ROOT="/$(realpath $PREFIX | cut -d "/" -f2)" + BINDPATH=$PREFIX_ROOT + echo " --> $PREFIX_ROOT" + for dir in /work /scratch /volatile /cache; do + ## only add directories once + if [[ ${BINDPATH} =~ $(basename $dir) ]]; then + continue + fi + if [ -d $dir ]; then + echo " --> $dir" + BINDPATH="${BINDPATH},$dir" + fi + done -## We want to make sure the root directory of the install directory -## is always bound. We also check for the existence of a few standard -## locations (/scratch /volatile /cache) and bind those too if found -echo " - Determining additional bind paths" -PREFIX_ROOT="/$(realpath $PREFIX | cut -d "/" -f2)" -BINDPATH=$PREFIX_ROOT -echo " --> $PREFIX_ROOT" -for dir in /work /scratch /volatile /cache; do - if [ -d $dir ]; then - echo " --> $dir" - BINDPATH="${BINDPATH},$dir" - fi -done - -## create a new top-level eic-shell launcher script -## that sets the ATHENA_PREFIX and then starts singularity + ## create a new top-level eic-shell launcher script + ## that sets the ATHENA_PREFIX and then starts singularity cat << EOF > eic-shell #!/bin/bash @@ -270,8 +283,127 @@ export SINGULARITY_BINDPATH=$BINDPATH $SINGULARITY exec $SIF eic-shell \$@ EOF -chmod +x eic-shell + chmod +x eic-shell + + echo " - Created custom eic-shell excecutable" +} + +function install_macos() { + ## check for docker install + DOCKER=$(which docker) + if [ -z ${DOCKER} ]; then + echo "ERROR: no docker install found, docker is required for running on MacOS" + fi + echo " - Found docker at ${DOCKER}" + + IMG=eicweb/${CONTAINER}:${VERSION} + docker pull ${IMG} + echo " - Deployed ${CONTAINER} image: ${IMG}" + + ## We want to make sure the root directory of the install directory + ## is always bound. We also check for the existence of a few standard + ## locations (/Volumes /Users /tmp) and bind those too if found + echo " - Determining mount paths" + PREFIX_ROOT="/$(realpath $PREFIX | cut -d "/" -f2)" + MOUNT="" + echo " --> $PREFIX_ROOT" + for dir in /Volumes /Users /tmp; do + ## only add directories once + if [[ ${MOUNT} =~ $(basename $dir) ]]; then + continue + fi + if [ -d $dir ]; then + echo " --> $dir" + MOUNT="$MOUNT -v $dir:$dir" + fi + done + echo " - Docker mount directive: '$MOUNT'" + + ## create a new top-level eic-shell launcher script + ## that sets the ATHENA_PREFIX and then starts singularity +cat << EOF > eic-shell +#!/bin/bash + +## capture environment setup for upgrades +CONTAINER=$CONTAINER +TMPDIR=$TMPDIR +VERSION=$VERSION +PREFIX=$PREFIX +DISABLE_CVMFS_USAGE=${DISABLE_CVMFS_USAGE} + +function print_the_help { + echo "USAGE: ./eic-shell [OPTIONS] [ -- COMMAND ]" + echo "OPTIONAL ARGUMENTS:" + echo " -u,--upgrade Upgrade the container to the latest version" + echo " -h,--help Print this message" + echo "" + echo " Start the eic-shell containerized software environment." + echo "" + echo "EXAMPLES: " + echo " - Start an interactive shell: ./eic-shell" + echo " - Upgrade the container: ./eic-shell --upgrade" + echo " - Execute a single command: ./eic-shell -- <COMMAND>" + echo "" + exit +} + +UPGRADE= + +while [ \$# -gt 0 ]; do + key=\$1 + case \$key in + -u|--upgrade) + UPGRADE=1 + shift + ;; + -h|--help) + print_the_help + exit 0 + ;; + --) + shift + break + ;; + *) + echo "ERROR: unknown argument: \$key" + echo "use --help for more info" + exit 1 + ;; + esac +done + +if [ ! -z \${UPGRADE} ]; then + echo "Upgrading eic-shell..." + docker pull $IMG || exit 1 + echo "eic-shell upgrade sucessful" + exit 0 +fi + +docker run $MOUNT -w=$PWD -it --rm -e ATHENA_PREFIX=$PREFIX/local $IMG eic-shell \$@ +EOF + + chmod +x eic-shell + + echo " - Created custom eic-shell excecutable" +} + +## detect OS +OS=`uname -s` +case ${OS} in + Linux) + echo " - Detected OS: Linux" + install_linux + ;; + Darwin) + echo " - Detected OS: MacOS" + install_macos + ;; + *) + echo "ERROR: OS '${OS}' not currently supported" + exit 1 + ;; +esac -echo " - Created custom eic-shell excecutable" +popd echo "Environment setup succesfull" echo "You can start the development environment by running './eic-shell'" -- GitLab