Skip to content

Instantly share code, notes, and snippets.

@lrtfm
Last active October 4, 2024 09:56
Show Gist options
  • Select an option

  • Save lrtfm/93d55c6d8d5bc92d2c7551dd0048fd4f to your computer and use it in GitHub Desktop.

Select an option

Save lrtfm/93d55c6d8d5bc92d2c7551dd0048fd4f to your computer and use it in GitHub Desktop.
Run command in container of firedrake or firedrake-complex
#!/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 \
"$@"
@lrtfm
Copy link
Copy Markdown
Author

lrtfm commented Apr 16, 2024

This aims to address inconsistent permission issues of the shared folders in the Firedrake container.

  1. Download the script

    curl -O https://gist.githubusercontent.com/lrtfm/93d55c6d8d5bc92d2c7551dd0048fd4f/raw/firedrake-run
    
  2. Add exec permission

    chmod +x firedrake-run
    
  3. Now, you can run firedrake script

    ./firedrake-run python my-script.py
    

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment