Skip to content

Commit 3ceef12

Browse files
authored
Merge pull request #9 from boegel/eessi_container_unionfs
add support to `eessi_container.sh` for using `unionfs` overlay tool
2 parents a676158 + 0ec75f1 commit 3ceef12

File tree

3 files changed

+98
-33
lines changed

3 files changed

+98
-33
lines changed

.github/workflows/test_eessi_container_script.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
- shell
2222
- container
2323
- resume
24+
- unionfs
2425
# FIXME disabled because '--access rw' is not working in CI environment
2526
#- readwrite
2627
#- save
@@ -135,6 +136,18 @@ jobs:
135136
136137
tar tfv test-save.tar | grep "overlay-upper/${fn}"
137138
139+
# test use of --overlay-tool unionfs
140+
elif [[ ${{matrix.SCRIPT_TEST}} == 'unionfs' ]]; then
141+
outfile=out_unionfs.txt
142+
container="docker://ghcr.io/eessi/build-node:debian12"
143+
export SINGULARITY_BIND="$PWD:/test"
144+
echo 'ls -ld /cvmfs*/software.eessi.io/*' > test_script.sh
145+
chmod u+x test_script.sh
146+
./eessi_container.sh --verbose --container ${container} --access rw --overlay-tool unionfs --mode run /test/test_script.sh 2>&1 | tee ${outfile}
147+
for pattern in "/cvmfs/software.eessi.io/versions" "/cvmfs_ro/software.eessi.io/versions"; do
148+
grep "${pattern}" ${outfile} || (echo "Pattern '${pattern}' not found in ${outfile}"; exit 1)
149+
done
150+
138151
else
139152
echo "Unknown test case: ${{matrix.SCRIPT_TEST}}" >&2
140153
exit 1

.github/workflows/tests_scripts.yml

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ permissions:
2929
jobs:
3030
build:
3131
runs-on: ubuntu-24.04
32+
strategy:
33+
fail-fast: false
34+
matrix:
35+
EESSI_VERSION:
36+
- '2023.06'
3237
steps:
3338
- name: checkout
3439
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
@@ -39,8 +44,8 @@ jobs:
3944
4045
- name: test load_easybuild_module.sh script
4146
run: |
42-
# bind current directory into container as /software-layer
43-
export SINGULARITY_BIND="${PWD}:/software-layer"
47+
# bind current directory into container as /software-layer-scripts
48+
export SINGULARITY_BIND="${PWD}:/software-layer-scripts"
4449
4550
# can't test with EasyBuild versions older than v4.5.2 when using EESSI 2023.06,
4651
# since Python in compat layer is Python 3.11.x;
@@ -58,64 +63,79 @@ jobs:
5863
echo 'export TMPDIR=$(mktemp -d)' >> ${test_script}
5964
# set up environment to have utility functions in place that load_easybuild_module.sh script relies on,
6065
# along with $EESSI_* environment variables, and Lmod
61-
echo 'ls -l /software-layer/' >> ${test_script}
62-
echo 'source /software-layer/scripts/utils.sh' >> ${test_script}
63-
echo 'source /software-layer/init/eessi_environment_variables' >> ${test_script}
66+
echo 'ls -l /software-layer-scripts/' >> ${test_script}
67+
echo 'export EESSI_VERSION_OVERRIDE="${{matrix.EESSI_VERSION}}"' >> ${test_script}
68+
echo 'source /software-layer-scripts/scripts/utils.sh' >> ${test_script}
69+
echo 'source /software-layer-scripts/init/eessi_environment_variables' >> ${test_script}
6470
echo 'source ${EPREFIX}/usr/share/Lmod/init/bash' >> ${test_script}
6571
# minimal configuration for EasyBuild so we can test installation aspect of load_easybuild_module.sh script
6672
echo "export EASYBUILD_INSTALLPATH=/tmp/eb-${EB_VERSION}" >> ${test_script}
6773
echo 'module use ${EASYBUILD_INSTALLPATH}/modules/all' >> ${test_script}
6874
echo '' >> ${test_script}
69-
echo "source /software-layer/load_easybuild_module.sh ${EB_VERSION}" >> ${test_script}
75+
echo "source /software-layer-scripts/load_easybuild_module.sh ${EB_VERSION}" >> ${test_script}
7076
echo 'module list' >> ${test_script}
7177
echo 'eb --version' >> ${test_script}
7278
7379
chmod u+x ${test_script}
7480
81+
# make sure that correct EESSI version is used (required because default is a placeholder version)
82+
export EESSI_VERSION_OVERRIDE="${{matrix.EESSI_VERSION}}"
83+
7584
# run wrapper script + capture & check output
7685
out="${PWD}/eb-${EB_VERSION}.out"
77-
./eessi_container.sh --access rw --mode run --verbose /software-layer/run_in_compat_layer_env.sh /software-layer/eb-${EB_VERSION}.sh 2>&1 | tee ${out}
86+
./eessi_container.sh --access rw --mode run --verbose /software-layer-scripts/run_in_compat_layer_env.sh /software-layer-scripts/eb-${EB_VERSION}.sh 2>&1 | tee ${out}
7887
pattern="^This is EasyBuild ${EB_VERSION} "
7988
grep "${pattern}" ${out} || (echo "Pattern '${pattern}' not found in output!" && exit 1)
8089
done
8190
8291
- name: test install_software_layer.sh script
8392
run: |
84-
# bind current directory into container as /software-layer
85-
export SINGULARITY_BIND="${PWD}:/software-layer"
93+
# bind current directory into container as /software-layer-scripts
94+
export SINGULARITY_BIND="${PWD}:/software-layer-scripts"
8695
# force using x86_64/generic, to avoid triggering an installation from scratch
8796
sed -i "s@./EESSI-install-software.sh@\"export EESSI_SOFTWARE_SUBDIR_OVERRIDE='x86_64/generic'; ./EESSI-install-software.sh\"@g" install_software_layer.sh
8897
# skip installation of CUDA SDKs, since this is too heavy for CI
8998
sed -i "s@./EESSI-install-software.sh@./EESSI-install-software.sh --skip-cuda-install@g" install_software_layer.sh
90-
./eessi_container.sh --mode run --verbose /software-layer/install_software_layer.sh
99+
100+
# make sure that correct EESSI version is used (required because default is a placeholder version)
101+
export EESSI_VERSION_OVERRIDE="${{matrix.EESSI_VERSION}}"
102+
103+
./eessi_container.sh --mode run --verbose /software-layer-scripts/install_software_layer.sh
91104
92105
- name: test create_directory_tarballs.sh script
93106
run: |
94-
# bind current directory into container as /software-layer
95-
export SINGULARITY_BIND="${PWD}:/software-layer"
107+
# bind current directory into container as /software-layer-scripts
108+
export SINGULARITY_BIND="${PWD}:/software-layer-scripts"
109+
110+
# make sure that correct EESSI version is used (required because default is a placeholder version)
111+
export EESSI_VERSION_OVERRIDE="${{matrix.EESSI_VERSION}}"
112+
96113
# scripts need to be copied to /tmp,
97114
# since create_directory_tarballs.sh must be accessible from within build container
98-
./eessi_container.sh --mode run --verbose /software-layer/create_directory_tarballs.sh 2023.06
115+
./eessi_container.sh --mode run --verbose /software-layer-scripts/create_directory_tarballs.sh 2023.06
99116
# check if tarballs have been produced
100117
ls -l *.tar.gz
101118
102119
- name: test create_lmodsitepackage.py script
103120
run: |
104-
# bind current directory into container as /software-layer
105-
export SINGULARITY_BIND="${PWD}:/software-layer"
121+
# bind current directory into container as /software-layer-scripts
122+
export SINGULARITY_BIND="${PWD}:/software-layer-scripts"
106123
107-
# Creates .lmod/SitePackage.lua in current dir, which then gets bind-mounted into /software-layer
124+
# Creates .lmod/SitePackage.lua in current dir, which then gets bind-mounted into /software-layer-scripts
108125
python3 create_lmodsitepackage.py .
109126
# run some commands to make sure that generated Lmod SitePackage file works
110127
test_script="${PWD}/test_lmod_sitepackage.sh"
111128
echo '#!/bin/bash' > ${test_script}
112-
echo 'export LMOD_PACKAGE_PATH="/software-layer/.lmod"' > ${test_script}
129+
echo 'export LMOD_PACKAGE_PATH="/software-layer-scripts/.lmod"' > ${test_script}
113130
echo 'ml --config' >> ${test_script}
114131
115132
chmod u+x ${test_script}
116133
134+
# make sure that correct EESSI version is used (required because default is a placeholder version)
135+
export EESSI_VERSION_OVERRIDE="${{matrix.EESSI_VERSION}}"
136+
117137
out="${PWD}/test_create_lmodsitepackage.out"
118-
./eessi_container.sh --mode run --verbose /software-layer/run_in_compat_layer_env.sh /software-layer/test_lmod_sitepackage.sh 2>&1 | tee ${out}
119-
for pattern in "^Site Pkg location.*/software-layer/.lmod/SitePackage.lua" "LMOD_SITEPACKAGE_LOCATION.*/software-layer/.lmod/SitePackage.lua"; do
138+
./eessi_container.sh --mode run --verbose /software-layer-scripts/run_in_compat_layer_env.sh /software-layer-scripts/test_lmod_sitepackage.sh 2>&1 | tee ${out}
139+
for pattern in "^Site Pkg location.*/software-layer-scripts/.lmod/SitePackage.lua" "LMOD_SITEPACKAGE_LOCATION.*/software-layer-scripts/.lmod/SitePackage.lua"; do
120140
grep "${pattern}" ${out} || (echo "Pattern '${pattern}' not found in output!" && exit 1)
121141
done

