@@ -123,6 +123,74 @@ display_help() {
123123 echo " '--' to let eessi_container.sh stop parsing arguments."
124124}
125125
126+ # function to parse and check bind paths
127+ # returns:
128+ # 0 if target found with matching source (no conflict)
129+ # 1 if target found with different source (conflict)
130+ # 2 if target not found
131+ check_bind_paths_for_target () {
132+ local search_target=" $1 "
133+ local search_src=" $2 "
134+ local bind_paths=" $3 " # typically used to pass value of $BIND_PATHS
135+
136+ # handle empty BIND_PATHS
137+ if [[ -z " ${bind_paths} " ]]; then
138+ return 2
139+ fi
140+
141+ # split by comma and process each entry
142+ IFS=' ,' read -ra BIND_ENTRIES <<< " ${bind_paths}"
143+
144+ for entry in " ${BIND_ENTRIES[@]} " ; do
145+ # skip empty entries
146+ [[ -z " ${entry} " ]] && continue
147+
148+ local bind_src bind_target
149+
150+ # split entry by ':'
151+ IFS=' :' read -ra PARTS <<< " ${entry}"
152+
153+ bind_src=" ${PARTS[0]} "
154+
155+ if [[ ${# PARTS[@]} -ge 2 ]]; then
156+ bind_target=" ${PARTS[1]} "
157+ else
158+ # no target given, use src
159+ bind_target=${bind_src}
160+ fi
161+
162+ # trim any possible whitespace
163+ bind_src=$( echo " ${bind_src} " | xargs)
164+ bind_target=$( echo " ${bind_target} " | xargs)
165+
166+ [[ ${VERBOSE} -eq 1 ]] && echo " Parsed bind entry: src='${bind_src} ' target='${bind_target} '"
167+
168+ # check if this entry matches our target
169+ if [[ " ${bind_target} " == " ${search_target} " ]]; then
170+ # found target -> need to compare normalised sources
171+ # try to normalise source paths, but don't fail if they don't exist (yet)
172+
173+ bind_src_normalised=$( readlink -f " ${bind_src} " 2> /dev/null)
174+ search_src_normalised=$( readlink -f " ${search_src} " 2> /dev/null)
175+
176+ # decide which path to use - normalised or original
177+ local bind_src_compare=" ${bind_src_normalised:- ${bind_src} } "
178+ local search_src_compare=" ${search_src_normalised:- ${search_src} } "
179+
180+ [[ ${VERBOSE} -eq 1 ]] && echo " Comparing: '${bind_src_compare} ' vs '${search_src_compare} '"
181+
182+ if [[ " ${bind_src_compare} " == " ${search_src_compare} " ]]; then
183+ return 0 # found target with same source (all good)
184+ else
185+ echo " ${bind_src} " # return the conflicting source for error message
186+ return 1 # found target with different source (conflict)
187+ fi
188+ fi
189+ done
190+
191+ return 2 # target not found in bind paths
192+ }
193+
126194# set defaults for command line arguments
127195ACCESS=" ro"
128196CONTAINER=" docker://ghcr.io/eessi/build-node:debian12"
@@ -719,17 +787,38 @@ if [[ ! -z ${http_proxy} ]]; then
719787 HTTP_PROXY_IPV4=$( get_ipv4_address ${PROXY_HOST} )
720788 [[ ${VERBOSE} -eq 1 ]] && echo " HTTP_PROXY_IPV4='${HTTP_PROXY_IPV4} '"
721789 echo " CVMFS_HTTP_PROXY=\" ${http_proxy} |http://${HTTP_PROXY_IPV4} :${PROXY_PORT} \" " \
722- >> ${EESSI_TMPDIR} /repos_cfg/default.local
790+ >> ${EESSI_TMPDIR} /repos_cfg/default.local
723791 [[ ${VERBOSE} -eq 1 ]] && echo " contents of default.local"
724792 [[ ${VERBOSE} -eq 1 ]] && cat ${EESSI_TMPDIR} /repos_cfg/default.local
725793
726794 # if default.local is not BIND mounted into container, add it to BIND_PATHS
727795 src=${EESSI_TMPDIR} /repos_cfg/default.local
728796 target=/etc/cvmfs/default.local
729- if [[ ${BIND_PATHS} =~ " ${target} " ]]; then
730- fatal_error " BIND target in '${src} :${target} ' is already in paths to be bind mounted into the container ('${BIND_PATHS} ')" ${REPOSITORY_ERROR_EXITCODE}
731- fi
732- BIND_PATHS=" ${BIND_PATHS} ,${src} :${target} "
797+
798+ # check if target already exists in BIND_PATHS, and, if so, if sources are
799+ # the same
800+ conflict_src=$( check_bind_paths_for_target " ${target} " " ${src} " " ${BIND_PATHS} " )
801+ check_result=$?
802+
803+ case ${check_result} in
804+ 0)
805+ # target already bound with same source - no action needed
806+ [[ ${VERBOSE} -eq 1 ]] && echo " Bind mount already configured: ${src} :${target} "
807+ ;;
808+ 1)
809+ # target already bound with different source - conflict!
810+ fatal_error " BIND target '${target} ' conflict: already bound from '${conflict_src} ', cannot bind from '${src} '" ${REPOSITORY_ERROR_EXITCODE}
811+ ;;
812+ 2)
813+ # target not found - safe to add
814+ if [[ -z ${BIND_PATH} ]]; then
815+ BIND_PATHS=" ${src} :${target} "
816+ else
817+ BIND_PATHS=" ${BIND_PATHS} ,${src} :${target} "
818+ fi
819+ [[ ${VERBOSE} -eq 1 ]] && echo " Added bind mount: ${src} :${target} "
820+ ;;
821+ esac
733822fi
734823
735824# 4. set up vars and dirs specific to a scenario
0 commit comments