Skip to content

Commit bc08870

Browse files
authored
Merge pull request #50 from bedroge/cvmfs_bind_or_fuse_mount
Add functionality to `eessi_container.sh` for specifying if a CVMFS repo should be bind or fuse mounted
2 parents ce4f213 + 2edf309 commit bc08870

File tree

2 files changed

+79
-20
lines changed

2 files changed

+79
-20
lines changed

.github/workflows/tests_scripts.yml

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,14 @@ jobs:
4545
4646
- name: test load_easybuild_module.sh script
4747
run: |
48+
export SINGULARITY_CACHEDIR=$PWD
4849
# bind current directory into container as /software-layer-scripts
4950
export SINGULARITY_BIND="${PWD}:/software-layer-scripts"
5051
5152
# can't test with EasyBuild versions older than v4.5.2 when using EESSI 2023.06,
5253
# since Python in compat layer is Python 3.11.x;
5354
# testing with a single EasyBuild version takes a while in GitHub Actions, so stick to a single sensible version
54-
for EB_VERSION in '4.6.0'; do
55+
for EB_VERSION in '5.1.0'; do
5556
# Create script that uses load_easybuild_module.sh which we can run in compat layer environment
5657
# note: Be careful with single vs double quotes below!
5758
# ${EB_VERSION} should be expanded, so use double quotes;
@@ -91,6 +92,7 @@ jobs:
9192
9293
- name: test install_software_layer.sh script
9394
run: |
95+
export SINGULARITY_CACHEDIR=$PWD
9496
# bind current directory into container as /software-layer-scripts
9597
export SINGULARITY_BIND="${PWD}:/software-layer-scripts"
9698
# force using x86_64/generic, to avoid triggering an installation from scratch
@@ -105,6 +107,7 @@ jobs:
105107
106108
- name: test create_directory_tarballs.sh script
107109
run: |
110+
export SINGULARITY_CACHEDIR=$PWD
108111
# bind current directory into container as /software-layer-scripts
109112
export SINGULARITY_BIND="${PWD}:/software-layer-scripts"
110113
@@ -113,12 +116,13 @@ jobs:
113116
114117
# scripts need to be copied to /tmp,
115118
# since create_directory_tarballs.sh must be accessible from within build container
116-
./eessi_container.sh --mode run --verbose /software-layer-scripts/create_directory_tarballs.sh 2023.06
119+
./eessi_container.sh --mode run --verbose /software-layer-scripts/create_directory_tarballs.sh "${{matrix.EESSI_VERSION}}"
117120
# check if tarballs have been produced
118121
ls -l *.tar.gz
119122
120123
- name: test create_lmodsitepackage.py script
121124
run: |
125+
export SINGULARITY_CACHEDIR=$PWD
122126
# bind current directory into container as /software-layer-scripts
123127
export SINGULARITY_BIND="${PWD}:/software-layer-scripts"
124128
@@ -140,3 +144,22 @@ jobs:
140144
for pattern in "^Site Pkg location.*/software-layer-scripts/.lmod/SitePackage.lua" "LMOD_SITEPACKAGE_LOCATION.*/software-layer-scripts/.lmod/SitePackage.lua"; do
141145
grep "${pattern}" ${out} || (echo "Pattern '${pattern}' not found in output!" && exit 1)
142146
done
147+
148+
- name: Mount EESSI CernVM-FS repository
149+
uses: eessi/github-action-eessi@v3
150+
with:
151+
eessi_stack_version: ${{matrix.EESSI_VERSION}}
152+
use_eessi_module: true
153+
154+
- name: Verify that mounted repositories are passed through directly
155+
run: |
156+
export SINGULARITY_CACHEDIR=$PWD
157+
# run wrapper script + capture & check output
158+
export SINGULARITY_BIND="${PWD}:/software-layer-scripts"
159+
# make sure that correct EESSI version is used (required because default is a placeholder version)
160+
export EESSI_VERSION_OVERRIDE="${{matrix.EESSI_VERSION}}"
161+
162+
out="${PWD}/eb-${EB_VERSION}.out"
163+
./eessi_container.sh --access rw --mode run --verbose /software-layer-scripts/run_in_compat_layer_env.sh ls 2>&1 | tee ${out}
164+
echo $(grep "SINGULARITY_BIND" ${out})
165+
grep "SINGULARITY_BIND" ${out} | grep "software.eessi.io" || (echo "software.eessi.io did not seem to be bind mounted!" && exit 1)

