app.def
{#- Required jinja arguments -#}
{#- APPTAINER_BOOTSTRAP: The BootStrap to use (typically localimage or oras) -#}
{#- APPTAINER_FROM: The From to use (path to an image or an oras URI) -#}
{#- APPLICATION_DIR: Path on the host to the application repository -#}
{#- MOOSE_DIR: Path on the host to the MOOSE repository -#}
{#- BINARY_NAME: Name of the application binary -#}
{#- Optional jinja arguments -#}
{#- MOOSE_JOBS: Number of jobs to pass to the build -#}
{#- MOOSE_OPTIONS: Options to pass to the MOOSE configure -#}
{#- MOOSE_SKIP_DOCS: Set to anything to skip the docs build -#}
{#- MOOSE_DOCS_FLAGS: Doc options to pass during the make install -#}
{#- METHOD: The method to build; defaults to "opt" -#}
{#- TEST_DIRS: Directories to test in the %test section; defaults to just "tests" -#}
{#- EXTRA_MAMBA_PACKAGES: Extra mamba packages to install -#}
{#- Civet Specific jinja arguments -#}
{#- CIVET_STEP_ALLOWED_TO_FAIL: BOOL, specific to Civet. Available in %post, %test section -#}
{#- Optional Application specific jinja arguments -#}
{#- SECTION_ENVIRONMENT: Adds additional environment variables set upon entering container -#}
{#- SECTION_POST: Partially replaces %post (make, make install, section) -#}
{#- SECTION_TEST: Partially replaces %test (for loop section) -#}
{#- The within-container build directory to use -#}
{%- set ROOT_BUILD_DIR = '/root/build' -%}
BootStrap: {{ APPTAINER_BOOTSTRAP }}
From: {{ APPTAINER_FROM }}
%setup
# Load jinja vars
ROOT_BUILD_DIR={{ ROOT_BUILD_DIR }}
APPLICATION_DIR={{ APPLICATION_DIR }}
MOOSE_DIR={{ MOOSE_DIR }}
# Build directory in the container
BUILD_DIR=${APPTAINER_ROOTFS}${ROOT_BUILD_DIR}
mkdir ${BUILD_DIR}
# Copy application into the container
cp -r ${APPLICATION_DIR} ${BUILD_DIR}
# Where the application ends up; needed for MOOSE logic below
APPLICATION_NAME=$(basename ${APPLICATION_DIR})
APPLICATION_BUILD_DIR=${BUILD_DIR}/${APPLICATION_NAME}
# Figure out where moose is; regardless %post will expect
# it to be in {{ ROOT_BUILD_DIR }}/moose
MOOSE_BUILD_DIR=${BUILD_DIR}/moose
MOOSE_RELATIVE_PATH=$(realpath --relative-to ${APPLICATION_DIR} ${MOOSE_DIR})
# MOOSE_DIR is not in the application; we need to copy it
if [[ $MOOSE_RELATIVE_PATH = ..* ]]; then
mkdir ${MOOSE_BUILD_DIR}
cp -r ${MOOSE_DIR}/. ${MOOSE_BUILD_DIR}
# MOOSE_DIR is the application (combined-opt)
elif [[ '{{ BINARY_NAME }}' == 'moose' ]]; then
# do nothing
:
# MOOSE_DIR is in the application, setup a symlink
else
ln -s ./${APPLICATION_NAME}/${MOOSE_RELATIVE_PATH} ${MOOSE_BUILD_DIR}
fi
{%- if MOOSE_SKIP_DOCS is not defined %}
# Need large_media for documentation
cd ${MOOSE_BUILD_DIR}
git submodule update --init large_media
{%- endif %}
%environment
{%- if BINARY_NAME == 'moose' %}
export PATH=/opt/moose/bin:$PATH
{%- else %}
export PATH=/opt/{{ BINARY_NAME }}/bin:$PATH
{%- endif %}
{%- if SECTION_ENVIRONMENT is defined %}
{{ SECTION_ENVIRONMENT }}
{%- endif %}
%post
{%- if SECTION_POST_BEGIN is defined %}
{{ SECTION_POST_BEGIN }}
{%- endif %}
# Load jinja vars
APPLICATION_NAME=$(basename {{ APPLICATION_DIR }})
BINARY_NAME={{ BINARY_NAME }}
export METHOD={{ METHOD or "opt" }}
MOOSE_DOCS_FLAGS="{{ MOOSE_DOCS_FLAGS }}"
export MOOSE_JOBS={{ MOOSE_JOBS or "1" }}
MOOSE_OPTIONS="{{ MOOSE_OPTIONS }}"
MOOSE_SKIP_DOCS={{ MOOSE_SKIP_DOCS }}
TEMP_LOC={{ ROOT_BUILD_DIR }}
APPLICATION_DIR=${TEMP_LOC}/${APPLICATION_NAME}
export MOOSE_DIR=${TEMP_LOC}/moose
# If MOOSE_DIR is a symlink, we're using MOOSE within
# the app, so use that instead
if test -h $MOOSE_DIR; then
MOOSE_DIR_REAL=$(realpath $MOOSE_DIR)
rm ${MOOSE_DIR}
export MOOSE_DIR=${MOOSE_DIR_REAL}
fi
# Remove the libmesh methods from moose-dev that we do not need
for method in opt oprof devel dbg; do
if [ "$method" != "$METHOD" ]; then
find ${LIBMESH_DIR}/lib -name "*_$method.so*" -delete -print
find ${LIBMESH_DIR}/lib -name "*_$method.la" -delete -print
find ${LIBMESH_DIR}/bin -name "*-$method" -delete -print
find ${LIBMESH_DIR} -name "*-$method.pc" -delete -print
fi
done
# Setup install
{%- if BINARY_NAME == 'moose' %}
MOOSE_PREFIX=/opt/moose
{%- else %}
MOOSE_PREFIX=/opt/${BINARY_NAME}
{%- endif %}
cd ${MOOSE_DIR}
./configure --prefix=$MOOSE_PREFIX ${MOOSE_OPTIONS}
# Build and install
{%- if BINARY_NAME == 'moose' %}
cd ${APPLICATION_DIR}/modules
{%- else %}
cd ${APPLICATION_DIR}
{%- endif %}
{%- if SECTION_POST_PRE_MAKE is defined %}
{{ SECTION_POST_PRE_MAKE }}
{%- endif %}
make -j ${MOOSE_JOBS}
{%- if SECTION_POST_PRE_INSTALL is defined %}
{{ SECTION_POST_PRE_INSTALL }}
{%- endif %}
make install -j ${MOOSE_JOBS} MOOSE_SKIP_DOCS=${MOOSE_SKIP_DOCS} MOOSE_DOCS_FLAGS="${MOOSE_DOCS_FLAGS}"
{%- if SECTION_POST_POST_INSTALL is defined %}
{{ SECTION_POST_POST_INSTALL }}
{%- endif %}
{%- if BINARY_NAME == 'moose' %}
# Also build and install moose_test-opt
cd ${APPLICATION_DIR}/test
make -j ${MOOSE_JOBS}
make install -j ${MOOSE_JOBS} MOOSE_SKIP_DOCS=1
# Create moose-opt symlink to combined-opt
cd /opt/moose/bin
ln -s combined-opt moose-opt
{%- endif %}
# Fix permissions for installed application
chmod -R o=u-w,g=u-w ${MOOSE_PREFIX}
{%- if SECTION_POST_END is defined %}
{{ SECTION_POST_END }}
{%- endif %}
# Cleanup
rm -rf $TEMP_LOC
%test
set -x
# Load jinja vars
export BINARY_NAME={{ BINARY_NAME }}
export METHOD={{ METHOD or "opt" }}
TEST_DIRS="{{ TEST_DIRS or "tests" }}"
# Temp location for copying and running in
export TEMP_LOC=$(mktemp -d /tmp/${BINARY_NAME}test.XXXXXX)
# Really make sure that we nuke the temp location in all circumstances
trap "/usr/bin/rm -rf $TEMP_LOC" EXIT HUP INT TERM
{%- if SECTION_TEST_BEGIN is defined %}
{{ SECTION_TEST_BEGIN }}
{%- endif %}
function run_tests()
{
local BINARY_NAME=$1
local TEST_DIR=$2
local TEMP_TEST_LOC=${TEMP_LOC}/${TEST_DIR}
mkdir $TEMP_TEST_LOC && \
cd $TEMP_TEST_LOC && \
${BINARY_NAME}-${METHOD} --copy-inputs $TEST_DIR && \
cd ${BINARY_NAME}/${TEST_DIR} && \
${BINARY_NAME}-${METHOD} --run -j ${MOOSE_JOBS:-1} -t
return_code=$?
rm -rf $TEMP_TEST_LOC
return $return_code
}
return_flag=0
{%- if BINARY_NAME == 'moose' %}
run_tests moose_test tests || return_flag=$?
{%- endif %}
# Copy and run each subset of tests
for TEST_DIR in ${TEST_DIRS}; do
run_tests ${BINARY_NAME} ${TEST_DIR} || return_flag=$?
done
rm -rf $TEMP_LOC
if [ $return_flag != 0 ]; then
exit $return_flag
fi
{%- if SECTION_TEST_END is defined %}
{{ SECTION_TEST_END }}
{%- endif %}