eessi_container.sh

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ HTTP_PROXY_ERROR_EXITCODE=$((${ANY_ERROR_EXITCODE} << 9))
4747
HTTPS_PROXY_ERROR_EXITCODE=$((${ANY_ERROR_EXITCODE} << 10))
4848
RUN_SCRIPT_MISSING_EXITCODE=$((${ANY_ERROR_EXITCODE} << 11))
4949
NVIDIA_MODE_UNKNOWN_EXITCODE=$((${ANY_ERROR_EXITCODE} << 12))
50+
OVERLAY_TOOL_EXITCODE=$((${ANY_ERROR_EXITCODE} << 13))
5051

5152
# CernVM-FS settings
5253
CVMFS_VAR_LIB="var-lib-cvmfs"
@@ -89,6 +90,9 @@ display_help() {
8990
echo " -n | --nvidia MODE - configure the container to work with NVIDIA GPUs,"
9091
echo " MODE==install for a CUDA installation, MODE==run to"
9192
echo " attach a GPU, MODE==all for both [default: false]"
93+
echo " -o | --overlay-tool ARG - tool to use to create (read-only or writable) overlay;"
94+
echo " selected tool *must* be available in container image being used;"
95+
echo " can be 'fuse-overlayfs' or 'unionfs' [default: fuse-overlayfs]"
9296
echo " -p | --pass-through ARG - argument to pass through to the launch of the"
9397
echo " container; can be given multiple times [default: not set]"
9498
echo " -r | --repository CFG - configuration file or identifier defining the"
@@ -128,6 +132,7 @@ VERBOSE=0
128132
STORAGE=
129133
LIST_REPOS=0
130134
MODE="shell"
135+
OVERLAY_TOOL="fuse-overlayfs"
131136
PASS_THROUGH=()
132137
SETUP_NVIDIA=0
133138
REPOSITORIES=()
@@ -185,6 +190,10 @@ while [[ $# -gt 0 ]]; do
185190
NVIDIA_MODE="$2"
186191
shift 2
187192
;;
193+
-o|--overlay-tool)
194+
OVERLAY_TOOL="$2"
195+
shift 2
196+
;;
188197
-p|--pass-through)
189198
PASS_THROUGH+=("$2")
190199
shift 2
@@ -779,7 +788,7 @@ do
779788
# below); the overlay-upper directory can only exist because it is part of
780789
# the ${RESUME} directory or tarball
781790
# to be able to see the contents of the read-write session we have to mount
782-
# the fuse-overlayfs (in read-only mode) on top of the CernVM-FS repository
791+
# the overlay (in read-only mode) on top of the CernVM-FS repository
783792

784793
echo "While processing '${cvmfs_repo_name}' to be mounted 'read-only' we detected an overlay-upper"
785794
echo " directory (${EESSI_TMPDIR}/${cvmfs_repo_name}/overlay-upper) likely from a previous"
@@ -791,14 +800,25 @@ do
791800
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_READONLY}")
792801