eessi_container.sh

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ display_help() {
9797
echo " container; can be given multiple times [default: not set]"
9898
echo " -r | --repository CFG - configuration file or identifier defining the"
9999
echo " repository to use; can be given multiple times;"
100-
echo " CFG may include a suffix ',access={ro,rw}' to"
101-
echo " overwrite the global access mode for this repository"
100+
echo " CFG may include suffixes ',access={ro,rw},mode={bind,fuse}' to"
101+
echo " overwrite the global access and/or mount mode for this repository"
102102
echo " [default: software.eessi.io via CVMFS config available"
103103
echo " via default container, see --container]"
104104
echo " -u | --resume DIR/TGZ - resume a previous run from a directory or tarball,"
@@ -756,14 +756,40 @@ for cvmfs_repo in "${REPOSITORIES[@]}"
756756
do
757757
unset cfg_repo_id
758758
[[ ${VERBOSE} -eq 1 ]] && echo "add fusemount options for CVMFS repo '${cvmfs_repo}'"
759-
# split into name and access mode if ',access=' in $cvmfs_repo
760-
if [[ ${cvmfs_repo} == *",access="* ]] ; then
761-
cvmfs_repo_name=${cvmfs_repo/,access=*/} # remove access mode specification
762-
cvmfs_repo_access=${cvmfs_repo/*,access=/} # remove repo name part
763-
else
764-
cvmfs_repo_name="${cvmfs_repo}"
765-
cvmfs_repo_access="${ACCESS}" # use globally defined access mode
759+
# split into name, access mode, and mount mode
760+
readarray -td, cvmfs_repo_args <<<"$cvmfs_repo"
761+
cvmfs_repo_name=${cvmfs_repo_args[0]}
762+
cvmfs_repo_access="${ACCESS}" # initialize to the default access mode
763+
for arg in ${cvmfs_repo_args[@]:1}; do
764+
if [[ $arg == "access="* ]]; then
765+
cvmfs_repo_access=${arg/access=}
766+
fi
767+
if [[ $arg == "mount="* ]]; then
768+
cvmfs_repo_mount=${arg/mount=}
769+
# check if the specified mount mode is a valid one
770+
if [[ ${cvmfs_repo_mount} != "bind" ]] && [[ ${cvmfs_repo_mount} != "fuse" ]]; then
771+
echo -e "ERROR: mount mode '${cvmfs_repo_mount}' for CVMFS repository\n '${cvmfs_repo_name}' is not known"
772+
exit ${REPOSITORY_ERROR_EXITCODE}
773+
fi
774+
fi
775+
done
776+
# if a mount mode was not specified, we use a bind mount if the repository is available on the host,
777+
# and otherwise we use a fuse mount
778+
if [[ -z ${cvmfs_repo_mount} ]]; then
779+
cvmfs_repo_mount="fuse"
780+
if [[ -x $(command -v cvmfs_config) ]] && cvmfs_config probe ${cvmfs_repo_name} >& /dev/null; then
781+
cvmfs_repo_mount="bind"
782+
fi
783+
fi
784+
[[ ${VERBOSE} -eq 1 ]] && echo "Using a ${cvmfs_repo_mount} mount for /cvmfs/${cvmfs_repo_name}"
785+
# if a bind mount was requested, check if the repository is really available on the host
786+
if [[ ${cvmfs_repo_mount} == "bind" ]]; then
787+
if [[ ! -x $(command -v cvmfs_config) ]] || ! cvmfs_config probe ${cvmfs_repo_name} >& /dev/null; then
788+
echo -e "ERROR: bind mount requested for CVMFS repository\n '${cvmfs_repo_name}', but it cannot be probed on the host"
789+
exit ${REPOSITORY_ERROR_EXITCODE}
790+
fi
766791
fi
792+
767793
# obtain cvmfs_repo_name from EESSI_REPOS_CFG_FILE if cvmfs_repo is in cfg_cvmfs_repos
768794
if [[ ${cfg_cvmfs_repos[${cvmfs_repo_name}]} ]]; then
769795
[[ ${VERBOSE} -eq 1 ]] && echo "repo '${cvmfs_repo_name}' is not an EESSI CVMFS repository..."
@@ -795,9 +821,12 @@ do
795821
echo " session. Will use it as left-most directory in 'lowerdir' argument for fuse-overlayfs."
796822

797823
# make the target CernVM-FS repository available under /cvmfs_ro
798-
export EESSI_READONLY="container:cvmfs2 ${cvmfs_repo_name} /cvmfs_ro/${cvmfs_repo_name}"
799-
800-
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_READONLY}")
824+
if [[ ${cvmfs_repo_mount} == "fuse" ]]; then
825+
export EESSI_READONLY="container:cvmfs2 ${cvmfs_repo_name} /cvmfs_ro/${cvmfs_repo_name}"
826+
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_READONLY}")
827+
elif [[ ${cvmfs_repo_mount} == "bind" ]]; then
828+
BIND_PATHS="/cvmfs/${cvmfs_repo_name}:/cvmfs_ro/${cvmfs_repo_name},${BIND_PATHS}"
829+
fi
801830

802831
# now, put the overlay-upper read-only on top of the repo and make it available under the usual prefix /cvmfs
803832
if [[ "${OVERLAY_TOOL}" == "fuse-overlayfs" ]]; then
@@ -827,10 +856,14 @@ do
827856
# basic "ro" access that doesn't require any fuseoverlay-fs
828857
echo "Mounting '${cvmfs_repo_name}' 'read-only' without fuse-overlayfs."
829858

830-
export EESSI_READONLY="container:cvmfs2 ${cvmfs_repo_name} /cvmfs/${cvmfs_repo_name}"
859+
if [[ ${cvmfs_repo_mount} == "fuse" ]]; then
860+
export EESSI_READONLY="container:cvmfs2 ${cvmfs_repo_name} /cvmfs/${cvmfs_repo_name}"
861+
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_READONLY}")
862+
export EESSI_FUSE_MOUNTS
863+
elif [[ ${cvmfs_repo_mount} == "bind" ]]; then
864+
BIND_PATHS="/cvmfs/${cvmfs_repo_name},${BIND_PATHS}"
865+
fi
831866

832-
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_READONLY}")
833-
export EESSI_FUSE_MOUNTS
834867
fi
835868
elif [[ ${cvmfs_repo_access} == "rw" ]] ; then
836869
# use repo-specific overlay directories
@@ -840,9 +873,12 @@ do
840873
[[ ${VERBOSE} -eq 1 ]] && echo -e "TMP directory contents:\n$(ls -l ${EESSI_TMPDIR})"
841874

842875
# set environment variables for fuse mounts in Singularity container
843-
export EESSI_READONLY="container:cvmfs2 ${cvmfs_repo_name} /cvmfs_ro/${cvmfs_repo_name}"
844-
845-
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_READONLY}")
876+
if [[ ${cvmfs_repo_mount} == "fuse" ]]; then
877+
export EESSI_READONLY="container:cvmfs2 ${cvmfs_repo_name} /cvmfs_ro/${cvmfs_repo_name}"
878+
EESSI_FUSE_MOUNTS+=("--fusemount" "${EESSI_READONLY}")
879+
elif [[ ${cvmfs_repo_mount} == "bind" ]]; then
880+
BIND_PATHS="/cvmfs/${cvmfs_repo_name}:/cvmfs_ro/${cvmfs_repo_name},${BIND_PATHS}"
881+
fi
846882

847883
if [[ "${OVERLAY_TOOL}" == "fuse-overlayfs" ]]; then
848884
EESSI_WRITABLE_OVERLAY="container:fuse-overlayfs"

0 commit comments

Comments
 (0)