Last active
October 4, 2024 09:56
-
-
Save lrtfm/93d55c6d8d5bc92d2c7551dd0048fd4f to your computer and use it in GitHub Desktop.
Run command in container of firedrake or firedrake-complex
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -e | |
| TOOL=${TOOL:-docker} # Set TOOL to 'docker' by default. Change it to 'podman' if needed. | |
| BASE_IMAGE=${BASE_IMAGE:-firedrakeproject/firedrake} | |
| RUN_ARGS=${RUN_ARGS:---rm} | |
| if [[ "$TOOL" == "docker" ]]; then | |
| BUILD_ARGS="${BUILD_ARGS:---network=host}" | |
| elif [[ "$TOOL" == "podman" ]]; then | |
| BUILD_ARGS="${BUILD_ARGS} --format docker" # Use Docker format for Podman | |
| else | |
| echo "Error: TOOL must be set to either 'docker' or 'podman'." | |
| exit 1 | |
| fi | |
| usage() { | |
| PROG=$(basename "$0") | |
| echo | |
| echo "Usage: $PROG command [args...]" | |
| echo "Run a command inside the Firedrake container." | |
| echo | |
| echo "Examples (Scalar type: real):" | |
| echo " $PROG python my-python-file.py" | |
| echo " $PROG mpiexec -n 16 python my-python-file.py" | |
| echo | |
| echo "To use Podman instead of Docker:" | |
| echo " TOOL=podman $PROG python my-python-file.py" | |
| echo " TOOL=podman $PROG mpiexec -n 16 python my-python-file.py" | |
| echo | |
| echo "Run command with debug messages enabled:" | |
| echo " DEBUG=Y $PROG python my-python-file.py" | |
| echo | |
| echo "Force a rebuild of the container image:" | |
| echo " FORCE_BUILD=Y $PROG" | |
| echo | |
| if [[ "$TOOL" == "docker" ]]; then | |
| echo "Customize build arguments for '$TOOL build' (Default: '--network=host'):" | |
| echo " FORCE_BUILD=Y BUILD_ARGS=\"--no-cache --network=host\" $PROG" | |
| else | |
| echo "Customize build arguments for '$TOOL build':" | |
| echo " TOOL=podman FORCE_BUILD=Y BUILD_ARGS=\"--no-cache\" $PROG" | |
| fi | |
| echo | |
| echo "Example for complex scalar type:" | |
| echo " BASE_IMAGE=firedrakeproject/firedrake-complex $PROG python my-python-file.py" | |
| echo | |
| exit 1 | |
| } | |
| if [[ "x$1" =~ x-h|x--help ]]; then | |
| usage | |
| fi | |
| is_true () { | |
| _VAL=$(echo "${1:-N}" | tr '[:upper:]' '[:lower:]') | |
| [[ ${_VAL} =~ [1-9]|t|true|y|yes|on ]] && return 0 # true | |
| return 1 # false | |
| } | |
| print_msg () { | |
| MSG=$1 | |
| TERM_WIDTH=${TERM_WIDTH:-$(tput cols)} | |
| PADDING_WIDTH=$(( (${TERM_WIDTH} - 2 - ${#MSG})/2 )) | |
| PADDING=$(for i in $(seq 1 ${PADDING_WIDTH}); do echo -n =; done) | |
| echo "$PADDING $MSG $PADDING"$([ $(( ${#MSG}%2 )) == 1 ] && echo -n = || echo -n "") | |
| } | |
| TERM_WIDTH=80 | |
| FORCE_BUILD=$( is_true ${FORCE_BUILD} && echo Y || echo N) | |
| DEBUG=$( is_true ${DEBUG:-$FORCE_BUILD} && echo "" || echo ":" ) | |
| ${DEBUG} print_msg "DEBUG VARS BEGIN" | |
| ${DEBUG} echo -e "VARs:\n\tDEBUG: \"${DEBUG:-Y}\"\n\tFORCE_BUILD: \"$FORCE_BUILD\"" | |
| ${DEBUG} print_msg "DEBUG VARS END" | |
| if [[ "x$FDUTILS_COMMIT" != "x" ]]; then | |
| CHECKOUT_COMMIT="&& git checkout $FDUTILS_COMMIT" | |
| fi | |
| create_dockerfile () { | |
| _BASE_IMAGE=$1 | |
| _DOCKERFILE=$2 | |
| cat <<EOF > $_DOCKERFILE | |
| FROM $_BASE_IMAGE | |
| USER root | |
| RUN echo -e "[safe]\n\tdirectory = *\n" >> /etc/gitconfig | |
| USER firedrake | |
| WORKDIR /home/firedrake | |
| RUN bash -c ". /home/firedrake/firedrake/bin/activate && \\ | |
| pip install pqdm gmsh siphash24 && \\ | |
| git clone https://github.com/lrtfm/fdutils.git && \\ | |
| cd fdutils $CHECKOUT_COMMIT && make develop" | |
| RUN bash -c "sed -i.bak -e 's/^.*simplefilter.*$//g' firedrake/src/firedrake/firedrake/checkpointing.py" | |
| EOF | |
| ${DEBUG} print_msg "THE DOCKER FILE BEGIN" | |
| ${DEBUG} cat $_DOCKERFILE | |
| ${DEBUG} print_msg "THE DOCKER FILE END" | |
| } | |
| if [[ "x$IMAGE" == "x" ]]; then | |
| BASE_NAME_NOTAG=${BASE_IMAGE//:*/} | |
| IMAGE_NAME=${BASE_NAME_NOTAG//*\//}-$(id -u -n) | |
| if ! ${TOOL} image inspect $BASE_IMAGE > /dev/null 2>&1; then | |
| ${TOOL} pull $BASE_IMAGE | |
| fi | |
| DATE_TAG=$(${TOOL} inspect -f '{{ .Created }}' $BASE_IMAGE | sed -E -e 's/(T| ).*//' -e 's/-//g') | |
| if ! ${TOOL} image inspect $IMAGE_NAME:$DATE_TAG > /dev/null 2>&1; then | |
| TARGET_EXIST="N" | |
| else | |
| TARGET_EXIST="Y" | |
| fi | |
| if [[ "$TARGET_EXIST" == "N" || "$FORCE_BUILD" == "Y" ]]; then | |
| TEMP_DOCKERFILE=$(mktemp .Dockerfile.XXXXXXXXXXXXXXXX) | |
| trap 'rm -f -- "$TEMP_DOCKERFILE"' EXIT | |
| create_dockerfile $BASE_IMAGE $TEMP_DOCKERFILE | |
| if [[ "$TARGET_EXIST" == "Y" ]]; then | |
| ${TOOL} tag $IMAGE_NAME:$DATE_TAG $IMAGE_NAME:$DATE_TAG-bak-$(date +%Y%m%d-%H%M%S) | |
| fi | |
| ${DEBUG} print_msg "BUILD BEGIN" | |
| echo "${TOOL} build $BUILD_ARGS -t $IMAGE_NAME:$DATE_TAG -f $TEMP_DOCKERFILE ." | |
| ${TOOL} build $BUILD_ARGS -t $IMAGE_NAME:$DATE_TAG -f $TEMP_DOCKERFILE . | |
| ${DEBUG} print_msg "BUILD END" | |
| fi | |
| IMAGE=$IMAGE_NAME:$DATE_TAG | |
| fi | |
| FD_INFO=$(${TOOL} run --rm $IMAGE bash -c 'echo $(id -u)\;$(id -g -n)\;$HOME\;$PATH\;') | |
| IFS=';' read -r FD_UID FD_GNAME FD_HOME FD_PATH <<< "$FD_INFO" | |
| [[ $(id -u) != ${FD_UID} ]] && FD_HOME=/work | |
| FD_ENV=/home/firedrake/firedrake | |
| FD_PATH=${FD_ENV}/bin:${FD_PATH} | |
| SET_USER=${SET_USER:-$(id -u):$(id -g)} | |
| ADD_GROUP=${ADD_GROUP:-$FD_GNAME} | |
| ${DEBUG} print_msg "THE CMD BEGIN" | |
| ${DEBUG} echo -ne "IMAGE:\n\t"; ${DEBUG} echo "$IMAGE" | |
| ${DEBUG} echo -ne "COMMAND:\n\t\x60"; ${DEBUG} echo -n "$@"; ${DEBUG} echo -e "\x27" | |
| ${DEBUG} echo -ne "HOME:\n\t"; ${DEBUG} echo "$FD_HOME" | |
| ${DEBUG} echo -ne "PATH:\n\t"; ${DEBUG} echo "$FD_PATH" | |
| ${DEBUG} echo -ne "SET_USER:\n\t"; ${DEBUG} echo "$SET_USER" | |
| ${DEBUG} echo -ne "ADD_GROUP:\n\t"; ${DEBUG} echo "$ADD_GROUP" | |
| ${DEBUG} print_msg "THE CMD END" | |
| if [[ $# -eq 0 ]]; then | |
| usage | |
| fi | |
| if [[ "$TOOL" == "docker" ]]; then | |
| PERMISSION_ARGS="-u ${SET_USER} --group-add ${ADD_GROUP}" | |
| elif [[ "$TOOL" == "podman" ]]; then | |
| PERMISSION_ARGS="--security-opt label=disable --userns keep-id:uid=1000,gid=1000" | |
| fi | |
| ${TOOL} run ${RUN_ARGS} ${PERMISSION_ARGS} \ | |
| -ti -v $(pwd):/work -w /work \ | |
| -e HOME=${FD_HOME} \ | |
| -e PATH=${FD_PATH} \ | |
| -e VIRTUAL_ENV=${FD_ENV} \ | |
| -e PYOP2_CACHE_DIR=/work/.cache \ | |
| -e FIREDRAKE_TSFC_KERNEL_CACHE_DIR=/work/.cache \ | |
| $IMAGE \ | |
| "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This aims to address inconsistent permission issues of the shared folders in the Firedrake container.
Download the script
Add exec permission
Now, you can run firedrake script