793802
# now, put the overlay-upper read-only on top of the repo and make it available under the usual prefix /cvmfs
794-
EESSI_READONLY_OVERLAY="container:fuse-overlayfs"
795-
# The contents of the previous session are available under
796-
# ${EESSI_TMPDIR} which is bind mounted to ${TMP_IN_CONTAINER}.
797-
# Hence, we have to use ${TMP_IN_CONTAINER}/${cvmfs_repo_name}/overlay-upper
798-
# the left-most directory given for the lowerdir argument is put on top,
799-
# and with no upperdir=... the whole overlayfs is made available read-only
800-
EESSI_READONLY_OVERLAY+=" -o lowerdir=${TMP_IN_CONTAINER}/${cvmfs_repo_name}/overlay-upper:/cvmfs_ro/${cvmfs_repo_name}"
801-
EESSI_READONLY_OVERLAY+=" /cvmfs/${cvmfs_repo_name}"
803+
if [[ "${OVERLAY_TOOL}" == "fuse-overlayfs" ]]; then
804+
EESSI_READONLY_OVERLAY="container:fuse-overlayfs"
805+
# The contents of the previous session are available under
806+
# ${EESSI_TMPDIR} which is bind mounted to ${TMP_IN_CONTAINER}.
807+
# Hence, we have to use ${TMP_IN_CONTAINER}/${cvmfs_repo_name}/overlay-upper
808+
# the left-most directory given for the lowerdir argument is put on top,
809+
# and with no upperdir=... the whole overlayfs is made available read-only
810+
EESSI_READONLY_OVERLAY+=" -o lowerdir=${TMP_IN_CONTAINER}/${cvmfs_repo_name}/overlay-upper:/cvmfs_ro/${cvmfs_repo_name}"
811+
EESSI_READONLY_OVERLAY+=" /cvmfs/${cvmfs_repo_name}"
812+
elif [[ "${OVERLAY_TOOL}" == "unionfs" ]]; then
813+
EESSI_READONLY_OVERLAY="container:unionfs"
814+
# cow stands for 'copy-on-write'
815+
EESSI_READONLY_OVERLAY+=" -o cow"
816+
EESSI_READONLY_OVERLAY+=" /cvmfs_ro/${cvmfs_repo_name}=RO"
817+
EESSI_READONLY_OVERLAY+=" /cvmfs/${cvmfs_repo_name}"
818+
else
819+
echo -e "ERROR: unknown overlay tool specified: ${OVERLAY_TOOL}"
820+
exit ${OVERLAY_TOOL_EXITCODE}
821+
fi
802822
export EESSI_READONLY_OVERLAY
803823

804824
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_READONLY_OVERLAY}")
@@ -824,11 +844,23 @@ do
824844

825845
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_READONLY}")
826846

827-
EESSI_WRITABLE_OVERLAY="container:fuse-overlayfs"
828-
EESSI_WRITABLE_OVERLAY+=" -o lowerdir=/cvmfs_ro/${cvmfs_repo_name}"
829-
EESSI_WRITABLE_OVERLAY+=" -o upperdir=${TMP_IN_CONTAINER}/${cvmfs_repo_name}/overlay-upper"
830-
EESSI_WRITABLE_OVERLAY+=" -o workdir=${TMP_IN_CONTAINER}/${cvmfs_repo_name}/overlay-work"
831-
EESSI_WRITABLE_OVERLAY+=" /cvmfs/${cvmfs_repo_name}"
847+
if [[ "${OVERLAY_TOOL}" == "fuse-overlayfs" ]]; then
848+
EESSI_WRITABLE_OVERLAY="container:fuse-overlayfs"
849+
EESSI_WRITABLE_OVERLAY+=" -o lowerdir=/cvmfs_ro/${cvmfs_repo_name}"
850+
EESSI_WRITABLE_OVERLAY+=" -o upperdir=${TMP_IN_CONTAINER}/${cvmfs_repo_name}/overlay-upper"
851+
EESSI_WRITABLE_OVERLAY+=" -o workdir=${TMP_IN_CONTAINER}/${cvmfs_repo_name}/overlay-work"
852+
EESSI_WRITABLE_OVERLAY+=" /cvmfs/${cvmfs_repo_name}"
853+
elif [[ "${OVERLAY_TOOL}" == "unionfs" ]]; then
854+
# files touched are reflected under /cvmfs/<repo>/.unionfs/
855+
EESSI_WRITABLE_OVERLAY="container:unionfs"
856+
# cow stands for 'copy-on-write'
857+
EESSI_WRITABLE_OVERLAY+=" -o cow"
858+
EESSI_WRITABLE_OVERLAY+=" ${TMP_IN_CONTAINER}/${cvmfs_repo_name}/overlay-upper=RW:/cvmfs_ro/${cvmfs_repo_name}=RO"
859+
EESSI_WRITABLE_OVERLAY+=" /cvmfs/${cvmfs_repo_name}"
860+
else
861+
echo -e "ERROR: unknown overlay tool specified: ${OVERLAY_TOOL}"
862+
exit ${OVERLAY_TOOL_EXITCODE}
863+
fi
832864
export EESSI_WRITABLE_OVERLAY
833865

834866
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_WRITABLE_OVERLAY}")

0 commit comments

Comments
 (0)