@@ -6,6 +6,30 @@ if [[ -n "${RULES_PYTHON_BOOTSTRAP_VERBOSE:-}" ]]; then
66 set -x
77fi
88
9+ # Creates a symlink. If the symlink already exists, it is tolerated to avoid
10+ # race conditions during startup.
11+ function _symlink() {
12+ local target=" $1 "
13+ local link=" $2 "
14+ if ln -s " $target " " $link " 2> /dev/null; then
15+ return 0
16+ fi
17+ # If it failed, maybe it already exists because of a race.
18+ if [[ -L " $link " || -e " $link " ]]; then
19+ return 0
20+ fi
21+ # If it doesn't exist, maybe we don't have write permission in the directory.
22+ local dir
23+ dir=$( dirname " $link " )
24+ if [[ ! -w " $dir " ]]; then
25+ echo >&2 " ERROR: Cannot create symlink $link : Directory $dir is not writable"
26+ else
27+ echo >&2 " ERROR: Failed to create symlink $link -> $target "
28+ fi
29+ return 1
30+ }
31+
32+
933# runfiles-root-relative path
1034STAGE2_BOOTSTRAP=" %stage2_bootstrap%"
1135
@@ -153,7 +177,7 @@ if [[ "$IS_ZIPFILE" == "1" ]]; then
153177 fi
154178 # The bin/ directory may not exist if it is empty.
155179 mkdir -p " $( dirname $python_exe ) "
156- ln -s " $symlink_to " " $python_exe "
180+ _symlink " $symlink_to " " $python_exe "
157181elif [[ " $RECREATE_VENV_AT_RUNTIME " == " 1" ]]; then
158182 if [[ -n " $RULES_PYTHON_EXTRACT_ROOT " ]]; then
159183 use_exec=1
@@ -226,16 +250,16 @@ EOF
226250 fi
227251
228252 mkdir -p " $venv /bin"
229- ln -s " $python_exe_actual " " $python_exe "
253+ _symlink " $python_exe_actual " " $python_exe "
230254
231255 if [[ ! -e " $venv_site_packages " ]]; then
232256 mkdir -p $( dirname $venv_site_packages )
233- ln -s " $runfiles_venv_site_packages " " $venv_site_packages "
257+ _symlink " $runfiles_venv_site_packages " " $venv_site_packages "
234258 fi
235259 fi
236260
237261 if [[ ! -e " $venv /pyvenv.cfg" ]]; then
238- ln -s " $runfiles_venv /pyvenv.cfg" " $venv /pyvenv.cfg"
262+ _symlink " $runfiles_venv /pyvenv.cfg" " $venv /pyvenv.cfg"
239263 fi
240264else
241265 use_exec=1
0 commit comments