Skip to content

Commit 0d5359d

Browse files
committed
RF: Disable symlinks if destination is on CIFS
1 parent 3107a6d commit 0d5359d

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

nipype/utils/filemanip.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import sys
1414
import pickle
15+
import subprocess
1516
import gzip
1617
import hashlib
1718
from hashlib import md5
@@ -237,6 +238,30 @@ def hash_timestamp(afile):
237238
return md5hex
238239

239240

241+
def _on_cifs(fname):
242+
""" Checks whether a PATH is on a CIFS filesystem mounted in a POSIX
243+
host (i.e., has the "mount" command).
244+
245+
CIFS shares are how Docker mounts Windows host directories into containers.
246+
CIFS has partial support for symlinks that can break, causing misleading
247+
errors, so this test is used to disable them on such systems.
248+
"""
249+
exit_code, output = subprocess.getstatusoutput("mount")
250+
# Not POSIX
251+
if exit_code != 0:
252+
return False
253+
254+
# (path, fstype) tuples, sorted by path length (longest first)
255+
paths_types = sorted((line.split()[2:5:2] for line in output.splitlines()),
256+
key=lambda x: len(x[0]),
257+
reverse=True)
258+
# Only the first match counts
259+
for fspath, fstype in paths_types:
260+
if fname.startswith(fspath):
261+
return fstype == 'cifs'
262+
return False
263+
264+
240265
def copyfile(originalfile, newfile, copy=False, create_new=False,
241266
hashmethod=None, use_hardlink=False,
242267
copy_related_files=True):
@@ -288,6 +313,10 @@ def copyfile(originalfile, newfile, copy=False, create_new=False,
288313
if hashmethod is None:
289314
hashmethod = config.get('execution', 'hash_method').lower()
290315

316+
# Don't try creating symlinks on CIFS
317+
if _on_cifs(newfile):
318+
copy = True
319+
291320
# Existing file
292321
# -------------
293322
# Options:

0 commit comments

Comments
 (0)